FuncRegionalPerson.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #include "FuncRegionalPerson.h"
  2. #include "FromWebAPI.h"
  3. #include "FromRedis.h"
  4. #include "GlobalConfig.h"
  5. #include "GlobalVariable.h"
  6. #include "UniversalFunc.h"
  7. PersonCountRuleInfo::PersonCountRuleInfo()
  8. {
  9. ChannelID = -1;
  10. week = 0;
  11. RuleType = Enum_PeriodType::PERIOD_ALL;
  12. LiveMinEnable = false;
  13. LiveMaxEnable = false;
  14. DicMinEnable = false;
  15. DicMaxEnable = false;
  16. LiveDicMinEnable = false;
  17. LiveDicMaxEnable = false;
  18. LiveMin = 0;
  19. LiveMax = 0;
  20. DicMin = 0;
  21. DicMax = 0;
  22. LiveDicMin = 0;
  23. LiveDicMax = 0;
  24. RuleName = "";
  25. }
  26. PersonCountRuleInfo& PersonCountRuleInfo::operator=(PersonCountRuleInfo& other)
  27. {
  28. if(this != &other)
  29. {
  30. ChannelID = other.ChannelID;
  31. week = other.week;
  32. RuleType = other.RuleType;
  33. PeriodName = other.PeriodName;
  34. StartTime = other.StartTime;
  35. EndTime = other.EndTime;
  36. LiveMinEnable = other.LiveMinEnable;
  37. LiveMaxEnable = other.LiveMaxEnable;
  38. DicMinEnable = other.DicMinEnable;
  39. DicMaxEnable = other.DicMaxEnable;
  40. LiveDicMinEnable = other.LiveDicMinEnable;
  41. LiveDicMaxEnable = other.LiveDicMaxEnable;
  42. LiveMin = other.LiveMin;
  43. LiveMax = other.LiveMax;
  44. DicMin = other.DicMin;
  45. DicMax = other.DicMax;
  46. LiveDicMin = other.LiveDicMin;
  47. LiveDicMax = other.LiveDicMax;
  48. RuleName = other.RuleName;
  49. }
  50. return *this;
  51. }
  52. EndAlarmParam::EndAlarmParam()
  53. {
  54. ChannelID = -1;
  55. AppID = AppFunction::APP_NONE;
  56. CameraID = -1;
  57. insertAlarmNum = 0;
  58. }
  59. EndAlarmParam::EndAlarmParam(const EndAlarmParam& other)
  60. {
  61. ChannelID = other.ChannelID;
  62. AppID = other.AppID;
  63. CameraID = other.CameraID;
  64. insertAlarmNum = other.insertAlarmNum;
  65. }
  66. EndAlarmParam& EndAlarmParam::operator=(const EndAlarmParam& other)
  67. {
  68. if(this != &other)
  69. {
  70. ChannelID = other.ChannelID;
  71. AppID = other.AppID;
  72. CameraID = other.CameraID;
  73. insertAlarmNum = other.insertAlarmNum;
  74. }
  75. return *this;
  76. }
  77. bool EndAlarmParam::operator==(const EndAlarmParam& other)
  78. {
  79. if(this == &other)
  80. {
  81. return true;
  82. }
  83. if(ChannelID != other.ChannelID)
  84. {
  85. return false;
  86. }
  87. if(AppID != other.AppID)
  88. {
  89. return false;
  90. }
  91. if(CameraID != other.CameraID)
  92. {
  93. return false;
  94. }
  95. if(insertAlarmNum != other.insertAlarmNum)
  96. {
  97. return false;
  98. }
  99. return true;
  100. }
  101. FuncRegionalPersonCount::FuncRegionalPersonCount()
  102. {
  103. m_logger = spdlog::get("SPAServer");
  104. if(m_logger == nullptr)
  105. {
  106. SPDLOG_ERROR("SPAServer logger is nullptr");
  107. return;
  108. }
  109. m_pListAlarm = new ListAlarmInfo();
  110. if(m_pListAlarm == nullptr)
  111. {
  112. SPDLOG_ERROR("FuncRegionalPersonDetection m_pListAlarm is nullptr");
  113. return;
  114. }
  115. }
  116. FuncRegionalPersonCount::~FuncRegionalPersonCount()
  117. {
  118. if(m_pListAlarm != nullptr)
  119. {
  120. delete m_pListAlarm;
  121. m_pListAlarm = nullptr;
  122. }
  123. }
  124. void FuncRegionalPersonCount::task()
  125. {
  126. while (m_bRunning)
  127. {
  128. std::this_thread::sleep_for(std::chrono::milliseconds(GConfig.ThreadSleepMS));
  129. /* 更新线程信息,并判断是否需要退出 */
  130. GThreadInfo.updateFuncInfo(m_funcThreadInfo);
  131. if( (m_funcThreadInfo.appFunction == AppFunction::APP_NONE) ||
  132. (m_funcThreadInfo.RunState == RunTimeState::RUN_STATE_STOP) )
  133. {
  134. break;
  135. }
  136. /* 判断是否在检测时间段内 */
  137. // if(!isInDetectTime(m_funcThreadInfo.StartTime, m_funcThreadInfo.EndTime))
  138. // {
  139. // continue;
  140. // }
  141. /* 更新报警规则 */
  142. if(!getPersonCountRuleInfo(m_personCountRule))
  143. {
  144. /* 判断报警是否已经结束,没有结束就结束报警 */
  145. autoEndAlarm();
  146. continue;
  147. }
  148. m_nowTime = QDateTime::currentDateTime();
  149. /************ 判断是否在检测时间内 ************/
  150. if(!isInPeriodTime())
  151. {
  152. SPDLOG_LOGGER_INFO(m_logger, "★ 频道[{}][{}],{},不在检测时段",
  153. m_funcThreadInfo.ChannelID, m_funcThreadInfo.strChannelName,
  154. getAppFunctionName(m_funcThreadInfo.appFunction));
  155. /* 判断报警是否已经结束,没有结束就结束报警 */
  156. autoEndAlarm();
  157. continue;
  158. }
  159. /* 更新房间列表 */
  160. updateRoomList();
  161. if(m_listRoomCamAct.empty())
  162. {
  163. SPDLOG_LOGGER_ERROR(m_logger, "★ 频道[{}][{}],{},房间列表为空",
  164. m_funcThreadInfo.ChannelID, m_funcThreadInfo.strChannelName,
  165. getAppFunctionName(m_funcThreadInfo.appFunction));
  166. /* 判断报警是否已经结束,没有结束就结束报警 */
  167. autoEndAlarm();
  168. continue;
  169. }
  170. /* -----------------------------------------------------------------------
  171. * 读取Redis数据
  172. * ----------------------------------------------------------------------- */
  173. m_pListAlarm->clearAlarmInfo();
  174. for(const auto& RoomInfo : m_listRoomCamAct)
  175. {
  176. for(const auto& it : RoomInfo.mapCameraAction)
  177. {
  178. for(const auto& act : it.second)
  179. {
  180. std::string strKey = std::to_string(it.first) + ":" + act;
  181. std::string strRetValue;
  182. if(!m_fromRedis->getRedisString(strKey, strRetValue))
  183. {
  184. SPDLOG_LOGGER_ERROR(m_logger, "读取Redis数据失败, Key:{}", strKey);
  185. continue;
  186. }
  187. /* 解析数据 */
  188. AlarmInfo alarmInfo;
  189. parseRedisBaseData(strRetValue, alarmInfo);
  190. parseRedisBBoxesData(strRetValue, alarmInfo);
  191. /* 判断事件的时效性,超过多少秒不更新就可能是超脑挂了 */
  192. if(isEventTimeVaild(alarmInfo.EventTime))
  193. {
  194. SPDLOG_LOGGER_WARN(m_logger, "Redis Key:{} 数据长时间没有更新,EventTime:{}",strKey, alarmInfo.EventTime);
  195. continue;
  196. }
  197. m_pListAlarm->addAlarmInfo(alarmInfo);
  198. }
  199. }
  200. }
  201. /************ 挨个房间检测人数 ************/
  202. /************ 检测频率直播间 + 导播间房间的人数 ************/
  203. }
  204. }
  205. /* 获取该频率的人员计数规则 */
  206. bool FuncRegionalPersonCount::getPersonCountRuleInfo(PersonCountRuleInfo& personCountRuleInfo)
  207. {
  208. std::list<PersonCountRuleInfo> listRule;
  209. if(!m_fromWebAPI->getPersonCountRuleInfo(listRule))
  210. {
  211. SPDLOG_LOGGER_ERROR(m_logger, "获取《人员计数》报警规则失败");
  212. return false;
  213. }
  214. if(listRule.size() == 0)
  215. {
  216. SPDLOG_LOGGER_ERROR(m_logger, "★ 频道[{}][{}],{},未配置人员计数规则",
  217. m_funcThreadInfo.ChannelID, m_funcThreadInfo.strChannelName,
  218. getAppFunctionName(m_funcThreadInfo.appFunction));
  219. return false;
  220. }
  221. /* 获取这个频率的报警信息 */
  222. m_personCountRule.ChannelID = -1;
  223. for(auto& it : listRule)
  224. {
  225. if(it.ChannelID == m_funcThreadInfo.ChannelID)
  226. {
  227. m_personCountRule = it;
  228. break;
  229. }
  230. }
  231. if(m_personCountRule.ChannelID == -1)
  232. {
  233. SPDLOG_LOGGER_ERROR(m_logger, "频率:{}《人员计数》无报警规则", m_funcThreadInfo.ChannelID);
  234. return false;
  235. }
  236. return true;
  237. }
  238. /* 判断是否在检测时间段内 */
  239. bool FuncRegionalPersonCount::isInPeriodTime()
  240. {
  241. /* 所有时段 */
  242. if(m_personCountRule.RuleType == Enum_PeriodType::PERIOD_ALL)
  243. {
  244. return true;
  245. }
  246. /* 按天检测 */
  247. else if(m_personCountRule.RuleType == Enum_PeriodType::PERIOD_DAY)
  248. {
  249. if(m_personCountRule.StartTime <= m_nowTime && m_personCountRule.EndTime >= m_nowTime)
  250. {
  251. /* 在检测时间内 */
  252. return true;
  253. } else {
  254. /* 不在检测时间内 */
  255. return false;
  256. }
  257. }
  258. /* 按周检测 */
  259. else if (m_personCountRule.RuleType == Enum_PeriodType::PERIOD_WEEK)
  260. {
  261. if(m_personCountRule.week != m_nowTime.date().dayOfWeek())
  262. {
  263. /* 一周日期不相等 */
  264. return false;
  265. }
  266. /* 判断周日期是否相等 */
  267. if(m_personCountRule.StartTime.time() <= m_nowTime.time() && m_personCountRule.EndTime.time() >= m_nowTime.time())
  268. {
  269. return true;
  270. } else {
  271. /* 不在检测时间内 */
  272. return false;
  273. }
  274. }
  275. return true;
  276. }
  277. /* 更新房间列表 */
  278. void FuncRegionalPersonCount::updateRoomList()
  279. {
  280. /* 清空房间列表 */
  281. m_listRoomCamAct.clear();
  282. for(const auto& it : m_funcThreadInfo.listRoomCamActInfo)
  283. {
  284. /* 只添加直播间和导播间 */
  285. if(it.RoomType == Enum_RoomType::ROOM_LIVE || it.RoomType == Enum_RoomType::ROOM_DIC)
  286. {
  287. m_listRoomCamAct.push_back(it);
  288. }
  289. }
  290. }
  291. /* 自动结束报警 */
  292. void FuncRegionalPersonCount::autoEndAlarm()
  293. {
  294. EndAlarmParam alarmParam;
  295. alarmParam.ChannelID = m_funcThreadInfo.ChannelID;
  296. alarmParam.AppID = m_funcThreadInfo.appFunction;
  297. /* 判断报警是否已经结束,没有结束就结束报警 */
  298. if(findAlarmEnd(alarmParam))
  299. {
  300. SPDLOG_LOGGER_DEBUG(m_logger, "频率:{}《人员计数》报警已经结束", m_funcThreadInfo.strChannelName);
  301. return;
  302. }
  303. if(!m_fromWebAPI->endPersonCountAlarm(alarmParam))
  304. {
  305. SPDLOG_LOGGER_ERROR(m_logger, "频率:{}《人员计数》结束报警失败", m_funcThreadInfo.strChannelName);
  306. return;
  307. }
  308. /* 记录已经结束报警的信息,限制一下记录列表的大小 */
  309. if(m_listEndAlarmPara.size() > 1024)
  310. {
  311. m_listEndAlarmPara.clear();
  312. }
  313. m_listEndAlarmPara.push_back(alarmParam);
  314. }
  315. /* 查找是否已经结束了报警 */
  316. bool FuncRegionalPersonCount::findAlarmEnd(EndAlarmParam& alarmParam)
  317. {
  318. if(m_listEndAlarmPara.empty())
  319. {
  320. return false;
  321. }
  322. for(auto& it : m_listEndAlarmPara)
  323. {
  324. if(it == alarmParam)
  325. {
  326. return true;
  327. }
  328. }
  329. return false;
  330. }