UniversalFunc.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. #include "UniversalFunc.h"
  2. #include "spdlog/spdlog.h"
  3. #include "GlobalVariable.h"
  4. #include "GlobalConfig.h"
  5. /**
  6. * @brief 解析Redis的基础通用数据,不包含bBoxes数组数据
  7. *
  8. * @param strData Redis返回的源数据,JSON格式
  9. * @param alarmInfo 解析出来的数据
  10. */
  11. void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo)
  12. {
  13. try
  14. {
  15. nJson json0;
  16. json0 = nJson::parse(strData);
  17. alarmInfo.AlarmID = json0["alarmId"].get<int>();
  18. alarmInfo.ChannelID = json0["channel"].get<int>();
  19. alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
  20. alarmInfo.ImageInfo = json0["imageInfo"].get<std::string>();
  21. /* 解析时间,需要将时间中的“T”换成空格 */
  22. alarmInfo.StartTime = json0["beginTime"].get<std::string>();
  23. std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
  24. alarmInfo.EndTime = json0["endTime"].get<std::string>();
  25. std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
  26. alarmInfo.EventTime = json0["eventTime"].get<std::string>();
  27. std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
  28. }
  29. catch (const nJson::parse_error& e)
  30. {
  31. SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
  32. return;
  33. }
  34. catch (const nJson::type_error& e)
  35. {
  36. SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
  37. return;
  38. }
  39. catch (...)
  40. {
  41. SPDLOG_ERROR("解析Redis数据失败,其他错误!");
  42. return;
  43. }
  44. }
  45. /**
  46. * @brief 解析Redis的bBoxes数据,这个内容可能根据算法ID不同,内容不同
  47. *
  48. * @param strData
  49. * @param alarmInfo
  50. */
  51. void parseRedisBBoxesData(const std::string& strData, AlarmInfo& alarmInfo)
  52. {
  53. try
  54. {
  55. nJson json0;
  56. json0 = nJson::parse(strData);
  57. /* 判断bBoxes有无数据,有数据就解析,没数据就直接返回了 */
  58. nJson json1 = json0["bBoxes"];
  59. std::string labelList; /* 记录违禁品 */
  60. std::list<std::string> listBbox; /* 记录bbox */
  61. if(!json1.empty())
  62. {
  63. for(auto& it0 : json1)
  64. {
  65. /* 如果status是true,就不是报警,直接跳过 */
  66. bool status = it0["status"].get<bool>();
  67. if(status)
  68. {
  69. continue;
  70. }
  71. /* 这一条Box数据报警了将其内容存储起来 */
  72. alarmInfo.Is_Alarm = true;
  73. /* 解析label,违禁品关键字,先判断这个是不是违禁品检测的算法ID */
  74. if(alarmInfo.ActionID == GVariable.ActContraband)
  75. {
  76. /* 解析报警,取出报警类型 */
  77. nJson label = it0["label"];
  78. for(auto& it1 : label)
  79. {
  80. std::string strLabel = it1.get<std::string>();
  81. /* 检测是否已经加入到字符串中了 */
  82. strLabel += "|";
  83. if(labelList.find(strLabel) != std::string::npos)
  84. {
  85. continue;
  86. }
  87. labelList += strLabel;
  88. }
  89. }
  90. /* 解析bbox,貌似是在图像中的位置 */
  91. nJson bbox = it0["bbox"];
  92. std::string strBbox;
  93. for(auto& it1 : bbox)
  94. {
  95. strBbox += std::to_string(it1.get<int>()) + ",";
  96. }
  97. /* 去掉最后一个“,” */
  98. if(!strBbox.empty())
  99. {
  100. strBbox.pop_back();
  101. }
  102. listBbox.push_back(strBbox);
  103. }
  104. /* 去掉最后一个“|” */
  105. if(!labelList.empty())
  106. {
  107. labelList.pop_back();
  108. }
  109. SPDLOG_DEBUG("违禁品列表:{}", labelList);
  110. }
  111. /* 如果有报警的Box,解析出报警的说明 */
  112. if(alarmInfo.Is_Alarm)
  113. {
  114. /* 添加报警信息的提示信息 */
  115. alarmInfo.listBbox = listBbox;
  116. /* 违禁品报警信息,违禁品列表不是空的,就添加补充的文字 */
  117. if( (alarmInfo.ActionID == GVariable.ActContraband) && !labelList.empty() )
  118. {
  119. alarmInfo.ActionDes = fmt::format("出现违禁品[{}]告警", labelList);
  120. SPDLOG_INFO("{}", alarmInfo.ActionDes);
  121. }else {
  122. /* 其他报警信息,直接获取 */
  123. alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
  124. }
  125. /* 判断有没有报警数据 */
  126. if(alarmInfo.ImageInfo.empty())
  127. {
  128. SPDLOG_WARN("有报警区域,但是没有图片信息");
  129. return;
  130. }
  131. /* 如果是人员报警,就存储人员报警信息 */
  132. if(alarmInfo.ActionID == GVariable.ActFaceIdentify)
  133. {
  134. nJson jsonArray = json0["personList"];
  135. for(auto& it : jsonArray)
  136. {
  137. PersonInfo personInfo;
  138. personInfo.PersonID = it["personId"].get<std::string>();
  139. personInfo.PersonName = it["personName"].get<std::string>();
  140. alarmInfo.listPersonInfo.push_back(personInfo);
  141. }
  142. }
  143. }
  144. }
  145. catch (const nJson::parse_error& e)
  146. {
  147. SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
  148. return;
  149. }
  150. catch (const nJson::type_error& e)
  151. {
  152. SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
  153. return;
  154. }
  155. catch (...)
  156. {
  157. SPDLOG_ERROR("解析Redis数据失败,其他错误!");
  158. return;
  159. }
  160. }
  161. /**
  162. * @brief 判断时间是否长时间没有更新,默认的是600秒,超过这个时间Redis还未更新,可能是超脑挂了
  163. *
  164. * @param strTime
  165. * @return true
  166. * @return false
  167. */
  168. bool isEventTimeVaild(const std::string& strTime)
  169. {
  170. /* 获取当前时间 */
  171. std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
  172. /* 字符串转成时间 */
  173. std::istringstream iss(strTime);
  174. std::tm tmEvent = {};
  175. iss >> std::get_time(&tmEvent, "%Y-%m-%d %H:%M:%S");
  176. /* 时间差 */
  177. std::chrono::system_clock::time_point eventTime = std::chrono::system_clock::from_time_t(std::mktime(&tmEvent));
  178. std::chrono::duration<double> diff = now - eventTime;
  179. // SPDLOG_LOGGER_DEBUG(m_logger, "now:{} eventTime: {} 时间差:{}秒",now, eventTime, diff);
  180. if(diff.count() > 600)
  181. {
  182. // SPDLOG_LOGGER_ERROR(m_logger, "Redis数据长时间没有更新,EventTime:{}", strTime);
  183. return false;
  184. }
  185. return true;
  186. }
  187. /* 计算与当前时间的时间差,返回秒 */
  188. int timeDiffWithNow(const std::string& strTime)
  189. {
  190. auto now = std::chrono::system_clock::now();
  191. auto eventTime = strTimeToChrono(strTime);
  192. std::chrono::duration<double> diff = now - eventTime;
  193. return diff.count();
  194. }
  195. /* 字符串时间转换成std::chrono时间点 */
  196. std::chrono::system_clock::time_point strTimeToChrono(const std::string& strTime)
  197. {
  198. std::istringstream iss(strTime);
  199. std::tm tmEvent = {};
  200. iss >> std::get_time(&tmEvent, "%Y-%m-%d %H:%M:%S");
  201. return std::chrono::system_clock::from_time_t(std::mktime(&tmEvent));
  202. }
  203. /* 时间点转换成字符串 */
  204. std::string chronoToStrTime(const std::chrono::system_clock::time_point& timePoint)
  205. {
  206. std::time_t time = std::chrono::system_clock::to_time_t(timePoint);
  207. std::tm tmEvent = *std::localtime(&time);
  208. char buf[64] = {0};
  209. std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmEvent);
  210. return std::string(buf);
  211. }
  212. /* 通过应用ID获取应用名称 */
  213. std::string getAppFunctionName(const AppFunction appID)
  214. {
  215. std::string strRet;
  216. switch(appID)
  217. {
  218. case AppFunction::APP_OnWork:
  219. strRet = "人员在岗识别";
  220. break;
  221. case AppFunction::APP_Contraband:
  222. strRet = "违禁物品识别";
  223. break;
  224. case AppFunction::APP_Illegal:
  225. strRet = "区域非法入侵检测";
  226. break;
  227. case AppFunction::APP_Fatigue:
  228. strRet = "疲劳检测识别";
  229. break;
  230. case AppFunction::APP_Regional:
  231. strRet = "区域人员统计";
  232. break;
  233. case AppFunction::APP_Mouse:
  234. strRet = "老鼠识别";
  235. break;
  236. case AppFunction::APP_PlayPhone:
  237. strRet = "玩手机识别";
  238. break;
  239. case AppFunction::APP_NoMask:
  240. strRet = "未戴口罩识别";
  241. break;
  242. case AppFunction::APP_AllDown:
  243. strRet = "摔倒识别";
  244. break;
  245. default:
  246. strRet = "未知功能";
  247. break;
  248. }
  249. return strRet;
  250. }