#include "UniversalFunc.h" #include "spdlog/spdlog.h" #include "GlobalVariable.h" #include "GlobalConfig.h" /** * @brief 解析Redis的基础通用数据,不包含bBoxes数组数据 * * @param strData Redis返回的源数据,JSON格式 * @param alarmInfo 解析出来的数据 */ void parseRedisBaseData(const std::string& strData, AlarmInfo& alarmInfo) { try { nJson json0; json0 = nJson::parse(strData); alarmInfo.AlarmID = json0["alarmId"].get(); alarmInfo.ChannelID = json0["channel"].get(); alarmInfo.PicUrl = json0["picUrl"].get(); alarmInfo.ImageInfo = json0["imageInfo"].get(); /* 解析时间,需要将时间中的“T”换成空格 */ alarmInfo.StartTime = json0["beginTime"].get(); std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' '); alarmInfo.EndTime = json0["endTime"].get(); std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' '); alarmInfo.EventTime = json0["eventTime"].get(); std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' '); } catch (const nJson::parse_error& e) { SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id); return; } catch (const nJson::type_error& e) { SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id); return; } catch (...) { SPDLOG_ERROR("解析Redis数据失败,其他错误!"); return; } } /** * @brief 解析Redis的bBoxes数据,这个内容可能根据算法ID不同,内容不同 * * @param strData * @param alarmInfo */ void parseRedisBBoxesData(const std::string& strData, AlarmInfo& alarmInfo) { try { nJson json0; json0 = nJson::parse(strData); /* 判断bBoxes有无数据,有数据就解析,没数据就直接返回了 */ nJson json1 = json0["bBoxes"]; std::string labelList; /* 记录违禁品 */ std::list listBbox; /* 记录bbox */ if(!json1.empty()) { for(auto& it0 : json1) { /* 如果status是true,就不是报警,直接跳过 */ bool status = it0["status"].get(); if(status) { continue; } /* 这一条Box数据报警了将其内容存储起来 */ alarmInfo.Is_Alarm = true; /* 解析label,违禁品关键字,先判断这个是不是违禁品检测的算法ID */ if(alarmInfo.ActionID == GVariable.ActContraband) { /* 解析报警,取出报警类型 */ nJson label = it0["label"]; for(auto& it1 : label) { std::string strLabel = it1.get(); /* 检测是否已经加入到字符串中了 */ strLabel += "|"; if(labelList.find(strLabel) != std::string::npos) { continue; } labelList += strLabel; } } /* 解析bbox,貌似是在图像中的位置 */ nJson bbox = it0["bbox"]; std::string strBbox; for(auto& it1 : bbox) { strBbox += std::to_string(it1.get()) + ","; } /* 去掉最后一个“,” */ if(!strBbox.empty()) { strBbox.pop_back(); } listBbox.push_back(strBbox); } /* 去掉最后一个“|” */ if(!labelList.empty()) { labelList.pop_back(); } SPDLOG_DEBUG("违禁品列表:{}", labelList); } /* 如果有报警的Box,解析出报警的说明 */ if(alarmInfo.Is_Alarm) { /* 添加报警信息的提示信息 */ alarmInfo.listBbox = listBbox; /* 违禁品报警信息,违禁品列表不是空的,就添加补充的文字 */ if( (alarmInfo.ActionID == GVariable.ActContraband) && !labelList.empty() ) { alarmInfo.ActionDes = fmt::format("出现违禁品[{}]告警", labelList); SPDLOG_INFO("{}", alarmInfo.ActionDes); }else { /* 其他报警信息,直接获取 */ alarmInfo.ActionDes = json0["actionDes"].get(); } /* 判断有没有报警数据 */ if(alarmInfo.ImageInfo.empty()) { SPDLOG_WARN("有报警区域,但是没有图片信息"); return; } /* 如果是人员报警,就存储人员报警信息 */ if(alarmInfo.ActionID == GVariable.ActFaceIdentify) { nJson jsonArray = json0["personList"]; for(auto& it : jsonArray) { PersonInfo personInfo; personInfo.PersonID = it["personId"].get(); personInfo.PersonName = it["personName"].get(); alarmInfo.listPersonInfo.push_back(personInfo); } } } } catch (const nJson::parse_error& e) { SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id); return; } catch (const nJson::type_error& e) { SPDLOG_ERROR("解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id); return; } catch (...) { SPDLOG_ERROR("解析Redis数据失败,其他错误!"); return; } } /** * @brief 判断时间是否长时间没有更新,默认的是600秒,超过这个时间Redis还未更新,可能是超脑挂了 * * @param strTime * @return true * @return false */ bool isEventTimeVaild(const std::string& strTime) { /* 获取当前时间 */ std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); /* 字符串转成时间 */ std::istringstream iss(strTime); std::tm tmEvent = {}; iss >> std::get_time(&tmEvent, "%Y-%m-%d %H:%M:%S"); /* 时间差 */ std::chrono::system_clock::time_point eventTime = std::chrono::system_clock::from_time_t(std::mktime(&tmEvent)); std::chrono::duration diff = now - eventTime; // SPDLOG_LOGGER_DEBUG(m_logger, "now:{} eventTime: {} 时间差:{}秒",now, eventTime, diff); if(diff.count() > 600) { // SPDLOG_LOGGER_ERROR(m_logger, "Redis数据长时间没有更新,EventTime:{}", strTime); return false; } return true; } /* 计算与当前时间的时间差,返回秒 */ int timeDiffWithNow(const std::string& strTime) { auto now = std::chrono::system_clock::now(); auto eventTime = strTimeToChrono(strTime); std::chrono::duration diff = now - eventTime; return diff.count(); } /* 字符串时间转换成std::chrono时间点 */ std::chrono::system_clock::time_point strTimeToChrono(const std::string& strTime) { std::istringstream iss(strTime); std::tm tmEvent = {}; iss >> std::get_time(&tmEvent, "%Y-%m-%d %H:%M:%S"); return std::chrono::system_clock::from_time_t(std::mktime(&tmEvent)); } /* 时间点转换成字符串 */ std::string chronoToStrTime(const std::chrono::system_clock::time_point& timePoint) { std::time_t time = std::chrono::system_clock::to_time_t(timePoint); std::tm tmEvent = *std::localtime(&time); char buf[64] = {0}; std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tmEvent); return std::string(buf); } /* 通过应用ID获取应用名称 */ std::string getAppFunctionName(const AppFunction appID) { std::string strRet; switch(appID) { case AppFunction::APP_OnWork: strRet = "人员在岗识别"; break; case AppFunction::APP_Contraband: strRet = "违禁物品识别"; break; case AppFunction::APP_Illegal: strRet = "区域非法入侵检测"; break; case AppFunction::APP_Fatigue: strRet = "疲劳检测识别"; break; case AppFunction::APP_Regional: strRet = "区域人员统计"; break; case AppFunction::APP_Mouse: strRet = "老鼠识别"; break; case AppFunction::APP_PlayPhone: strRet = "玩手机识别"; break; case AppFunction::APP_NoMask: strRet = "未戴口罩识别"; break; case AppFunction::APP_AllDown: strRet = "摔倒识别"; break; default: strRet = "未知功能"; break; } return strRet; }