|
@@ -762,94 +762,67 @@ void SPAServer::threadRoomCamera()
|
|
{
|
|
{
|
|
/* 房间相机关联信息 */
|
|
/* 房间相机关联信息 */
|
|
std::list<RoomCameraInfo> listRC;
|
|
std::list<RoomCameraInfo> listRC;
|
|
|
|
+ /* 存储获取到的应用和启用时间的信息 */
|
|
|
|
+ std::list<AppAndTimeInfo> listAppAndTime;
|
|
/* 创建连接数据库实例 */
|
|
/* 创建连接数据库实例 */
|
|
std::shared_ptr<ToEQMDataBase> toEQMDataBase = std::make_shared<ToEQMDataBase>();
|
|
std::shared_ptr<ToEQMDataBase> toEQMDataBase = std::make_shared<ToEQMDataBase>();
|
|
|
|
|
|
while (m_threadRunning)
|
|
while (m_threadRunning)
|
|
{
|
|
{
|
|
|
|
+ m_mutexRunFAI.lock();
|
|
|
|
+ /* 先清理已经退出的线程所用到的Action或者RoomAction */
|
|
|
|
+ m_runListFuncActInfo.clearNoneFuncActionInfo();
|
|
|
|
+
|
|
|
|
+ /* 创建应用信息,根据从EQM数据库读取到的配置的应用信息创建 */
|
|
|
|
+ toEQMDataBase->getAlarmAppInfo(listAppAndTime);
|
|
|
|
+ for(const auto& it : listAppAndTime)
|
|
|
|
+ {
|
|
|
|
+ /* 创建应用信息,如果已有该应用,就更新时间 */
|
|
|
|
+ m_runListFuncActInfo.addFuncActionInfo(it);
|
|
|
|
+ }
|
|
|
|
+
|
|
/* 先获取EQM数据库信息,取出房间和摄像机关联信息 */
|
|
/* 先获取EQM数据库信息,取出房间和摄像机关联信息 */
|
|
m_mutexActionInfo.lock();
|
|
m_mutexActionInfo.lock();
|
|
toEQMDataBase->getActionInfo(m_listActionInfo);
|
|
toEQMDataBase->getActionInfo(m_listActionInfo);
|
|
- /* 取出每个房间的所有算法,int是RoomID,string是Action */
|
|
|
|
- // std::multimap<int, std::string> mapCameraActionID;
|
|
|
|
- m_mutexRunRAI.lock();
|
|
|
|
- m_mutexRunAI.lock();
|
|
|
|
- /* 先清理已经退出的线程所用到的Action或者RoomAction */
|
|
|
|
- m_runListRoomActionInfo.clearStopRoomAction();
|
|
|
|
- m_runListActionInfo.clearStopAction();
|
|
|
|
-
|
|
|
|
- /* 将算法信息加入到不同的列表中
|
|
|
|
- * 需要多个摄像机配合的加入到m_runListRoomActionInfo列表
|
|
|
|
- * 不需要多个摄像机配合的加入到m_runListActionInfo列表
|
|
|
|
- * */
|
|
|
|
- m_runListRoomActionInfo.clearCameraList();
|
|
|
|
- m_runListActionInfo.clearCameraList();
|
|
|
|
|
|
+ /* 将算法信息加入到不同的列表中 */
|
|
|
|
+ m_runListFuncActInfo.clearActionList();
|
|
for(const auto& it : m_listActionInfo.getData())
|
|
for(const auto& it : m_listActionInfo.getData())
|
|
{
|
|
{
|
|
- if(it->ActionID == ActPersonWork || it->ActionID == ActPersonNumber)
|
|
|
|
|
|
+ m_runListFuncActInfo.addActionInfo(*it);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* 检查算法信息的状态,频率里的应用没有配置摄像机就设置为线程运行状态为停止,退出该线程 */
|
|
|
|
+ for(const auto& it : m_runListFuncActInfo.getData())
|
|
|
|
+ {
|
|
|
|
+ if(it->listRoomCamActInfo.size() == 0)
|
|
{
|
|
{
|
|
- m_runListRoomActionInfo.addActionInfo(*it);
|
|
|
|
- }else {
|
|
|
|
- m_runListActionInfo.addActionCamera(it);
|
|
|
|
|
|
+ it->RunState = RunTimeState::RUN_STATE_STOP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m_mutexActionInfo.unlock();
|
|
m_mutexActionInfo.unlock();
|
|
- /* 这个容器只用于多个摄像机融合的算法,一个功能是一个线程 */
|
|
|
|
- for(const auto& it0 : m_runListRoomActionInfo.getData())
|
|
|
|
|
|
+ /* 开启线程 */
|
|
|
|
+ for(const auto& it0 : m_runListFuncActInfo.getData())
|
|
{
|
|
{
|
|
/* 人员在岗识别 */
|
|
/* 人员在岗识别 */
|
|
- if(it0->ActionID == ActPersonWork)
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "RoomID:{} 人员在岗识别", it0->RoomID);
|
|
|
|
- /* 判断是否需要创建新的线程 */
|
|
|
|
- if(it0->RunState == RunTimeState::RUN_STATE_INIT)
|
|
|
|
- {
|
|
|
|
- /* 创建新的线程 */
|
|
|
|
- CPPTP.add_task(&SPAServer::threadActPersonWork, this, it0);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
/* 区域人员检测 */
|
|
/* 区域人员检测 */
|
|
- else if (it0->ActionID == ActPersonNumber)
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "RoomID:{} 区域人员检测", it0->RoomID);
|
|
|
|
- if(it0->RunState == RunTimeState::RUN_STATE_INIT)
|
|
|
|
- {
|
|
|
|
- CPPTP.add_task(&SPAServer::threadActRegionalPersonnelDetection, this, it0);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- /* 非法入侵 */
|
|
|
|
- else if( it0->ActionID == ActIllegalInvasion)
|
|
|
|
- {
|
|
|
|
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- /* 这个容器用于不关联的算法信息,每个设备上的每个算法是一个线程
|
|
|
|
- * ActionInfo.RunState = RUN_STATE_INIT ,就是新增的算法,需要创建新的线程 */
|
|
|
|
- for(const auto& it0 : m_runListActionInfo.getData())
|
|
|
|
- {
|
|
|
|
- /* 违禁物品识别,不需要多个摄像机融合判断,多少个报警都直接上报 */
|
|
|
|
- if (it0->ActionID == ActContraband)
|
|
|
|
|
|
+ /* 非法入侵检测 */
|
|
|
|
+
|
|
|
|
+ /* 违禁品识别 */
|
|
|
|
+
|
|
|
|
+ /* 普通任务线程,一个任务对应一个摄像机和一个算法ID,无需联动 */
|
|
|
|
+ if(it0->appFunction == AppFunction::APP_ALLDOWN)
|
|
{
|
|
{
|
|
- SPDLOG_LOGGER_INFO(m_logger, "RoomID:{} 违禁品检测", it0->RoomID);
|
|
|
|
- it0->strActionName = "违禁品检测";
|
|
|
|
if(it0->RunState == RunTimeState::RUN_STATE_INIT)
|
|
if(it0->RunState == RunTimeState::RUN_STATE_INIT)
|
|
{
|
|
{
|
|
CPPTP.add_task(&SPAServer::threadActNormal, this, it0);
|
|
CPPTP.add_task(&SPAServer::threadActNormal, this, it0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- /* 非法入侵检测,这个也不需要摄像机融合 */
|
|
|
|
- else if (it0->ActionID == ActIllegalInvasion)
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "RoomID:{} 非法入侵检测", it0->RoomID);
|
|
|
|
- }
|
|
|
|
- /* 疲劳检测,不需要摄像机融合检测,直接上报 */
|
|
|
|
- else if (it0->ActionID == ActFatigueDetection)
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "RoomID:{} 疲劳检测", it0->RoomID);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
- m_mutexRunRAI.unlock();
|
|
|
|
- m_mutexRunAI.unlock();
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ m_mutexRunFAI.unlock();
|
|
|
|
|
|
/* 休眠n秒,默认应该是300秒 */
|
|
/* 休眠n秒,默认应该是300秒 */
|
|
std::this_thread::sleep_for(std::chrono::seconds(g_config.CheckSet));
|
|
std::this_thread::sleep_for(std::chrono::seconds(g_config.CheckSet));
|
|
@@ -857,93 +830,6 @@ void SPAServer::threadRoomCamera()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
-/* 将该算法对应的摄像机放入摄像机列表 */
|
|
|
|
-bool SPAServer::insertCameraToAction(RoomActionInfo* pRAInfo, std::list<RoomCameraInfo>& listRC, std::multimap<int, std::string>& mapCameraActionID)
|
|
|
|
-{
|
|
|
|
- for(const auto& rci : listRC)
|
|
|
|
- {
|
|
|
|
- if(rci.RoomID == pRAInfo->RoomID)
|
|
|
|
- {
|
|
|
|
- /* 这个摄像机在这个房间内,再判断这个摄像机有没有这个算法 */
|
|
|
|
- for(const auto& camID : rci.listCameraID)
|
|
|
|
- {
|
|
|
|
- for(const auto& cai : mapCameraActionID)
|
|
|
|
- {
|
|
|
|
- if(camID == cai.first)
|
|
|
|
- {
|
|
|
|
- /* 再判断这个摄像机的算法是否是当前需要的 */
|
|
|
|
- if(cai.second == pRAInfo->ActionID)
|
|
|
|
- {
|
|
|
|
- pRAInfo->listCameraID.push_back(camID);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* 更新房间、算法需要的摄像机个数,从内存中更新 */
|
|
|
|
-bool SPAServer::updateRoomActionCameraCount(std::shared_ptr<RoomActionInfo> pRAInfo)
|
|
|
|
-{
|
|
|
|
- std::lock_guard<std::mutex> look(m_mutexRunRAI);
|
|
|
|
- for(auto& it : m_runListRoomActionInfo.getData())
|
|
|
|
- {
|
|
|
|
- if((it->RoomID == pRAInfo->RoomID) && (it->ActionID == pRAInfo->ActionID))
|
|
|
|
- {
|
|
|
|
- it->listCameraID = pRAInfo->listCameraID;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* 更新算法的摄像机ID,这里是从内存中的数组里获取 */
|
|
|
|
-bool SPAServer::updateActionCameraID(std::shared_ptr<FuncActionInfo> pInfo)
|
|
|
|
-{
|
|
|
|
- pInfo->listRoomCamActInfo = -1;
|
|
|
|
- std::lock_guard<std::mutex> look(m_mutexRunAI);
|
|
|
|
- for(auto& it : m_runListActionInfo.getData())
|
|
|
|
- {
|
|
|
|
- if(it->isEqualBaseInfo(*pInfo))
|
|
|
|
- {
|
|
|
|
- pInfo->CameraID = it->CameraID;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* 设置线程状态 */
|
|
|
|
-void SPAServer::setThreadState(std::shared_ptr<ActionInfo> pInfo, RunTimeState state)
|
|
|
|
-{
|
|
|
|
- std::lock_guard<std::mutex> look(m_mutexRunAI);
|
|
|
|
- for(auto& it : m_runListActionInfo.getData())
|
|
|
|
- {
|
|
|
|
- if(it->isEqualBaseInfo(*pInfo))
|
|
|
|
- {
|
|
|
|
- it->RunState = state;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/* 设置线程状态 */
|
|
|
|
-void SPAServer::setThreadState(std::shared_ptr<RoomActionInfo> pInfo, RunTimeState state)
|
|
|
|
-{
|
|
|
|
- std::lock_guard<std::mutex> look(m_mutexRunRAI);
|
|
|
|
- for(auto& it : m_runListRoomActionInfo.getData())
|
|
|
|
- {
|
|
|
|
- if(it->isEqualBaseInfo(*pInfo))
|
|
|
|
- {
|
|
|
|
- it->RunState = state;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1069,7 +955,7 @@ void SPAServer::threadActRegionalPersonnelDetection(RoomActionInfo* RAInfo)
|
|
*/
|
|
*/
|
|
void SPAServer::threadActNormal(FuncActionInfo* info)
|
|
void SPAServer::threadActNormal(FuncActionInfo* info)
|
|
{
|
|
{
|
|
- SPDLOG_LOGGER_INFO(m_logger, "开启 {} 线程, ChannelID:{} ,Action:{}",info->strFunctionName, info->ChannelID, info->listRoomCamActInfo.front().mapCameraAction.begin()->second);
|
|
|
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "开启 {} 线程, ChannelID:{} ,App:{}",info->strFunctionName, info->ChannelID, info->strFunctionName);
|
|
/* 创建读取Redis的实例 */
|
|
/* 创建读取Redis的实例 */
|
|
std::shared_ptr<FromRedis> fromRedis = std::make_shared<FromRedis>();
|
|
std::shared_ptr<FromRedis> fromRedis = std::make_shared<FromRedis>();
|
|
/* 创建写入EQM数据库实例 */
|
|
/* 创建写入EQM数据库实例 */
|
|
@@ -1078,93 +964,119 @@ void SPAServer::threadActNormal(FuncActionInfo* info)
|
|
std::shared_ptr<FuncActionInfo> pFuncAct = std::make_shared<FuncActionInfo>();
|
|
std::shared_ptr<FuncActionInfo> pFuncAct = std::make_shared<FuncActionInfo>();
|
|
*pFuncAct = *info;
|
|
*pFuncAct = *info;
|
|
/* 保存报警数据 */
|
|
/* 保存报警数据 */
|
|
- std::shared_ptr<AlarmInfo> pAlarmInfo = std::make_shared<AlarmInfo>();
|
|
|
|
|
|
+ std::shared_ptr<ListAlarmInfo> listAlarmInfo = std::make_shared<ListAlarmInfo>();
|
|
|
|
|
|
while (m_threadRunning)
|
|
while (m_threadRunning)
|
|
{
|
|
{
|
|
/* 更新算法关联的摄像机ID */
|
|
/* 更新算法关联的摄像机ID */
|
|
- updateActionCameraID(pFuncAct);
|
|
|
|
- /* 如果摄像机ID是小于0,那么这个算法就没有对应的摄像机了,线程就退出了 */
|
|
|
|
- if(pActInfo->CameraID < 0)
|
|
|
|
|
|
+ updateFuncInfo(pFuncAct);
|
|
|
|
+ /* 如果线程的运行状态为 */
|
|
|
|
+ if(pFuncAct->RunState == RunTimeState::RUN_STATE_STOP)
|
|
{
|
|
{
|
|
|
|
+ pFuncAct->appFunction = AppFunction::APP_NONE;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
- /* 读取Redis数据 */
|
|
|
|
- std::string strKey = std::to_string(pActInfo->CameraID) + ":" + pActInfo->ActionID;
|
|
|
|
- std::string strRetValue;
|
|
|
|
- if(!fromRedis->getRedisString(strKey, strRetValue))
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
|
|
|
|
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- /* 解析数据 */
|
|
|
|
- AlarmInfo alarmInfo;
|
|
|
|
- parseRedisBaseData(strRetValue, alarmInfo);
|
|
|
|
- parseRedisBBoxesData(strRetValue, alarmInfo);
|
|
|
|
- /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
|
|
|
|
- if(isEventTimeVaild(alarmInfo.EventTime))
|
|
|
|
- {
|
|
|
|
- SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
|
|
|
|
- std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- /* 判断有无报警记录,新的报警就写入到EQM的tAlarmInfo表中,正在报警的记录就判断和更新,
|
|
|
|
- * 结束报警就更新tAlarmInfo的报警数据的结束时间,并清空pAlarmInfo */
|
|
|
|
- if(pAlarmInfo->Is_Alarm)
|
|
|
|
|
|
+ /* 读取Redis信息,处理数据 */
|
|
|
|
+ for(const auto& roomInfo : pFuncAct->listRoomCamActInfo)
|
|
{
|
|
{
|
|
- /* 正在报警中,检查是否报警结束 */
|
|
|
|
- if(alarmInfo.Is_Alarm)
|
|
|
|
|
|
+ for(const auto& it : roomInfo.mapCameraAction)
|
|
{
|
|
{
|
|
- /* 更新图片信息 */
|
|
|
|
- if(!alarmInfo.ImageInfo.empty())
|
|
|
|
|
|
+ /* 读取Redis数据 */
|
|
|
|
+ std::string strKey = std::to_string(it.first) + ":" + it.second;
|
|
|
|
+ std::string strRetValue;
|
|
|
|
+ if(!fromRedis->getRedisString(strKey, strRetValue))
|
|
{
|
|
{
|
|
- pAlarmInfo->ImageInfo = alarmInfo.ImageInfo;
|
|
|
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
|
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- /* 报警结束,判断时长,更新数据库结束时间,结束时间是此时电脑时间 */
|
|
|
|
- if(timeDiffWithNow(pAlarmInfo->EventTime) > g_config.Contraband)
|
|
|
|
|
|
+ /* 解析数据 */
|
|
|
|
+ AlarmInfo alarmInfo;
|
|
|
|
+ parseRedisBaseData(strRetValue, alarmInfo);
|
|
|
|
+ parseRedisBBoxesData(strRetValue, alarmInfo);
|
|
|
|
+ /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
|
|
|
|
+ if(isEventTimeVaild(alarmInfo.EventTime))
|
|
{
|
|
{
|
|
- pAlarmInfo->EndTime = chronoToStrTime(std::chrono::system_clock::now());
|
|
|
|
- toEQMDataBase->updateAlarmEndTime(*pAlarmInfo);
|
|
|
|
- }else {
|
|
|
|
- /* 不够报警时间,目前不做任何处理,不删除EQM报警记录 */
|
|
|
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
|
|
|
|
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
+ /* 找出数组中与当前报警ID相同的的报警信息 */
|
|
|
|
+ auto pAlarmInfo = listAlarmInfo->findAlarmInfo(alarmInfo);
|
|
|
|
+ if(pAlarmInfo == nullptr)
|
|
|
|
+ {
|
|
|
|
+ /* 没有找到报警记录,就新建一个 */
|
|
|
|
+ AlarmInfo newAlarmInfo = alarmInfo;
|
|
|
|
+ listAlarmInfo->addAlarmInfo(newAlarmInfo);
|
|
|
|
+ /* 重新查找该报警信息 */
|
|
|
|
+ pAlarmInfo = listAlarmInfo->findAlarmInfo(alarmInfo);
|
|
|
|
+ if(pAlarmInfo == nullptr)
|
|
|
|
+ {
|
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "查找报警信息失败, Key:{}", strKey);
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ /* 判断有无报警记录,新的报警就写入到EQM的tAlarmInfo表中,正在报警的记录就判断和更新,
|
|
|
|
+ * 结束报警就更新tAlarmInfo的报警数据的结束时间,并清空pAlarmInfo */
|
|
|
|
+ if(pAlarmInfo->Is_Alarm)
|
|
|
|
+ {
|
|
|
|
+ /* 正在报警中,检查是否报警结束 */
|
|
|
|
+ if(alarmInfo.Is_Alarm)
|
|
|
|
+ {
|
|
|
|
+ /* 更新图片信息 */
|
|
|
|
+ if(!alarmInfo.ImageInfo.empty())
|
|
|
|
+ {
|
|
|
|
+ pAlarmInfo->ImageInfo = alarmInfo.ImageInfo;
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ /* 报警结束,判断时长,更新数据库结束时间,结束时间是此时电脑时间 */
|
|
|
|
+ if(timeDiffWithNow(pAlarmInfo->EventTime) > g_config.Contraband)
|
|
|
|
+ {
|
|
|
|
+ pAlarmInfo->EndTime = chronoToStrTime(std::chrono::system_clock::now());
|
|
|
|
+ toEQMDataBase->updateAlarmEndTime(*pAlarmInfo);
|
|
|
|
+ }else {
|
|
|
|
+ /* 不够报警时间,目前不做任何处理,不删除EQM报警记录 */
|
|
|
|
+ }
|
|
|
|
|
|
- /* 清空报警信息 */
|
|
|
|
- pAlarmInfo->reInit();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- /* 是新的报警 */
|
|
|
|
- if(alarmInfo.Is_Alarm)
|
|
|
|
- {
|
|
|
|
- /* 布片不能是空,如果是空的,就不写入数据库 */
|
|
|
|
- if(!alarmInfo.ImageInfo.empty())
|
|
|
|
|
|
+ /* 清空报警信息 */
|
|
|
|
+ pAlarmInfo->reInit();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- /* 违禁品检测,开始时间是事件时间 */
|
|
|
|
- alarmInfo.StartTime = alarmInfo.EventTime;
|
|
|
|
- alarmInfo.EndTime = "";
|
|
|
|
- if(toEQMDataBase->insertAlarmInfo(alarmInfo))
|
|
|
|
|
|
+ /* 是新的报警 */
|
|
|
|
+ if(alarmInfo.Is_Alarm)
|
|
{
|
|
{
|
|
- /* 保存新的报警记录 */
|
|
|
|
- *pAlarmInfo = alarmInfo;
|
|
|
|
- }else {
|
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "写入tAlarmInfo报警数据失败, Key: {}", strKey);
|
|
|
|
|
|
+ /* 图片不能是空,如果是空的,就不写入数据库 */
|
|
|
|
+ if(!alarmInfo.ImageInfo.empty())
|
|
|
|
+ {
|
|
|
|
+ /* 违禁品检测,开始时间是事件时间 */
|
|
|
|
+ alarmInfo.StartTime = alarmInfo.EventTime;
|
|
|
|
+ alarmInfo.EndTime = "";
|
|
|
|
+ if(toEQMDataBase->insertAlarmInfo(alarmInfo))
|
|
|
|
+ {
|
|
|
|
+ /* 保存新的报警记录 */
|
|
|
|
+ *pAlarmInfo = alarmInfo;
|
|
|
|
+ }else {
|
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "写入tAlarmInfo报警数据失败, Key: {}", strKey);
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", pFuncAct->ChannelID, roomInfo.RoomID, it.first, it.second);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }else {
|
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", pActInfo->ChannelID, pActInfo->RoomID, pActInfo->CameraID, pActInfo->ActionID);
|
|
|
|
}
|
|
}
|
|
|
|
+
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
/* 休眠设置的时间 */
|
|
/* 休眠设置的时间 */
|
|
std::this_thread::sleep_for(std::chrono::seconds(g_config.ThreadSleepMS));
|
|
std::this_thread::sleep_for(std::chrono::seconds(g_config.ThreadSleepMS));
|
|
}
|
|
}
|
|
/* 设置线程退出的状态 */
|
|
/* 设置线程退出的状态 */
|
|
- setThreadState(pActInfo, RunTimeState::RUN_STATE_STOP);
|
|
|
|
- SPDLOG_LOGGER_INFO(m_logger, "{} 线程退出,RoomID:{} ,CameraID, Action:{}",pActInfo->strActionName, pActInfo->RoomID, pActInfo->CameraID, pActInfo->ActionID);
|
|
|
|
|
|
+ setThreadState(pFuncAct, RunTimeState::RUN_STATE_STOP);
|
|
|
|
+ SPDLOG_LOGGER_INFO(m_logger, "{} 线程退出,Channel:{}",pFuncAct->strFunctionName, pFuncAct->ChannelID);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -1188,7 +1100,7 @@ void SPAServer::threadActIllegalInvasion(ActionInfo* info)
|
|
while (m_threadRunning)
|
|
while (m_threadRunning)
|
|
{
|
|
{
|
|
/* 更新算法关联的摄像机ID */
|
|
/* 更新算法关联的摄像机ID */
|
|
- updateActionCameraID(pActInfo);
|
|
|
|
|
|
+ // updateActionCameraID(pActInfo);
|
|
/* 如果摄像机ID是小于0,那么这个算法就没有对应的摄像机了,线程就退出了 */
|
|
/* 如果摄像机ID是小于0,那么这个算法就没有对应的摄像机了,线程就退出了 */
|
|
if(pActInfo->CameraID < 0)
|
|
if(pActInfo->CameraID < 0)
|
|
{
|
|
{
|
|
@@ -1214,10 +1126,103 @@ void SPAServer::threadActIllegalInvasion(ActionInfo* info)
|
|
/* 判断有无报警记录,写入到EQM数据库 */
|
|
/* 判断有无报警记录,写入到EQM数据库 */
|
|
}
|
|
}
|
|
/* 设置线程退出的状态 */
|
|
/* 设置线程退出的状态 */
|
|
- setThreadState(pActInfo, RunTimeState::RUN_STATE_STOP);
|
|
|
|
|
|
+ // setThreadState(pActInfo, RunTimeState::RUN_STATE_STOP);
|
|
SPDLOG_LOGGER_INFO(m_logger, "非法入侵检测线程退出,RoomID:{} ,CameraID:{}, Action:{}", pActInfo->RoomID, pActInfo->CameraID, pActInfo->ActionID);
|
|
SPDLOG_LOGGER_INFO(m_logger, "非法入侵检测线程退出,RoomID:{} ,CameraID:{}, Action:{}", pActInfo->RoomID, pActInfo->CameraID, pActInfo->ActionID);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/* 将该算法对应的摄像机放入摄像机列表 */
|
|
|
|
+bool SPAServer::insertCameraToAction(RoomActionInfo* pRAInfo, std::list<RoomCameraInfo>& listRC, std::multimap<int, std::string>& mapCameraActionID)
|
|
|
|
+{
|
|
|
|
+ for(const auto& rci : listRC)
|
|
|
|
+ {
|
|
|
|
+ if(rci.RoomID == pRAInfo->RoomID)
|
|
|
|
+ {
|
|
|
|
+ /* 这个摄像机在这个房间内,再判断这个摄像机有没有这个算法 */
|
|
|
|
+ for(const auto& camID : rci.listCameraID)
|
|
|
|
+ {
|
|
|
|
+ for(const auto& cai : mapCameraActionID)
|
|
|
|
+ {
|
|
|
|
+ if(camID == cai.first)
|
|
|
|
+ {
|
|
|
|
+ /* 再判断这个摄像机的算法是否是当前需要的 */
|
|
|
|
+ if(cai.second == pRAInfo->ActionID)
|
|
|
|
+ {
|
|
|
|
+ pRAInfo->listCameraID.push_back(camID);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* 更新房间、算法需要的摄像机个数,从内存中更新 */
|
|
|
|
+bool SPAServer::updateRoomActionCameraCount(std::shared_ptr<RoomActionInfo> pRAInfo)
|
|
|
|
+{
|
|
|
|
+ std::lock_guard<std::mutex> look(m_mutexRunRAI);
|
|
|
|
+ for(auto& it : m_runListRoomActionInfo.getData())
|
|
|
|
+ {
|
|
|
|
+ if((it->RoomID == pRAInfo->RoomID) && (it->ActionID == pRAInfo->ActionID))
|
|
|
|
+ {
|
|
|
|
+ it->listCameraID = pRAInfo->listCameraID;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @brief 功能线程更新功能信息,这里是从内存中的数组里获取
|
|
|
|
+ *
|
|
|
|
+ * @param pInfo
|
|
|
|
+ * @return true
|
|
|
|
+ * @return false
|
|
|
|
+ */
|
|
|
|
+ bool SPAServer::updateFuncInfo(std::shared_ptr<FuncActionInfo> pInfo)
|
|
|
|
+{
|
|
|
|
+ pInfo->clearActionList();
|
|
|
|
+ std::lock_guard<std::mutex> look(m_mutexRunAI);
|
|
|
|
+ auto fa = m_runListFuncActInfo.findAppFunction(*pInfo);
|
|
|
|
+ if(fa == nullptr)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ *pInfo = *fa;
|
|
|
|
+
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* 设置线程状态 */
|
|
|
|
+void SPAServer::setThreadState(std::shared_ptr<FuncActionInfo> pInfo, RunTimeState state)
|
|
|
|
+{
|
|
|
|
+ std::lock_guard<std::mutex> look(m_mutexRunAI);
|
|
|
|
+ auto p = m_runListFuncActInfo.findAppFunction(*pInfo);
|
|
|
|
+ if(p != nullptr)
|
|
|
|
+ {
|
|
|
|
+ p->RunState = state;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/* 设置线程状态 */
|
|
|
|
+void SPAServer::setThreadState(std::shared_ptr<RoomActionInfo> pInfo, RunTimeState state)
|
|
|
|
+{
|
|
|
|
+ std::lock_guard<std::mutex> look(m_mutexRunRAI);
|
|
|
|
+ for(auto& it : m_runListRoomActionInfo.getData())
|
|
|
|
+ {
|
|
|
|
+ if(it->isEqualBaseInfo(*pInfo))
|
|
|
|
+ {
|
|
|
|
+ it->RunState = state;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
/* 计算与当前时间的时间差,返回秒 */
|
|
/* 计算与当前时间的时间差,返回秒 */
|
|
int SPAServer::timeDiffWithNow(const std::string& strTime)
|
|
int SPAServer::timeDiffWithNow(const std::string& strTime)
|
|
{
|
|
{
|