FuncPersonOnWork.cpp__ 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #include "FuncPersonOnWork.h"
  2. #include "GlobalVariable.h"
  3. #include "GlobalConfig.h"
  4. #include "FromRedis.h"
  5. #include "FromWebAPI.h"
  6. #include "UniversalFunc.h"
  7. FuncPersonOnWork::FuncPersonOnWork()
  8. {
  9. m_logger = spdlog::get("SPAServer");
  10. if(m_logger == nullptr)
  11. {
  12. SPDLOG_LOGGER_ERROR(m_logger, "SPAServer logger is nullptr");
  13. return;
  14. }
  15. /* 给变量分配内存 */
  16. /* 保存人脸信息的数据 */
  17. m_pListRoomFace = new ListRoomFaceInfo();
  18. }
  19. FuncPersonOnWork::~FuncPersonOnWork()
  20. {
  21. if(m_pListRoomFace != nullptr)
  22. {
  23. delete m_pListRoomFace;
  24. m_pListRoomFace = nullptr;
  25. }
  26. }
  27. /**
  28. * @brief 工作线程
  29. *
  30. */
  31. void FuncPersonOnWork::task()
  32. {
  33. while (GThreadInfo.getRunning())
  34. {
  35. std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS()));
  36. /* 更新线程信息 */
  37. GThreadInfo.updateFuncInfo(m_funcThreadInfo);
  38. if( (m_funcThreadInfo.appFunction == AppFunction::APP_NONE) ||
  39. (m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP) )
  40. {
  41. break;
  42. }
  43. /* 判断是否在检测时间段内 */
  44. if(!isInDetectTime(m_periodInfo))
  45. {
  46. continue;
  47. }
  48. /* -----------------------------------------------------------------------
  49. * 读取Redis数据
  50. * ----------------------------------------------------------------------- */
  51. readRedisData();
  52. /* -----------------------------------------------------------------------
  53. * 处理数据
  54. * ----------------------------------------------------------------------- */
  55. /* 处理数据,将报警信息的人脸信息取出来,放入到人脸信息列表中 */
  56. for(auto& alarmInfo : m_listSrcAlarm.listAlarmInfo)
  57. {
  58. /* 添加到人脸列表中,会自动去重,自动创建对应的频道和房间信息 */
  59. m_pListRoomFace->addRoomFaceInfo(*alarmInfo);
  60. }
  61. /* 计算人脸个数,每个房间逐个对比 */
  62. m_nowTime = QDateTime::currentDateTime();
  63. for(auto it = m_pListRoomFace->listRoomFaceInfo.begin(); it != m_pListRoomFace->listRoomFaceInfo.end(); )
  64. {
  65. /* m_pListRoomFace的数据不会删除,会和历史对比,这里的MaxNum和MinNum就是历史数据 */
  66. if(it->MaxNum < it->listPersonInfo.size())
  67. {
  68. it->MaxNum = it->listPersonInfo.size();
  69. }
  70. if(it->MinNum > it->listPersonInfo.size())
  71. {
  72. it->MinNum = it->listPersonInfo.size();
  73. }
  74. /* 判断是否需要写入数据库,一定时间写入一次,默认是10分钟写一次 */
  75. if(m_nowTime.toSecsSinceEpoch() - it->StartTime.toSecsSinceEpoch() > GVariable.AppUpdateOnWorkTimeInterval_Time)
  76. {
  77. /* 写入数据库 */
  78. if(m_fromWebAPI->insertOnWorkInfo(*it))
  79. {
  80. SPDLOG_LOGGER_INFO(m_logger, "☆ 新增人脸信息,频道[{}][{}],摄像头[{}][{}],时间范围[{} - {}],人数范围[{} - {}]",
  81. it->ChannelID, GConfig.getChannelName(it->ChannelID), it->CameraID, GConfig.getCameraName(it->CameraID),
  82. it->StartTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(), it->EndTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
  83. it->MinNum, it->MaxNum);
  84. /* 删除这条信息 */
  85. it = m_pListRoomFace->listRoomFaceInfo.erase(it);
  86. continue;
  87. }else {
  88. SPDLOG_LOGGER_ERROR(m_logger, "写入数据库tWorkOnInfo失败");
  89. }
  90. }
  91. ++it;
  92. }
  93. }
  94. m_listSrcAlarm.clearAlarmInfo();
  95. }
  96. /* 读取Redis数据 */
  97. void FuncPersonOnWork::readRedisData()
  98. {
  99. m_listSrcAlarm.clearAlarmInfo();
  100. /* 读取Redis数据 */
  101. for(const auto& roomInfo : m_funcThreadInfo.listRoomCamActInfo)
  102. {
  103. for(const auto& cam : roomInfo.mapCameraAction)
  104. {
  105. for(const auto act : cam.second)
  106. {
  107. /* 读取Redis数据 */
  108. std::string strKey = std::to_string(cam.first) + ":" + act;
  109. std::string strRetValue;
  110. // SPDLOG_LOGGER_DEBUG(m_logger, "读取Redis数据, Key:{}", strKey);
  111. if(!m_fromRedis->getRedisString(strKey, strRetValue))
  112. {
  113. // SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
  114. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  115. continue;
  116. }
  117. /* 解析数据,先设置基础数据 */
  118. AlarmInfo newAlarmInfo;
  119. newAlarmInfo.ChannelID = m_funcThreadInfo.ChannelID;
  120. newAlarmInfo.appFunction = m_funcThreadInfo.appFunction;
  121. newAlarmInfo.RoomID = roomInfo.RoomID;
  122. newAlarmInfo.DeviceID = cam.first;
  123. newAlarmInfo.ActionID = act;
  124. parseRedisBaseData(strRetValue, newAlarmInfo);
  125. parseRedisBBoxesData(strRetValue, newAlarmInfo);
  126. /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
  127. if(!isEventTimeVaild(newAlarmInfo.EventTime))
  128. {
  129. /* 事件时间超过600秒,可能是超脑挂了 */
  130. SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString());
  131. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  132. continue;
  133. }
  134. m_listSrcAlarm.addAlarmInfo(newAlarmInfo);
  135. SPDLOG_LOGGER_DEBUG(m_logger, "报警数据: {}, 房间ID: {}, 报警时间: {}, bBox数目: {}, Person数目: {}",
  136. strKey, roomInfo.RoomID, newAlarmInfo.EventTime.toString("yyyy-MM-dd hh:mm:ss").toStdString(),
  137. newAlarmInfo.listBbox.size(), newAlarmInfo.listPersonInfo.size());
  138. }
  139. }
  140. }
  141. }