Răsfoiți Sursa

V0.1.11
1、解析了部分Redis数据

Apple 7 luni în urmă
părinte
comite
b06d365712

+ 36 - 2
SecurePlayAuxServer/GlobalInfo.h

@@ -150,9 +150,43 @@ struct DeviceAlgorithmInfo
 
 
 
+/**
+ * @brief 摄像机线程需要的信息
+ * 
+ */
+struct CameraThreadInfo
+{
+    std::string RedisIP;        /* Redis IP */
+    int RedisPort;              /* Redis Port */
+    std::string RedisPWD;       /* Redis Password */
+    int DeviceID;               /* 设备ID */
+    std::vector<std::string> vecAction;  /* Redis Key,一个设备可能会有多个算法ID */
+};
 
-
-
+/**
+ * @brief 报警信息
+ * 
+ */
+struct AlarmInfo
+{
+    int AlarmID;                /* 报警ID */
+    int DeviceID;               /* 设备ID,数据库表格中对应的是CamerID */
+    
+    int RoomID;                 /* 房间ID */
+    int ChannelID;              /* 通道ID */
+    int OnWork;                 /* 是否在工作 */
+    bool State;                 /* 状态 */
+    std::string ActionID;       /* 算法ID */
+    std::string StartTime;      /* 报警开始时间 */
+    std::string EndTime;        /* 报警结束时间 */
+    std::string EventTime;      /* 事件时间(报警发生时间,在数据库里对应的是CreateTime) */
+    std::string PicUrl;         /* 报警图片URL */
+    std::string AppID;          /* 客户端应用ID */
+    std::string ActionDes;      /* 算法描述信息 */
+    std::string FaceIDList;     /* 人脸ID列表 */
+    std::string FaceNameList;   /* 人脸名称列表 */
+    
+};
 
 
 

+ 125 - 28
SecurePlayAuxServer/SPAServer.cpp

@@ -21,8 +21,8 @@ SPAServer::SPAServer()
     m_threadRunning = true;
     /* 初始化WebAPI */
     m_toEQMDataBase.initWebApi("http://192.1.3.133:31000/v6/", "", "4c2f9fc91c22dd98331e47af2e2964f4");
-
-
+    /* 模拟违禁品算法ID,后续需要动态调整 */
+    m_contrabandKey = "OD210_026_005246_001-IZRTKyEx";
     
 }
 
@@ -35,7 +35,17 @@ SPAServer::~SPAServer()
 void SPAServer::startServer()
 {
     /* 添加获取基础信息的线程 */
-    CPPTP.add_task(&SPAServer::fromSuperBrainThread, this);
+    // CPPTP.add_task(&SPAServer::threadFromSuperBrain, this);
+
+    /* 测试Redis读取并解析数据线程 */
+    CameraThreadInfo info;
+    info.RedisIP = "172.16.36.80";
+    info.RedisPort = 32222;
+    info.RedisPWD = "Ff1z@TOFr^iwd%Ra";
+    info.DeviceID = 117;
+    info.vecAction.push_back("OD210_026_005246_001-IZRTKyEx");
+    CPPTP.add_task(&SPAServer::threadFromRedis, this, info);
+
 }
 
 
@@ -43,36 +53,12 @@ void SPAServer::startServer()
  * @brief 从基础平台获取算法信息和设备信息的线程函数
  * 
  */
