FuncOrdinary.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include "FuncOrdinary.h"
  2. #include "GlobalVariable.h"
  3. #include "FromRedis.h"
  4. #include "FromWebAPI.h"
  5. #include "UniversalFunc.h"
  6. #include "GlobalConfig.h"
  7. FuncOrdinary::FuncOrdinary()
  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. FuncOrdinary::~FuncOrdinary()
  18. {
  19. }
  20. /* 任务线程 */
  21. void FuncOrdinary::task()
  22. {
  23. while (GThreadInfo.getRunning())
  24. {
  25. /* 从全局的信息块中更新功能信息,如是否需要退出线程,主要是更新摄像机关联的算法信息 */
  26. GThreadInfo.updateFuncInfo(m_funcThreadInfo);
  27. /* 如果线程的运行状态为停止 */
  28. if(m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP)
  29. {
  30. /* 退出线程 */
  31. break;
  32. }
  33. /* 判断是否在检测时间段内 */
  34. if(!isInDetectTime(m_funcThreadInfo.StartTime, m_funcThreadInfo.EndTime))
  35. {
  36. std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS));
  37. continue;
  38. }
  39. /* 读取Redis信息,处理数据,第一层循环是根据房间读取,第二个循环是根据房间内的摄像机读取 */
  40. for(const auto& roomInfo : m_funcThreadInfo.listRoomCamActInfo)
  41. {
  42. for(const auto& it : roomInfo.mapCameraAction)
  43. {
  44. for(const auto act : it.second)
  45. {
  46. /* 读取Redis数据 */
  47. std::string strKey = std::to_string(it.first) + ":" + act;
  48. std::string strRetValue;
  49. if(!m_fromRedis->getRedisString(strKey, strRetValue))
  50. {
  51. SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
  52. std::this_thread::sleep_for(std::chrono::milliseconds(10));
  53. continue;
  54. }
  55. /* 解析数据,先设置基础数据 */
  56. AlarmInfo newAlarmInfo;
  57. newAlarmInfo.ActionID = act;
  58. newAlarmInfo.appFunction = m_funcThreadInfo.appFunction;
  59. parseRedisBaseData(strRetValue, newAlarmInfo);
  60. parseRedisBBoxesData(strRetValue, newAlarmInfo);
  61. /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
  62. if(isEventTimeVaild(newAlarmInfo.EventTime))
  63. {
  64. SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, newAlarmInfo.EventTime);
  65. std::this_thread::sleep_for(std::chrono::milliseconds(100));
  66. continue;
  67. }
  68. /* -------------------------------------------------------------------------------
  69. * 判断有无报警记录,新的报警就先创建一个报警信息,写入报警列表,超过报警的最小误报时间后,
  70. * 再写入到EQM的tAlarmInfo表中,正在报警的记录就判断和更新,结束报警就更新tAlarmInfo的
  71. * 报警数据的结束时间,并清空pAlarmInfo
  72. * ------------------------------------------------------------------------------- */
  73. /* 找出数组中与当前报警ID相同的的报警信息 */
  74. auto pAlarmInfo = m_listAlarm.findAlarmInfo(newAlarmInfo);
  75. /* 没有找到报警记录,就新建一个 */
  76. if(pAlarmInfo == nullptr)
  77. {
  78. /* 新记录有报警,新建报警记录 */
  79. if(newAlarmInfo.Is_Alarm)
  80. {
  81. /* 图片不能是空,如果是空的,就不写入数据库 */
  82. if(!newAlarmInfo.ImageInfo.empty())
  83. {
  84. /* 违禁品检测,开始时间是事件时间 */
  85. newAlarmInfo.StartTime = newAlarmInfo.EventTime;
  86. newAlarmInfo.EndTime = "";
  87. /* 保存新的报警记录 */
  88. newAlarmInfo.Is_InsertEQM = false;
  89. m_listAlarm.addAlarmInfo(newAlarmInfo);
  90. }else
  91. {
  92. SPDLOG_LOGGER_WARN(m_logger, "频道:{}, 房间:{}, 摄像机:{}, 算法:{}, 有报警区域, 但是没有图片信息", m_funcThreadInfo.ChannelID, roomInfo.RoomID, it.first, act);
  93. }
  94. }
  95. }
  96. /* 已有报警记录 */
  97. else
  98. {
  99. /* 更新图片信息 */
  100. if(!newAlarmInfo.ImageInfo.empty())
  101. {
  102. pAlarmInfo->ImageInfo = newAlarmInfo.ImageInfo;
  103. }
  104. /* 判断是否还在报警中 */
  105. if(newAlarmInfo.Is_Alarm)
  106. {
  107. /* 正在报警中,检查是否已经写入到数据库中 */
  108. if(pAlarmInfo->Is_InsertEQM)
  109. {
  110. /* 已经写入到数据库中,不做处理 */
  111. }else
  112. {
  113. /* 判断报警时长间隔是否足够 */
  114. if(!isAlarmTimeVaild(*pAlarmInfo))
  115. {
  116. /* 不够报警时间,直接进行下一个循环 */
  117. continue;
  118. }
  119. /* 写入到数据库 */
  120. pAlarmInfo->Is_InsertEQM = false;
  121. if(m_fromWebAPI->insertAlarmInfo(*pAlarmInfo))
  122. {
  123. pAlarmInfo->Is_InsertEQM = true;
  124. }else {
  125. SPDLOG_LOGGER_ERROR(m_logger, "写入tAlarmInfo报警数据失败, 频率:{}, 房间:{}, 算法:{} ", m_funcThreadInfo.ChannelID, roomInfo.RoomID, act);
  126. }
  127. }
  128. } else
  129. {
  130. /* 报警结束,判断时长,如果小于设置的最小间隔,可能是误报警
  131. * 更新数据库结束时间,结束时间是此时电脑时间 */
  132. if(isAlarmTimeVaild(*pAlarmInfo))
  133. {
  134. pAlarmInfo->EndTime = chronoToStrTime(std::chrono::system_clock::now());
  135. /* 判断是否已经写入到数据库中 */
  136. if(pAlarmInfo->Is_InsertEQM)
  137. {
  138. /* 已经写入到数据库中,更新结束时间 */
  139. m_fromWebAPI->updateAlarmEndTime(*pAlarmInfo);
  140. }else {
  141. /* 没有写入到数据库中,写入到数据库中 */
  142. m_fromWebAPI->insertAlarmInfo(*pAlarmInfo);
  143. }
  144. SPDLOG_LOGGER_INFO(m_logger, "频率:{}, 房间:{}, 摄像机:{}, 算法:{}, 报警结束", m_funcThreadInfo.ChannelID, roomInfo.RoomID, it.first, act);
  145. }
  146. /* 删除这个报警信息 */
  147. m_listAlarm.deleteAlarmInfo(*pAlarmInfo);
  148. }
  149. }
  150. }
  151. }
  152. }
  153. /* 休眠设置的时间 */
  154. std::this_thread::sleep_for(std::chrono::milliseconds(GVariable.ThreadSleepMS));
  155. }
  156. }
  157. /* 判断报警时长是否符合不同应用的最小间隔 */
  158. bool FuncOrdinary::isAlarmTimeVaild(const AlarmInfo& info)
  159. {
  160. /* 违禁品物品 */
  161. if(info.appFunction == AppFunction::APP_Contraband)
  162. {
  163. if(timeDiffWithNow(info.EventTime) < GVariable.AppContraband_Time)
  164. {
  165. return false;
  166. }
  167. }
  168. /* 玩手机识别 */
  169. else if(info.appFunction == AppFunction::APP_PlayPhone)
  170. {
  171. if(timeDiffWithNow(info.EventTime) < GVariable.AppPlayPhone)
  172. {
  173. return false;
  174. }
  175. }
  176. /* 老鼠识别 */
  177. else if(info.appFunction == AppFunction::APP_Mouse)
  178. {
  179. if(timeDiffWithNow(info.EventTime) < GVariable.AppMouse)
  180. {
  181. return false;
  182. }
  183. }
  184. /* 未戴口罩识别 */
  185. else if(info.appFunction == AppFunction::APP_NoMask)
  186. {
  187. if(timeDiffWithNow(info.EventTime) < GVariable.AppMask)
  188. {
  189. return false;
  190. }
  191. }
  192. /* 疲劳检测 */
  193. else if(info.appFunction == AppFunction::APP_Fatigue)
  194. {
  195. if(timeDiffWithNow(info.EventTime) < GVariable.AppTired_Time)
  196. {
  197. return false;
  198. }
  199. }
  200. /* 摔倒识别 */
  201. else if(info.appFunction == AppFunction::APP_AllDown)
  202. {
  203. return true;
  204. }
  205. return true;
  206. }