#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_pListRoomFace = new ListRoomFaceInfo(); } FuncPersonOnWork::~FuncPersonOnWork() { if(m_pListRoomFace != nullptr) { delete m_pListRoomFace; m_pListRoomFace = nullptr; } } /** * @brief 工作线程 * */ void FuncPersonOnWork::task() { while (GThreadInfo.getRunning()) { std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS())); /* 更新线程信息 */ GThreadInfo.updateFuncInfo(m_funcThreadInfo); if( (m_funcThreadInfo.appFunction == AppFunction::APP_NONE) || (m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP) ) { break; } /* 判断是否在检测时间段内 */ if(!isInDetectTime(m_periodInfo)) { continue; } /* ----------------------------------------------------------------------- * 读取Redis数据 * ----------------------------------------------------------------------- */ readRedisData(); /* ----------------------------------------------------------------------- * 处理数据 * ----------------------------------------------------------------------- */ /* 处理数据,将报警信息的人脸信息取出来,放入到人脸信息列表中 */ for(auto& alarmInfo : m_listSrcAlarm.listAlarmInfo) { /* 添加到人脸列表中,会自动去重,自动创建对应的频道和房间信息 */ m_pListRoomFace->addRoomFaceInfo(*alarmInfo); } /* 计算人脸个数,每个房间逐个对比 */ m_nowTime = 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(m_nowTime.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; } } m_listSrcAlarm.clearAlarmInfo(); } /* 读取Redis数据 */ void FuncPersonOnWork::readRedisData() { m_listSrcAlarm.clearAlarmInfo(); /* 读取Redis数据 */ for(const auto& roomInfo : m_funcThreadInfo.listRoomCamActInfo) { for(const auto& cam : roomInfo.mapCameraAction) { for(const auto act : cam.second) { /* 读取Redis数据 */ std::string strKey = std::to_string(cam.first) + ":" + act; std::string strRetValue; // SPDLOG_LOGGER_DEBUG(m_logger, "读取Redis数据, Key:{}", strKey); 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 newAlarmInfo; newAlarmInfo.ChannelID = m_funcThreadInfo.ChannelID; newAlarmInfo.appFunction = m_funcThreadInfo.appFunction; newAlarmInfo.RoomID = roomInfo.RoomID; newAlarmInfo.DeviceID = cam.first; newAlarmInfo.ActionID = act; parseRedisBaseData(strRetValue, newAlarmInfo); parseRedisBBoxesData(strRetValue, newAlarmInfo); /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */ if(!isEventTimeVaild(newAlarmInfo.EventTime)) { /* 事件时间超过600秒,可能是超脑挂了 */ SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString()); std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } m_listSrcAlarm.addAlarmInfo(newAlarmInfo); SPDLOG_LOGGER_DEBUG(m_logger, "报警数据: {}, 房间ID: {}, 报警时间: {}, bBox数目: {}, Person数目: {}", strKey, roomInfo.RoomID, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), newAlarmInfo.listBbox.size(), newAlarmInfo.listPersonInfo.size()); } } } }