-void SPAServer::fromSuperBrainThread()
+void SPAServer::threadFromSuperBrain()
 {
     SPDLOG_LOGGER_INFO(m_logger, "开启 fromSuperBrainThread 线程");
     /* 创建变量 */
     std::vector<AlgorithmInfo> vecAlgNewInfo;
     std::vector<DeviceInfo> vecDevNewInfo;
-    
-    /* 测试读取Redis信息 */
-    m_fromRedis.setRedisIPAndPort("172.16.36.80", 32222);
-    m_fromRedis.setRedisPassword("Ff1z@TOFr^iwd%Ra");
-    if(m_fromRedis.connectRedis())
-    {
-        SPDLOG_LOGGER_INFO(m_logger, "连接Redis成功");
-    }else {
-        SPDLOG_LOGGER_ERROR(m_logger, "连接Redis失败");
-        return;
-    }
-
-    std::string strKey = "117:OD210_026_005246_001-IZRTKyEx";
-    std::string strRetValue;
-    while (m_threadRunning)
-    {
-        SPDLOG_LOGGER_INFO(m_logger, "读取Redis信息");
-        m_fromRedis.getRedisString(strKey, strRetValue);
-        SPDLOG_LOGGER_DEBUG(m_logger, "Redis Value:\n{}", strRetValue);
-        
-        std::this_thread::sleep_for(std::chrono::seconds(1));
-    }
-    
-    return;
 
     /* 获取一次token,后续失效了再获取 */
     m_fromSuperBrain.getToken();
@@ -365,3 +351,114 @@ void SPAServer::compareDeviceAlgorithmInfo(const std::vector<DeviceInfo>& vecNew
 }
 
 
+
+/**
+ * @brief 从Redis获取数据线程函数,这个是摄像机线程
+ *        一个设备一个线程,这个线程的相关变量只在这个线程中使用
+ * 
+ * @param info 
+ */
+void SPAServer::threadFromRedis(const CameraThreadInfo& info)
+{
+    SPDLOG_LOGGER_INFO(m_logger, "开启 fromRedisThread 线程,设备ID:{}", info.DeviceID);
+    FromRedis fromRedis;
+    fromRedis.setRedisIPAndPort(info.RedisIP, info.RedisPort);
+    fromRedis.setRedisPassword(info.RedisPWD);
+    if(fromRedis.connectRedis())
+    {
+        SPDLOG_LOGGER_INFO(m_logger, "连接Redis成功");
+    }else {
+        SPDLOG_LOGGER_ERROR(m_logger, "连接Redis失败");
+        return;
+    }
+
+    // std::string strKey = "117:OD210_026_005246_001-IZRTKyEx";
+    /* 取出该设备的Key */
+    std::vector<std::string> vecKey;
+    for(const auto& it : info.vecAction)
+    {
+        std::string strKey = std::to_string(info.DeviceID) + ":" + it;
+        vecKey.push_back(strKey);
+    }
+    std::string strRetValue;
+    while (m_threadRunning)
+    {
+        /* 循环读取这个设备关联的算法信息 */
+        for(const auto& it : vecKey)
+        {
+            SPDLOG_LOGGER_INFO(m_logger, "读取Redis信息, Key: {}", it);
+            fromRedis.getRedisString(it, strRetValue);
+            SPDLOG_LOGGER_TRACE(m_logger, "Redis Value:\n{}", strRetValue);
+            /* 解析数据 */
+            AlarmInfo alarmInfo;
+            alarmInfo.ActionID = it;
+            parseRedisData(strRetValue, alarmInfo);
+        }
+
+
+        std::this_thread::sleep_for(std::chrono::seconds(1));
+    }
+    
+    return;
+}
+
+/* 解析Redis基础数据 */
+void SPAServer::parseRedisData(const std::string& strData, AlarmInfo& alarmInfo)
+{
+
+    try
+    {
+        nJson json0;
+        json0 = nJson::parse(strData);
+        alarmInfo.AlarmID = json0["alarmId"].get<int>();
+        alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
+        alarmInfo.ChannelID = json0["channel"].get<int>();
+        alarmInfo.PicUrl = json0["picUrl"].get<std::string>();
+        
+        /* 解析时间,需要将时间中的“T”换成空格 */
+        alarmInfo.StartTime = json0["beginTime"].get<std::string>();
+        std::replace(alarmInfo.StartTime.begin(), alarmInfo.StartTime.end(), 'T', ' ');
+        alarmInfo.EndTime = json0["endTime"].get<std::string>();
+        std::replace(alarmInfo.EndTime.begin(), alarmInfo.EndTime.end(), 'T', ' ');
+        alarmInfo.EventTime = json0["eventTime"].get<std::string>();
+        std::replace(alarmInfo.EventTime.begin(), alarmInfo.EventTime.end(), 'T', ' ');
+        /* 判断bBoxes有无数据,有数据就解析,没数据就直接返回了 */
+        nJson json1 = json0["bBoxes"];
+        if(!json1.empty())
+        {
+            for(auto& it0 : json1)
+            {
+                /* 如果status是true,就不是报警,直接跳过 */
+                bool status = it0["status"].get<bool>();
+                if(alarmInfo.State)
+                {
+                    continue;
+                }
+                /* 判断这个是不是违禁品检测的算法ID */
+                if(alarmInfo.ActionID == m_contrabandKey)
+                {
+                    /* 解析报警 */
+                }
+            }
+        }
+        
+
+        alarmInfo.ActionDes = json0["actionDes"].get<std::string>();
+        if(alarmInfo.ActionDes.empty())
+        {
+            alarmInfo.ActionDes = "出现违禁品";
+        }
+    }
+    catch (const nJson::parse_error& e)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
+        return;
+    }
+    catch (const nJson::type_error& e)
+    {
+        SPDLOG_LOGGER_ERROR(m_logger, "解析Redis数据失败:{}, 错误ID:{}", e.what(), e.id);
+        return;
+    }
+
+}
+

+ 9 - 3
SecurePlayAuxServer/SPAServer.h

@@ -20,7 +20,7 @@ public:
 
 private:
     /* 从基础平台获取算法信息和设备信息的线程函数 */
