#include "FuncOnAndOffJob.h" #include "GlobalVariable.h" #include "GlobalConfig.h" #include "UniversalFunc.h" #include "FromRedis.h" #include "ToEQMDataBase.h" DecCondition::DecCondition() { ChannelID = -1; leaveNum = 0; leaveNumOnTime = 0; leaveOneTime = 0; } DecCondition::DecCondition(const DecCondition& other) { ChannelID = other.ChannelID; leaveNum = other.leaveNum; leaveNumOnTime = other.leaveNumOnTime; leaveOneTime = other.leaveOneTime; } DecCondition& DecCondition::operator=(const DecCondition& other) { if (this != &other) { ChannelID = other.ChannelID; leaveNum = other.leaveNum; leaveNumOnTime = other.leaveNumOnTime; leaveOneTime = other.leaveOneTime; } return *this; } RoomOnWorkInfo& RoomOnWorkInfo::operator=(const RoomOnWorkInfo& other) { if (this != &other) { bOnWork = other.bOnWork; RoomID = other.RoomID; CameraID = other.CameraID; RoomType = other.RoomType; StartTime = other.StartTime; EndTime = other.EndTime; strImagePath = other.strImagePath; listPersonInfo = other.listPersonInfo; } return *this; } RoomOnWorkInfo::RoomOnWorkInfo(const RoomOnWorkInfo& other) { bOnWork = other.bOnWork; RoomID = other.RoomID; CameraID = other.CameraID; RoomType = other.RoomType; StartTime = other.StartTime; EndTime = other.EndTime; strImagePath = other.strImagePath; listPersonInfo = other.listPersonInfo; } FuncOnAndOffJob::FuncOnAndOffJob() { m_pListAlarm = new ListAlarmInfo(); m_logger = spdlog::get("SPAServer"); if(m_logger == nullptr) { SPDLOG_ERROR("FuncOnAndOffJob logger is nullptr"); return; } } FuncOnAndOffJob::~FuncOnAndOffJob() { } /* 获取当前频率信息 */ bool FuncOnAndOffJob::getCurrentFrequencyInfo(const int ChannelID, DecCondition& info) { auto str = m_toEQMDataBase->getChannelName(ChannelID); if(str == "") { SPDLOG_LOGGER_ERROR(m_logger, "获取通道信息失败, ChannelID:{}", ChannelID); return false; } /* 解析数据 */ try { nJson json1 = nJson::parse(str); info.ChannelID = ChannelID; info.leaveNum = json1["leaveNum"].is_null() ? 0 : json1["leaveNum"].get(); info.leaveNumOnTime = json1["leaveNumTime"].is_null() ? 0 : json1["leaveNumTime"].get(); info.leaveOneTime = json1["leaveLongTime"].is_null() ? 0 : json1["leaveLongTime"].get(); } catch (const nJson::parse_error& e) { SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id); return false; } catch (const nJson::type_error& e) { SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败:{}, 错误ID:{}",e.what(), e.id); return false; } catch(...) { SPDLOG_LOGGER_ERROR(m_logger,"解析 tChannel数据失败 数据失败"); return false; } return true; } void FuncOnAndOffJob::task() { while(GThreadInfo.getRunning()) { /* 判断是否需要退出 */ if(m_funcAct.RunState == RunTimeState::RUN_STATE_STOP) { break; } /* 判断是否在检测时间段内 */ if(!isInDetectTime(m_funcAct.StartTime, m_funcAct.EndTime)) { /* 休眠一段时间 */ std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS)); continue; } /* 先获取所有的直播间,这里不需要读取所有的房间数据 */ std::map mapRoomCamActInfo; for(auto& it : m_funcAct.listRoomCamActInfo) { /* 判断是不是直播间 */ if(it.RoomType == GConfig.liveRoomType) { mapRoomCamActInfo.insert(std::make_pair(it.RoomID, it)); } } /* 获取当前频率的在岗离岗信息,在表格“tChannel”中 */ DecCondition decCondition; if(!getCurrentFrequencyInfo(m_funcAct.ChannelID, decCondition)) { SPDLOG_LOGGER_ERROR(m_logger, "获取当前频率信息失败, ChannelID:{}", m_funcAct.ChannelID); std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS)); continue; } /* 读取Redis数据 */ for(const auto& RoomInfo : mapRoomCamActInfo) { for(const auto& it : RoomInfo.second.mapCameraAction) { std::string strKey = std::to_string(it.first) + ":" + it.second; std::string strRetValue; if(!m_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; } m_pListAlarm->addAlarmInfo(alarmInfo); } } /* 对所有房间挨个判断 */ for(auto& roomInfo : mapRoomCamActInfo) { bool bHasPeople = false; bool bHasFace = false; /* 先使用人员计数判断直播间有没有人,如果直播间有人,再使用人脸识别算法判断是否是认识的人(是认识的人才会被识别到) */ for(auto& alarm : m_pListAlarm->listAlarmInfo) { if(alarm->RoomID == roomInfo.first) { if(alarm->ActionID == g_actionList.ActPersonNumber) { if(alarm->listBbox.size() > 0) { bHasPeople = true; break; } } } } /* 如果有人,再判断是不是认识的人 */ if(bHasPeople) { for(auto& alarm : m_pListAlarm->listAlarmInfo) { if(alarm->RoomID == roomInfo.first) { if(alarm->ActionID == g_actionList.ActFace) { if(alarm->vecPersonInfo.size() > 0) { bHasFace = true; break; } } } } } /* 查找这个房间对应的房间信息 */ RoomOnWorkInfo* pRoomOnWorkInfo = nullptr; auto it0 = m_mapRoomOnWorkInfo.find(roomInfo.first); if(it0 != m_mapRoomOnWorkInfo.end()) { pRoomOnWorkInfo = it0->second; } else { /* 没找到,就创建一个 */ pRoomOnWorkInfo = new RoomOnWorkInfo(); pRoomOnWorkInfo->RoomID = roomInfo.first; } } } }