#include "FuncPersonOnWork.h" #include "GlobalVariable.h" #include "GlobalConfig.h" #include "FromRedis.h" #include "FromWebAPI.h" #include "UniversalFunc.h" FuncPersonOnWork::FuncPersonOnWork() { m_logger = spdlog::get("SPAServer"); if(m_logger == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "SPAServer logger is nullptr"); return; } /* 给变量分配内存 */ /* 保存每个摄像机的报警信息 */ m_pListAlarm = std::make_shared>(); /* 保存人脸信息的数据 */ m_pListRoomFace = new ListRoomFaceInfo(); } FuncPersonOnWork::~FuncPersonOnWork() { if(m_pListRoomFace != nullptr) { delete m_pListRoomFace; m_pListRoomFace = nullptr; } } /** * @brief 工作线程 * */ void FuncPersonOnWork::task() { while (GThreadInfo.getRunning()) { /* 更新线程信息 */ GThreadInfo.updateFuncInfo(m_funcThreadInfo); if( (m_funcThreadInfo.appFunction == AppFunction::APP_NONE) || (m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP) ) { break; } /* 判断是否在检测时间段内 */ if(!isInDetectTime(m_funcThreadInfo.StartTime, m_funcThreadInfo.EndTime)) { std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS)); continue; } /* ----------------------------------------------------------------------- * 读取Redis数据 * ----------------------------------------------------------------------- */ m_pListAlarm->clear(); for(const auto& RoomInfo : m_funcThreadInfo.listRoomCamActInfo) { for(const auto& it : RoomInfo.mapCameraAction) { for(const auto& act : it.second) { /* 读取Redis数据 */ std::string strKey = std::to_string(it.first) + ":" + act; 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(10)); continue; } /* 解析数据 */ AlarmInfo alarmInfo; alarmInfo.ActionID = act; 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->push_back(alarmInfo); } } } /* 处理数据,将报警信息的人脸信息取出来,放入到人脸信息列表中 */ for(auto& alarmInfo : *m_pListAlarm) { /* 添加到人脸列表中,会自动去重,自动创建对应的频道和房间信息 */ m_pListRoomFace->addRoomFaceInfo(alarmInfo); } /* 计算人脸个数,每个房间逐个对比 */ QDateTime now = QDateTime::currentDateTime(); for(auto it = m_pListRoomFace->listRoomFaceInfo.begin(); it != m_pListRoomFace->listRoomFaceInfo.end(); ) { /* m_pListRoomFace的数据不会删除,会和历史对比,这里的MaxNum和MinNum就是历史数据 */ if(it->MaxNum < it->listPersonInfo.size()) { it->MaxNum = it->listPersonInfo.size(); } if(it->MinNum > it->listPersonInfo.size()) { it->MinNum = it->listPersonInfo.size(); } /* 判断是否需要写入数据库,一定时间写入一次,默认是10分钟写一次 */ if(now.toSecsSinceEpoch() - it->StartTime.toSecsSinceEpoch() > GVariable.AppUpdateOnWorkTimeInterval_Time) { /* 写入数据库 */ if(m_fromWebAPI->insertOnWorkInfo(*it)) { SPDLOG_LOGGER_INFO(m_logger, "☆ 新增人脸信息,频道[{}][{}],摄像头[{}][{}],时间范围[{} - {}],人数范围[{} - {}]", it->ChannelID, GConfig.getChannelName(it->ChannelID), it->CameraID, GConfig.getCameraName(it->CameraID), it->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), it->EndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), it->MinNum, it->MaxNum); /* 删除这条信息 */ it = m_pListRoomFace->listRoomFaceInfo.erase(it); continue; }else { SPDLOG_LOGGER_ERROR(m_logger, "写入数据库tWorkOnInfo失败"); } } ++it; } std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS)); } }