-    void fromSuperBrainThread();
+    void threadFromSuperBrain();
     /* 处理算法信息,返回值为true,说明有改变,需要重新读取 */
     bool processAlgorithmInfo(std::vector<AlgorithmInfo> vecNewAlgInfo);
     /* 处理设备信息,传入新获取到的值,返回true需要更新本地数据缓存 */
@@ -28,7 +28,12 @@ private:
     /* 对比算法信息现有的数据和新获取到的数据,取出要删除和添加的数据 */
     void compareAlgorithmInfo(const std::vector<AlgorithmInfo>& vecNewInfo, std::vector<AlgorithmInfo>& vecAlgUpdate, std::vector<AlgorithmInfo>& vecAlgDelete);
     /* 对比设备和算法关联表是否需要更新 */
-    void compareDeviceAlgorithmInfo(const std::vector<DeviceInfo>& vecNewInfo, std::vector<DeviceInfo>& vecDevUpdate);   
+    void compareDeviceAlgorithmInfo(const std::vector<DeviceInfo>& vecNewInfo, std::vector<DeviceInfo>& vecDevUpdate);
+
+    /* 从Redis获取数据线程函数,这个是摄像机线程 */
+    void threadFromRedis(const CameraThreadInfo& info);
+    /* 解析Redis基础数据 */
+    void parseRedisData(const std::string& strData, AlarmInfo& alarmInfo);
 
 private:
     std::shared_ptr<spdlog::logger> m_logger = nullptr;
@@ -36,9 +41,10 @@ private:
     bool m_threadRunning = true;                        /* 线程正在运行 */
 
     FromSuperBrain m_fromSuperBrain;
-    FromRedis m_fromRedis;
     ToEQMDataBase m_toEQMDataBase;
 
+    std::string m_contrabandKey;                        /* 违禁品检测的Key */
+
     /* 算法信息,这个就是tAction在内存中的数据,方便后续对比,程序启动的时候会先获取一份 */
     std::vector<AlgorithmInfo> m_vecEqmAlgInfo;
     /* 设备信息,这个是tActionCamer的信息 */

+ 48 - 2
安播辅助服务程序说明.md

@@ -1,7 +1,7 @@
 # 安播辅助服务程序说明
 
 ## 程序运行流程
-1. 从~~超脑WebAPI~~ Redis取出基础信息,基础信息包括
+1. 从`超脑WebAPI` 取出基础信息,基础信息包括
     - 算法信息
     - 平台信息(摄像机信息)
 2. 从总控WebAPI获取到相关的`处理规则`
@@ -55,7 +55,53 @@
     
 ## 从Redis获取数据
 1. `Key`的组成:`%d : %s`, `DeviceID`, `算法ID`
-2. `算法ID`通过获取摄像头算法列表获取到这个设备的算法编号,关键字是`ability`,存放在EQM数据库的tAction表格的ActionID,
+2. `算法ID`通过获取摄像头算法列表获取到这个设备的算法编号,关键字是`ability`,存放在EQM数据库的tAction表格的ActionID
+3. Redis获取到的是JSON格式的数据,写入`tAlarmInfo`表格,需要根据Redis数据去其他表格获取补充数据,组合好后写入`tAlarmInfo`表格。Redis数据格式如下:
+    ```JSON
+    {
+        "actionDes": "",
+        "actionResult": true,
+        "alarmId": 73113,
+        "beginTime": "2024-09-01T16:52:38.426",
+        "channel": 1,
+        "classifyId": 64,
+        "classifyName": "培训教室-海康",
+        "deviceSerial": "172.16.9.31",
+        "endTime": "2024-09-01T16:53:38.426",
+        "eventTime": "2024-09-01T16:53:08.426",
+        "imageInfo": "http://webdav-read.default:80/webdav//GUI/1/PUMPING/2024/09/01//66d42b74e4b02066478c1ace.jpg",
+        "isKeyPoint": 0,
+        "personList": [],
+        "picUrl": "66d42b74e4b02066478c1ace.jpg",
+        "taskId": 452,
+        "taskName": "夜晚001",
+        "bBoxes": [
+        {
+            "bbox": [
+            1692,
+            369,
+            1791,
+            604
+            ],
+            "colorFlag": 1,
+            "conf": [
+            "0.03"
+            ],
+            "label": [
+            "未成年人"
+            ],
+            "match_id": "",
+            "status": false
+        }
+        ]
+    }
+    ```
+4. 补充数据关键字和其对应的EQM库表格
+    |关键字|补充表格|所需的数据|
+    |:--|:--|:--|
+    |channel|tChannel|获取通道信息|
+    |CamerId|tRoomCamer|获取到RoomId|
+    |RoomId|tRoomInfo|获取到Room信息|
 
 ## EQM数据库表格说明
 1. `tAction`是算法信息表,从超脑获取到的算法信息写入这个表格