#include "FuncOrdinary.h" #include "GlobalVariable.h" #include "FromRedis.h" #include "ToEQMDataBase.h" #include "UniversalFunc.h" #include "GlobalConfig.h" FuncOrdinary::FuncOrdinary() { m_logger = spdlog::get("SPAServer"); if(m_logger == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "SPAServer logger is nullptr"); return; } /* 给变量分配内存 */ m_listAlarm = new ListAlarmInfo(); } FuncOrdinary::~FuncOrdinary() { if(m_listAlarm != nullptr) { delete m_listAlarm; m_listAlarm = nullptr; } } /* 任务线程 */ void FuncOrdinary::thread_task() { if(m_pFuncAct == nullptr) { SPDLOG_LOGGER_ERROR(m_logger, "未设置线程功能信息"); return; } SPDLOG_LOGGER_INFO(m_logger, "开启 {} 线程, ChannelID:{}",m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID); while (GThreadInfo.getRunning()) { /* 更新算法关联的摄像机ID */ // updateFuncInfo(pFuncAct); /* 如果线程的运行状态为 */ if(m_pFuncAct->RunState == RunTimeState::RUN_STATE_STOP) { /* 设置为NONE,就会被管理线程回收释放内存 */ m_pFuncAct->appFunction = AppFunction::APP_NONE; break; } /* 读取Redis信息,处理数据 */ for(const auto& roomInfo : m_pFuncAct->listRoomCamActInfo) { for(const auto& it : roomInfo.mapCameraAction) { /* 读取Redis数据 */ 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; } /* 找出数组中与当前报警ID相同的的报警信息 */ auto pAlarmInfo = m_listAlarm->findAlarmInfo(alarmInfo); if(pAlarmInfo == nullptr) { /* 没有找到报警记录,就新建一个 */ AlarmInfo newAlarmInfo = alarmInfo; m_listAlarm->addAlarmInfo(newAlarmInfo); /* 重新查找该报警信息 */ pAlarmInfo = m_listAlarm->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()); m_toEQMDataBase->updateAlarmEndTime(*pAlarmInfo); }else { /* 不够报警时间,目前不做任何处理,不删除EQM报警记录 */ } /* 清空报警信息 */ pAlarmInfo->reInit(); } } else { /* 是新的报警 */ if(alarmInfo.Is_Alarm) { /* 图片不能是空,如果是空的,就不写入数据库 */ if(!alarmInfo.ImageInfo.empty()) { /* 违禁品检测,开始时间是事件时间 */ alarmInfo.StartTime = alarmInfo.EventTime; alarmInfo.EndTime = ""; if(m_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); } } } } } /* 休眠设置的时间 */ std::this_thread::sleep_for(std::chrono::seconds(g_config.ThreadSleepMS)); } /* 设置线程退出的状态 */ setThreadState(m_pFuncAct, RunTimeState::RUN_STATE_STOP); SPDLOG_LOGGER_INFO(m_logger, "{} 线程退出,Channel:{}", m_pFuncAct->strFunctionName, m_pFuncAct->ChannelID); }