From 1b00804522534a5f9579d318776572eed9f228a2 Mon Sep 17 00:00:00 2001 From: zw <3466561528@qq.com> Date: Tue, 23 Sep 2025 14:03:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=A3=85=E7=BD=AE?= =?UTF-8?q?=E5=91=8A=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LFtid1056/LFtid1056.vcxproj | 1 - LFtid1056/LFtid1056.vcxproj.filters | 3 - LFtid1056/cloudfront/code/log4.h | 3 +- LFtid1056/dealMsg.cpp | 1123 +++++++++++++++------------ 4 files changed, 610 insertions(+), 520 deletions(-) diff --git a/LFtid1056/LFtid1056.vcxproj b/LFtid1056/LFtid1056.vcxproj index f510365..93bdaf4 100644 --- a/LFtid1056/LFtid1056.vcxproj +++ b/LFtid1056/LFtid1056.vcxproj @@ -147,7 +147,6 @@ - diff --git a/LFtid1056/LFtid1056.vcxproj.filters b/LFtid1056/LFtid1056.vcxproj.filters index faebd3c..96eaa06 100644 --- a/LFtid1056/LFtid1056.vcxproj.filters +++ b/LFtid1056/LFtid1056.vcxproj.filters @@ -169,9 +169,6 @@ cloudfront\code\nlohmann\thirdparty\hedley - - cloudfront\code\log4cplus - cloudfront\code\log4cplus diff --git a/LFtid1056/cloudfront/code/log4.h b/LFtid1056/cloudfront/code/log4.h index ec52585..c4d47c8 100644 --- a/LFtid1056/cloudfront/code/log4.h +++ b/LFtid1056/cloudfront/code/log4.h @@ -121,7 +121,8 @@ typedef enum LogCode { LOG_CODE_LOG_REQUEST = 405, /* 日志请求 */ LOG_CODE_REPORT = 500, /* 报告处理 */ LOG_CODE_COMM = 600, /* 通讯状态 */ - LOG_CODE_SPACE_ALARM = 700 /* 空间告警 */ + LOG_CODE_SPACE_ALARM = 700, /* 空间告警 */ + LOG_CODE_DEV_ALARM = 800 /* 装置告警 */ } LogCode; // ====================== 日志宏区域 ====================== diff --git a/LFtid1056/dealMsg.cpp b/LFtid1056/dealMsg.cpp index 39bfb51..55a0834 100644 --- a/LFtid1056/dealMsg.cpp +++ b/LFtid1056/dealMsg.cpp @@ -8,46 +8,47 @@ #include #include #include -#include // mkdir +#include // 用于mkdir #include #include "cloudfront/code/interface.h" //lnk20250708 #include "cloudfront/code/rocketmq.h" //lnk20250708 #include "client2.h" +#include "cloudfront/code/log4.h" using namespace std; -SafeMessageQueue message_queue; // ȫϢ +SafeMessageQueue message_queue; // 全局消息队列 -//ʱת +//时间转换函数 time_t ConvertToTimestamp(const tagTime& time) { struct tm t = {}; - t.tm_year = time.DeviceYear - 1900; // tm_year 1900 ʼ - t.tm_mon = time.DeviceMonth - 1; // tm_mon 01£ʼ + t.tm_year = time.DeviceYear - 1900; // tm_year 从 1900 开始计 + t.tm_mon = time.DeviceMonth - 1; // tm_mon 从 0(1月)开始 t.tm_mday = time.DeviceDay; t.tm_hour = time.DeviceHour; t.tm_min = time.DeviceMinute; t.tm_sec = time.DeviceSecond; - // ʱʱ䣩 + // 返回时间戳(本地时间) return mktime(&t); } -//ļָȡֶ +//文件分割取字段 std::string extract_filename(const std::string& path) { - // һ'/'λ + // 查找最后一个'/'的位置 size_t last_slash = path.find_last_of('/'); - // ҵ'/'򷵻'/'֮IJ + // 如果找到'/',则返回'/'之后的部分 if (last_slash != std::string::npos) { return path.substr(last_slash + 1); } - // û'/'ֱӷԭַ + // 如果没有'/',直接返回原字符串 return path; } -//ļcrcУ麯 +//文件crc校验函数 uint16_t crc_16_new(const uint8_t* buf, uint32_t len) { uint16_t crc = 0xffff; for (uint32_t i = 0; i < len; i++) { @@ -64,55 +65,55 @@ uint16_t crc_16_new(const uint8_t* buf, uint32_t len) { return crc; } -//Ϣ߼ +//消息处理逻辑 void process_received_message(string mac, string id,const char* data, size_t length) { - // ʵʵϢ߼ + // 实际的消息处理逻辑 std::cout << "Active connections: " << mac << " id:" << id << " size:" << length << std::endl; - // յϢҵָװˢ¶ӦͨѶʱ + // 接收到消息后,先找到指定装置刷新对应最新通讯时间戳 ClientManager::instance().set_cloudmessage_time(id); - //ݴ߼ + //数据处理逻辑 if (length > 0) { - // תΪ޷Ա㴦ֵ + // 将数据转为无符号类型以便处理二进制值 const unsigned char* udata = reinterpret_cast(data); - //Ϣij--¼ĸʽ + //对数据消息的初步处理--登录报文格式解析不出来 MessageParser parser; bool bool_msgset = parser.SetMsg(udata, length); - //Ʒ¼ + //云服务登录报文 if (udata[0] == 0xEB && udata[1] == 0x90 && udata[2] == 0xEB && udata[3] == 0x90) { - //ͨѶ״̬ + //通讯状态报文 if (udata[8] == 0x01) { std::cout << "cloud login: " << mac << " state: " << static_cast(udata[16]) << static_cast(udata[17]) << static_cast(udata[18]) << static_cast(udata[19]) << std::endl; if (udata[19] == 0x10) { std::cout << "cloud login: " << mac << " state: success!" << std::endl; - //װõ¼ɹ - ClientManager::instance().set_cloud_status(id, 1); //ǰõ¼״̬Ϊѵ¼ - ClientManager::instance().read_devversion_action_to_device(id);//ȡװð汾Ϣװõ¼ִһΣǰȡ汾Ϣȷ϶ʱĽṹ + //装置登录成功 + ClientManager::instance().set_cloud_status(id, 1); //设置了云前置登录状态为已登录 + ClientManager::instance().read_devversion_action_to_device(id);//主动触发,读取装置版本配置信息,仅在装置登录后执行一次,当前获取版本信息确认对时报文结构。 - //ClientManager::instance().get_dev_status(id);//豸ж ture false - //ClientManager::instance().set_real_state_count("D002", 1,1);//¼ʵʱ - //ClientManager::instance().add_file_menu_action_to_device("D002","/etc");//ļĿ¼ȡ - //ClientManager::instance().add_file_download_action_to_device("D002", "/etc/NPQS570_VX_ZJ_2(V103).icd");//ļ - //ClientManager::instance().get_fixedvalue_action_to_device(id,1);//Իȡװò㶨ֵ - //ClientManager::instance().get_fixedvaluedes_action_to_device(id);//Իȡװöֵ - //ClientManager::instance().set_fixedvalue_action_to_device();//װ޸ĶֵԣҪⲿṩ - //ClientManager::instance().get_interfixedvalue_action_to_device(id);//װûȡڲֵ - //ClientManager::instance().get_fixedvalucontrolword_action_to_device(id,1);//ȡ 1-ڲֵ 2- - //ClientManager::instance().set_interfixedvalue_action_to_device();װ޸ڲֵԣⲿṩ - //ClientManager::instance().read_runninginformation_action_to_device(id);//ȡװϢ + //ClientManager::instance().get_dev_status(id);//设备在线情况判断 ture在线 false离线 + //ClientManager::instance().set_real_state_count("D002", 1,1);//登录后测试实时 + //ClientManager::instance().add_file_menu_action_to_device("D002","/etc");//测试文件目录读取 + //ClientManager::instance().add_file_download_action_to_device("D002", "/etc/NPQS570_VX_ZJ_2(V103).icd");//测试文件下载 + //ClientManager::instance().get_fixedvalue_action_to_device(id,1);//测试获取装置测点定值数据 + //ClientManager::instance().get_fixedvaluedes_action_to_device(id);//测试获取装置定值描述 + //ClientManager::instance().set_fixedvalue_action_to_device();//装置修改定值测试(参数需要外部提供) + //ClientManager::instance().get_interfixedvalue_action_to_device(id);//装置获取内部定值 + //ClientManager::instance().get_fixedvalucontrolword_action_to_device(id,1);//获取 1-内部定值描述 或者 2-控制字描述 + //ClientManager::instance().set_interfixedvalue_action_to_device();装置修改内部定值测试(参数由外部提供) + //ClientManager::instance().read_runninginformation_action_to_device(id);//主动触发,读取装置运行信息 - //// ʼʱ: 202591 10:30:45 + //// 设置起始时间: 2025年9月1日 10:30:45 //std::tm start_time = {}; - //start_time.tm_year = 2025 - 1900; // ݴ1900ʼ - //start_time.tm_mon = 8 - 1; // ·ݴ0ʼ (0=һ) + //start_time.tm_year = 2025 - 1900; // 年份从1900开始计算 + //start_time.tm_mon = 8 - 1; // 月份从0开始 (0=一月) //start_time.tm_mday = 20; //start_time.tm_hour = 1; //start_time.tm_min = 1; //start_time.tm_sec = 1; - //// ýʱ: 202594 12:15:30 + //// 设置结束时间: 2025年9月4日 12:15:30 //std::tm end_time = {}; //end_time.tm_year = 2025 - 1900; //end_time.tm_mon = 8 - 1; @@ -121,48 +122,140 @@ void process_received_message(string mac, string id,const char* data, size_t len //end_time.tm_min = 1; //end_time.tm_sec = 1; //ClientManager::instance().read_eventlog_action_to_device(id, start_time, end_time,2,1); + + //DIY_ERRORLOG_CODE("111", 0, static_cast(LogCode::LOG_CODE_OTHER), "【ERROR】测试告警发送 前置"); + //DIY_ERRORLOG_CODE(id, 1, static_cast(LogCode::LOG_CODE_OTHER), "【ERROR】测试告警发送 设备"); + /*std::string mpid; + get_monitor_id_by_dev_and_seq(id, 1, mpid); + if (!mpid.empty()) { + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_OTHER), "【ERROR】测试告警发送 测点"); + }*/ + + + } if (udata[19] == 0x00) { std::cout << "cloud login: " << mac << " state: fail!" << std::endl; - //װõ¼ʧ رտͻ ȴ20µ¼ + //装置登录失败 关闭客户端连接 等待20秒重新登录 ClientManager::instance().restart_device(id); } } else { std::cout << "cloud login: " << mac << " state: error!"<< std::endl; - //װõ¼ʧ رտͻ ȴ20µ¼ + //装置登录失败 关闭客户端连接 等待20秒重新登录 ClientManager::instance().restart_device(id); } - //¼ĴϣǰĴ߼ + //登录报文处理完毕,当前报文处理逻辑结束并返回 return; } - //װͱ ̬¼/̬ļ + //装置主动上送报文 暂态事件报文/暂态波形文件报文 if (udata[8] == static_cast(MsgResponseType::Response_Event)) { - //͵̬¼ + //处理主动上送的暂态事件报文 NewTaglogbuffer event = NewTaglogbuffer::createFromData(parser.RecvData.data(), parser.RecvData.size()); - // ȡ - std::string strScale;//ѹȼ - int nPTType;//߷ʽ + //获取测点id + std::string mpid; + get_monitor_id_by_dev_and_seq(id, 1, mpid); + + //判断事件逻辑是否需要上送告警 + if (!mpid.empty()) { + switch (event.head.LogCode) + { + case 2: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】系统事件:突变量启动录波(NPQS-570特殊功能)"); + break; + case 21: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:装置掉电"); + break; + case 22: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:装置上电"); + break; + case 23: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:时钟出错"); + break; + case 24: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:AD采集出错"); + break; + case 25: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:主存储器出错"); + break; + case 26: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】硬件告警事件:内存出错"); + break; + case 31: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:程序升级成功"); + break; + case 32: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:程序升级失败"); + break; + case 33: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:程序文件出错"); + break; + case 34: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:ICD文件解析出错"); + break; + case 35: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:定值出错"); + break; + case 36: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】运行告警事件:Pqdif配置模板出错"); + break; + case 51: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:失压事件"); + break; + case 52: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:欠压事件"); + break; + case 53: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:过压事件"); + break; + case 54: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:断相事件"); + break; + case 55: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:电压不平衡事件"); + break; + case 56: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:电流不平衡事件"); + break; + case 57: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:失流事件"); + break; + case 58: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:过流事件"); + break; + case 59: + DIY_ERRORLOG_CODE(mpid, 2, static_cast(LogCode::LOG_CODE_DEV_ALARM), "【ERROR】电度告警事件:断流事件"); + break; + + default: + break; + } + } + + + // 获取测点参数 + std::string strScale;//电压等级 + int nPTType;//接线方式 float fPT = 1.0f; float fCT = 1.0f; if (ClientManager::instance().get_point_scale_and_pttype( - id, // ʹid - event.head.name, // ӱнIJ + id, // 或使用id + event.head.name, // 从报文中解析出的测点序号 strScale, nPTType) && ClientManager::instance().get_pt_ct_ratio(id, event.head.name, fPT, fCT)) { - // ʹûȡIJ¼¼ + // 使用获取的参数解析事件记录 QVVRRecord record = DynamicLog_GetQVVRRecordFromLogBuffer( strScale, nPTType, fPT, event); - // ʹü¼ݣʾӡ̨ - std::cout << "¼: " << record.nType - << ", ʱ: " << record.fPersisstime << "s" - << ", ֵ: " << record.fMagntitude << " pu" - << ", ʱ: " << record.triggerTimeMs << "ms" << std::endl; + // 使用记录数据(示例:打印到控制台) + std::cout << "事件类型: " << record.nType + << ", 持续时间: " << record.fPersisstime << "s" + << ", 特征幅值: " << record.fMagntitude << " pu" + << ", 时间戳: " << record.triggerTimeMs << "ms" << std::endl; - //lnk20250805 ¼ȼ¼¼ļϴٸļ + //lnk20250805 事件上送先记录,录波文件上传结束后再更新文件 append_qvvr_event(id,event.head.name, record.nType,record.fPersisstime,record.fMagntitude,record.triggerTimeMs,record.phase); transfer_json_qvvr_data(id,event.head.name, @@ -171,36 +264,36 @@ void process_received_message(string mac, string id,const char* data, size_t len } else { - // ȡʧܵ + // 处理获取失败的情况 std::cerr << "Failed to get point parameters for: " << mac << std::endl; } - //ͱĺֱ˳ҪװӦ + //处理完毕主动上送报文后直接退出,不要干扰装置正常应答 return; } else if (udata[8] == static_cast(MsgResponseType::Response_ActiveSOEInfo)) { - //͵IJļϢ - unsigned char file_type = udata[12];//¼ļ cfg dat hdr 1-3 - unsigned char line_id = udata[13];//¼ 1-6 - const uint8_t* data_ptr = parser.RecvData.data() + 2;//ȥǰλ + //处理主动上送的波形文件信息报文 + unsigned char file_type = udata[12];//录波文件类型数 cfg dat hdr 1-3 + unsigned char line_id = udata[13];//录波测点 1-6 + const uint8_t* data_ptr = parser.RecvData.data() + 2;//数据体去除前两位 size_t data_size = parser.RecvData.size() - 2; - // ֱӹַ⿽ + // 直接构造字符串(避免额外拷贝) std::string tempfilename( reinterpret_cast(data_ptr), data_size ); - // ========== ֹ ========== - // ַеĵһַֹ + // ========== 新增:处理终止符 ========== + // 查找字符串中的第一个空字符或其他终止符 size_t terminator_pos = tempfilename.find_first_of("\0\r\n", 0, 3); if (terminator_pos != std::string::npos) { - // ҵֹضַ + // 如果找到终止符,截断字符串 tempfilename.resize(terminator_pos); std::cout << "Found terminator at position: " << terminator_pos << ", truncated filename to: " << tempfilename << std::endl; } - // ========== ļ·߼ ========== - // 1. ָԭʼļͺ׺ + // ========== 新增文件路径处理逻辑 ========== + // 1. 分割原始文件名和后缀 size_t dotPos = tempfilename.find_last_of('.'); std::string baseName, originalExt; if (dotPos != std::string::npos) { @@ -212,7 +305,7 @@ void process_received_message(string mac, string id,const char* data, size_t len originalExt = ""; } - // 2. ȷСд + // 2. 确定大小写风格 bool isUppercase = false; if (!originalExt.empty()) { isUppercase = true; @@ -224,17 +317,17 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - // 3. Ҫĺ׺б + // 3. 生成需要的后缀列表 std::vector requiredExts; - if (file_type == 3) { // Ҫļ + if (file_type == 3) { // 需要三个文件 requiredExts = { ".cfg", ".dat", ".hdr" }; } - else { // ĬҪļ + else { // 默认需要两个文件 requiredExts = { ".cfg", ".dat" }; //requiredExts = { ".dat" }; } - // 4. ׺Сд + // 4. 调整后缀大小写 if (isUppercase) { for (auto& ext : requiredExts) { for (char& c : ext) { @@ -243,28 +336,28 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - // 5. ·б + // 5. 构建完整路径列表 std::vector fullFilenames; for (const auto& ext : requiredExts) { fullFilenames.push_back(baseName + ext); } - // 6. ӡʵʹпҪ滻Ĵӡ߼ + // 6. 打印结果(实际使用中可能需要替换这里的打印逻辑) std::cout << "Generated filenames: "; for (const auto& name : fullFilenames) { std::cout << name << " "; } std::cout << std::endl; - //lnk20250805¼ļĿ¼ӿ + //lnk20250805录波文件目录接口 assign_qvvr_file_list(id, line_id, fullFilenames); - // ========== Ϊÿļ ========== + // ========== 新增:为每个文件生成下载请求 ========== for (const auto& filename : fullFilenames) { - // (֡Ź̶Ϊ1ʼļ) + // 生成下载请求报文 (帧序号固定为1,代表开始新文件的下载) auto downloadMsg = generate_downloadfile_message(1, filename); - // ضӵ豸 + // 将下载动作添加到设备队列 ClientManager::instance().add_action_to_device( id, DeviceState::READING_EVENTFILE, @@ -274,142 +367,142 @@ void process_received_message(string mac, string id,const char* data, size_t len std::cout << "Added download request for: " << filename << std::endl; } - //շ߼ǰװÿִкǰװô״ֱ̬˳ҪװúִУ - DeviceState currentState = DeviceState::IDLE;//ȡǰװõ״̬ + //最后报文收发处理逻辑(如果当前装置空闲则尝试执行后续动作)(如果当前装置存在其他状态则直接退出,不要干扰装置后续执行) + DeviceState currentState = DeviceState::IDLE;//获取当前装置的状态 if (!ClientManager::instance().get_device_state(id, currentState)) { std::cerr << "Failed to get device state for: " << id << std::endl; return; } switch (currentState) { case DeviceState::IDLE: - //ǰװÿУִк + //当前装置空闲中,可以执行后续动作 ClientManager::instance().post_message_processing(id); break; default: - //ǿе״ֱ̬˳ɣȴϺٳԻȡļ + //非空闲的其他状态直接退出即可,等待后续处理完毕后再尝试获取波形文件 break; } - //ͱĺֱ˳ҪװӦ + //处理完毕主动上送报文后直接退出,不要干扰装置正常应答 return; } - //ͨѶ + //常规通讯报文 { - DeviceState currentState = DeviceState::IDLE;//ȡǰװõ״̬ + DeviceState currentState = DeviceState::IDLE;//获取当前装置的状态 if (!ClientManager::instance().get_device_state(id, currentState)) { std::cerr << "Failed to get device state for: " << id << std::endl; return; } - // װ״̬ + // 根据装置状态处理报文 switch (currentState) { case DeviceState::IDLE: - // ״̬յģϱ + // 空闲状态下收到报文,可能是主动上报数据 std::cout << "IDLE state: Received active report from " << mac << std::endl; - // Ӵϱݵ߼ + // 这里可以添加处理主动上报数据的逻辑 break; case DeviceState::READING_STATS: - // ȡͳ״̬ + // 读取统计数据状态 if (udata[8] == static_cast(MsgResponseType::Response_Stat)) { - // һգҪȴбȫװӦ һ֡1K ֱݴ - //ǰ֡δȫֱ˳Ϣȴ֡ + // 一发多收,需要在这里等待所有报文收全再组装相应数据 一帧1K 直到所有数据传送完毕 + //当前帧未收全,直接退出消息处理,等待后续帧 std::cout << "mac: " << mac << " count" << static_cast(udata[10]) << std::endl; - // ֡Ϣ (ʵЭ) - int current_packet = static_cast(udata[10]); // ǰ֡ - int total_packets = Stat_PacketNum; // ֡ + // 解析帧信息 (根据实际协议调整) + int current_packet = static_cast(udata[10]); // 当前帧序号 + int total_packets = Stat_PacketNum; // 总帧数 std::vector packet_data(udata, udata + length); bool complete = ClientManager::instance().add_stat_packet_to_device( id, packet_data, current_packet, total_packets ); - //жǷȫ + //判断是否收全 if (complete) { - // 1. ȡջݰ + // 1. 获取并清空缓存数据包 auto packets = ClientManager::instance().get_and_clear_stat_packets(id); - // 2. ֡ + // 2. 按帧序号排序 std::sort(packets.begin(), packets.end(), [](const ClientContext::StatPacket& a, const ClientContext::StatPacket& b) { return a.packet_index < b.packet_index; }); - // 3. ÿ֡ݲȡ + // 3. 解析每帧数据并提取数据体 std::vector full_data; MessageParser parser; for (const auto& packet : packets) { - // ֡ + // 解析单帧报文 if (!parser.SetMsg(packet.data.data(), packet.data.size())) { std::cerr << "Failed to parse packet " << packet.packet_index << " for device " << id << std::endl; continue; } - // ӵ + // 将数据体添加到完整序列 full_data.insert(full_data.end(), parser.RecvData.begin(), parser.RecvData.end()); } - // 4. װ tagPqData + // 4. 组装 tagPqData 对象 tagPqData pq_data; if (!pq_data.SetStructBuf(full_data.data(), full_data.size())) { std::cerr << "Failed to assemble tagPqData for device " << id << std::endl; } else { - // ɹװʹ pq_data + // 成功组装,可以在这里使用 pq_data 对象 std::cout << "Successfully assembled tagPqData for device: " << id << std::endl; float fPT = 1.0f; float fCT = 1.0f; if (ClientManager::instance().get_pt_ct_ratio(id, pq_data.name, fPT, fCT)) { - // ʹûȡıֵת + // 使用获取的变比值进行数据转换 tagPqData_Float float_data; float_data.SetFloatValue(pq_data, fPT, fCT); float_data.name = pq_data.name; float_data.Data_Type = pq_data.Data_Type; - // ӵ - // ӵ沢Ƿȫ + // 将浮点数据添加到缓存 + // 添加到缓存并检查是否收全 bool complete = ClientManager::instance().add_float_data_to_device( id, pq_data.name, pq_data.Data_Type, float_data); if (complete) { - // ȫȡ + // 如果收全,立即取出处理 std::array all_data = ClientManager::instance().get_and_clear_float_data(id, pq_data.name); if (!all_data.empty()) { - // 4ݴ߼ + //单个测点 4组数据处理逻辑 tagPqData_Float max_data = all_data[0]; tagPqData_Float min_data = all_data[1]; tagPqData_Float avg_data = all_data[2]; tagPqData_Float cp95_data = all_data[3]; - std::string strScale;//ѹȼ - int nPTType = 0;//߷ʽ + std::string strScale;//电压等级 + int nPTType = 0;//接线方式 ClientManager::instance().get_point_scale_and_pttype( - id, // ʹid - pq_data.name, // ӱнIJ + id, // 或使用id + pq_data.name, // 从报文中解析出的测点序号 strScale, nPTType); - // תΪBase64ַ + // 转换为Base64字符串 std::string max_base64Str = max_data.ConvertToBase64(nPTType); std::string min_base64Str = min_data.ConvertToBase64(nPTType); std::string avg_base64Str = avg_data.ConvertToBase64(nPTType); std::string cp95_base64Str = cp95_data.ConvertToBase64(nPTType); //std::cout << "New star base64Str0:" << max_base64Str << std::endl; //std::cout << "New del base64Str1:" << avg_data.ConvertToBase64(1) << std::endl; - //lnk20250708ʹýӿڷ + //lnk20250708使用接口发送 time_t data_time = ConvertToTimestamp(avg_data.time); std::vector arr; - arr.push_back({1, // -1-ޣ 0-Rt,1-Max,2-Min,3-Avg,4-Cp95 - data_time, //תʱ䣬ʱ꣬1970룬Ч롰-1 - 0, //ʱ꣬΢ӣЧ롰-1 - 0, //ݱʶ1-ʶ쳣 + arr.push_back({1, //数据属性 -1-无, 0-“Rt”,1-“Max”,2-“Min”,3-“Avg”,4-“Cp95” + data_time, //数据转换出来的时间,数据时标,相对1970年的秒,无效填入“-1” + 0, //数据时标,微秒钟,无效填入“-1” + 0, //数据标识,1-标识数据异常 max_base64Str}); arr.push_back({2, data_time, 0, 0, min_base64Str}); arr.push_back({3, data_time, 0, 0, avg_base64Str}); @@ -417,44 +510,44 @@ void process_received_message(string mac, string id,const char* data, size_t len std::string js = generate_json( normalize_mac(mac), - -1, //ӦıĶյԴIDӦӦ롰-1 - 1, //豸ΨһʶLdid0Ndid,id - 1, //Ĵȼ1 I/Ӧ 2 II/Ӧ 3 ͨ/Ӧ 4 㲥 - 0x1302, //豸͵ - avg_data.name, //߼豸ID0-߼豸-1 - 0x04, //͹̶Ϊ - 2, //ԣޡ0ʵʱ1ͳơ2 - 1, //ݼţݼʽͣ-1 - arr // + -1, //需应答的报文订阅者收到后需以此ID应答,无需应答填入“-1” + 1, //设备唯一标识Ldid,填入0代表Ndid,后续根据商议决定填id还是数字 + 1, //报文处理的优先级:1 I类紧急请求/响应 2 II类紧急请求/响应 3 普通请求/响应 4 广播报文 + 0x1302, //设备数据主动上送的数据类型 + avg_data.name, //逻辑子设备ID,0-逻辑设备本身,无填-1 + 0x04, //数据类型固定为电能质量 + 2, //数据属性:无“0”、实时“1”、统计“2”等 + 1, //数据集序号(以数据集方式上送),无填-1 + arr //数据数组 ); //std::cout << js << std::endl; - //// ļģʽ - //std::ofstream outFile("json.txt"); // ȼ std::ofstream outFile(filePath, std::ios::out); + //// 创建输出流并打开文件(覆盖模式) + //std::ofstream outFile("json.txt"); // 等价于 std::ofstream outFile(filePath, std::ios::out); - //if (outFile.is_open()) { // ļǷɹ - // outFile << js; // дַ - // outFile.close(); // رļ - // // ɹʾʵӦнʹ־ + //if (outFile.is_open()) { // 检查文件是否成功打开 + // outFile << js; // 写入字符串 + // outFile.close(); // 关闭文件 + // // 成功提示(实际应用中建议使用日志) //} //else { - // // ļʧܣ·ڣ + // // 错误处理:文件打开失败(如路径不存在) //} queue_data_t data; - data.monitor_no = avg_data.name; // - data.strTopic = TOPIC_STAT;//ͳtopic + data.monitor_no = avg_data.name; //监测点序号 + data.strTopic = TOPIC_STAT;//统计topic data.strText = js; - data.mp_id = ""; //idʱҪ - data.tag = G_ROCKETMQ_TAG; //ͳtag - data.key = G_ROCKETMQ_KEY; //ͳkey + data.mp_id = ""; //监测点id,暂时不需要 + data.tag = G_ROCKETMQ_TAG; //统计tag + data.key = G_ROCKETMQ_KEY; //统计key std::lock_guard lock(queue_data_list_mutex); queue_data_list.push_back(data); std::cout << "Successfully assembled tagPqData for line: " << avg_data.name << std::endl; - // + // 输出结果 //std::cout << "Base64 Encoded Data (" << max_data.CalculateFloatCount() // << " floats): " << base64Str << std::endl; } @@ -462,81 +555,81 @@ void process_received_message(string mac, string id,const char* data, size_t len } else { - // ȡֵʧܵ + // 处理获取变比值失败的情况 std::cerr << "Failed to get PT/CT ratio for device: " << mac << " lineno: " << pq_data.name << std::endl; } } - //װϣ޸Ϊ״̬ȴһ + //数据组装完毕,修改为空闲状态等待下一项工作 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - //δȫֱӽȴӦ + //未收全则直接结束处理,等待后续报文应答 return; } } else { - // װô쳣 - // ͳݴ󣬵Ϊ״̬һ + // 装置答非所问异常 + // 接收统计数据错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_STATS_TIME: - // ȡͳʱ״̬ + // 读取统计时间状态 if (udata[8] == static_cast(MsgResponseType::Response_StatTime)) { - std::vector points;//װòϢ + std::vector points;//装置测点信息 if (ClientManager::instance().get_device_points(mac, points)) { - // ɹȡϢ - // װõʱ + // 成功获取测点信息 + // 处理接收装置的时标 tagTime t3; t3.SetStructBuf(parser.RecvData.data(), parser.RecvData.size()); - int first = 0;//һα + int first = 0;//第一次标记 for (const auto& point : points) { - for (ushort i = 0; i < 4; i++)//ÿҪٻСƽ95ֵ + for (ushort i = 0; i < 4; i++)//每个测点需要单独召唤最大,最小,平均,95概率值 { - auto sendbuff = generate_statequerystat_message(t3, point.nCpuNo, i);//װѯͳݱ + auto sendbuff = generate_statequerystat_message(t3, point.nCpuNo, i);//组装询问统计数据报文 if (first == 0) { - //״γװ ֱӽǰ״̬ ȴ + //首次尝试组装报文 直接将当前状态调整 并等待最后启动发送 first++; ClientManager::instance().change_device_state(id, DeviceState::READING_STATS, sendbuff); } else { - //״ν룬еȴ + //非首次进入,将动作传入队列等待 ClientManager::instance().add_action_to_device(id, DeviceState::READING_STATS, sendbuff); } } } } else { - // δҵװ쳣 - // ͳʱ󣬵Ϊ״̬һ + // 未找到装置下属测点异常 + // 接收统计数据时间错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } else { - // װô쳣 - // ͳʱ󣬵Ϊ״̬һ + // 装置答非所问异常 + // 接收统计数据时间错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_REALSTAT: - //ȡʵʱ״̬ + //读取实时数据状态 if (udata[8] == static_cast(MsgResponseType::Response_New_3S)) { unsigned char packet_type = udata[13]; - //ȡ + //取监测点号 unsigned char cid = udata[12]; - // ӵ + // 将数据添加到缓存 const uint8_t* data_ptr = parser.RecvData.data() + 4; size_t data_size = parser.RecvData.size() - 4; ClientManager::instance().add_realtime_packet_to_device( id, packet_type, data_ptr, data_size ); - // һһ + // 如果不是最后一个包,请求下一个包 if (packet_type != 0x06) { unsigned char next_packet_type = packet_type + 1; auto sendbuff = generate_realstat_message( @@ -549,10 +642,10 @@ void process_received_message(string mac, string id,const char* data, size_t len ); } else { - // ȡջ + // 获取并清空缓存 auto packets = ClientManager::instance().get_and_clear_realtime_packets(id); - // 01-06 + // 按包类型排序(01-06) std::sort(packets.begin(), packets.end(), [](const ClientContext::RealtimePacket& a, const ClientContext::RealtimePacket& b) { @@ -560,7 +653,7 @@ void process_received_message(string mac, string id,const char* data, size_t len }); RealtagPqDate_float realdata; - // ˳ÿ + // 按顺序解析每个包 for (const auto& packet : packets) { switch (packet.packet_type) { case 0x01: @@ -584,124 +677,124 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - std::string strScale;//ѹȼ - int nPTType = 0;//߷ʽ + std::string strScale;//电压等级 + int nPTType = 0;//接线方式 ClientManager::instance().get_point_scale_and_pttype( - id, // ʹid - static_cast(udata[12]), // ӱнIJ + id, // 或使用id + static_cast(udata[12]), // 从报文中解析出的测点序号 strScale, nPTType); std::string base64 = realdata.ConvertToBase64(nPTType); //std::cout << base64 << std::endl; - //lnkʵʱʹýӿڷ20250711 + //lnk实时数据使用接口发送20250711 time_t data_time = ConvertToTimestamp(realdata.time); std::vector arr; - arr.push_back({1, // -1-ޣ 0-Rt,1-Max,2-Min,3-Avg,4-Cp95 - data_time, //תʱ䣬ʱ꣬1970룬Ч롰-1 - 0, //ʱ꣬΢ӣЧ롰-1 - 0, //ݱʶ1-ʶ쳣 + arr.push_back({1, //数据属性 -1-无, 0-“Rt”,1-“Max”,2-“Min”,3-“Avg”,4-“Cp95” + data_time, //数据转换出来的时间,数据时标,相对1970年的秒,无效填入“-1” + 0, //数据时标,微秒钟,无效填入“-1” + 0, //数据标识,1-标识数据异常 base64}); std::string js = generate_json( normalize_mac(mac), - -1, //ӦıĶյԴIDӦӦ롰-1 - 1, //豸ΨһʶLdid0Ndid,id - 1, //Ĵȼ1 I/Ӧ 2 II/Ӧ 3 ͨ/Ӧ 4 㲥 - 0x1302, //豸͵ - cid, //߼豸ID0-߼豸-1 - 0x04, //͹̶Ϊ - 1, //ԣޡ0ʵʱ1ͳơ2 - 2, //ݼţݼʽͣ-1 - arr // + -1, //需应答的报文订阅者收到后需以此ID应答,无需应答填入“-1” + 1, //设备唯一标识Ldid,填入0代表Ndid,后续根据商议决定填id还是数字 + 1, //报文处理的优先级:1 I类紧急请求/响应 2 II类紧急请求/响应 3 普通请求/响应 4 广播报文 + 0x1302, //设备数据主动上送的数据类型 + cid, //逻辑子设备ID,0-逻辑设备本身,无填-1 + 0x04, //数据类型固定为电能质量数据 + 1, //数据属性:无“0”、实时“1”、统计“2”等 + 2, //数据集序号(以数据集方式上送),无填-1 + arr //数据数组 ); //std::cout << js << std::en queue_data_t data; - data.monitor_no = 1; //͵ʵʱûвţͳһ1 - data.strTopic = TOPIC_RTDATA; //ʵʱtopic + data.monitor_no = 1; //上送的实时数据没有测点序号,统一填1 + data.strTopic = TOPIC_RTDATA; //实时topic data.strText = js; - data.mp_id = ""; //idʱҪ - data.tag = G_RT_TAG; //ʵʱtag - data.key = G_RT_KEY; //ʵʱkey + data.mp_id = ""; //监测点id,暂时不需要 + data.tag = G_RT_TAG; //实时tag + data.key = G_RT_KEY; //实时key std::lock_guard lock(queue_data_list_mutex); queue_data_list.push_back(data); - // ɺ״̬ + // 处理完成后重置状态 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id,0, static_cast(DeviceState::READING_REALSTAT)); - // ʵʱݴ󣬵Ϊ״̬һ + // 接收实时数据错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_EVENTFILE: - // ̬ļ + // 暂态波形文件下载 if (udata[8] == static_cast(MsgResponseType::Response_File_Download)) { - // ȡǰ֡ţ12-15ֽڣ + // 提取当前帧序号(12-15字节,大端序) int current_frame = (static_cast(udata[12]) << 24) | (static_cast(udata[13]) << 16) | (static_cast(udata[14]) << 8) | static_cast(udata[15]); - // ȡ֡16-19ֽڣ + // 提取总帧数(16-19字节,大端序) int total_frames = (static_cast(udata[16]) << 24) | (static_cast(udata[17]) << 16) | (static_cast(udata[18]) << 8) | static_cast(udata[19]); //std::cout << "eventfile frames: " << current_frame << "/" << total_frames << std::endl; - // ӵ ȥǰ14λ ߼Ժд + // 将数据添加到缓存 去除数据体前14位 (逻辑稍后编写) const uint8_t* data_ptr = parser.RecvData.data() + 14; size_t data_size = parser.RecvData.size() - 14; - // ǵһ֡¼ļ + // 如果是第一帧,记录文件名 if (current_frame == 1) { ClientManager::DownloadInfo info; if (ClientManager::instance().parse_download_packet(id, info)) { ClientManager::instance().update_current_filename(id, info.filename); } } - // ȡļ + // 获取文件名 std::string filename = ClientManager::instance().get_current_filename(id); - // ӵ + // 添加到缓存 ClientManager::instance().add_file_packet_to_device(id, current_frame, data_ptr, data_size); //std::cout << "fileinfo: " << info.filename << "/" << info.current_frame << std::endl; - //жǷȫδȫͱģȫȡлװļأϢ + //判断是否收全,未收全则继续发送报文,收全则取出所有缓存组装文件并保存至本地,推送消息 if (current_frame < total_frames) { - // δȫ֡Ų״̬,ȴԶ޸ĵ± + // 未收全,更新帧序号并保持状态,等待后续自动发送已修改的新报文 int nextframe = current_frame + 1; auto downloadMsg = generate_downloadfile_message(nextframe, filename); ClientManager::instance().change_device_state(id, DeviceState::READING_EVENTFILE, downloadMsg); } else { - // ȫڴ˴ļ + // 已收全,在此处处理文件 std::cout << "mac: " << mac << " fileinfo: " << filename < file_data; for (const auto& packet : packets) { file_data.insert(file_data.end(), packet.begin(), packet.end()); } - // ļ - std::string wavefile = "wave"; // ʹMACַΪĿ¼ - // Ŀ¼ڣ + // 保存文件 + std::string wavefile = "wave"; // 使用MAC地址作为目录名 + // 创建目录(如果不存在) if (mkdir(wavefile.c_str(), 0777) != 0 && errno != EEXIST) { std::cerr << "Failed to create directory: " << wavefile << std::endl; } - // ļ - std::string mac_dir = wavefile + "/" + mac; // ʹMACַΪĿ¼ - // Ŀ¼ڣ + // 保存文件 + std::string mac_dir = wavefile + "/" + mac; // 使用MAC地址作为目录名 + // 创建目录(如果不存在) if (mkdir(mac_dir.c_str(), 0777) != 0 && errno != EEXIST) { std::cerr << "Failed to create directory: " << mac_dir << std::endl; } @@ -715,137 +808,137 @@ void process_received_message(string mac, string id,const char* data, size_t len file_data.size()); std::cout << "File saved: " << file_path << std::endl; - //lnk20250805ļɹ¼ļͽӿ + //lnk20250805文件保存成功调用录波文件上送接口 update_qvvr_file_download(file_path, id); } else { std::cerr << "Failed to save file: " << file_path << ", Error: " << strerror(errno) << std::endl; - // ļʧܣ֪ͨƶ + // 文件保存失败,通知云端 /*on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::READING_EVENTFILE));*/ } - //ǰļϣΪдһļȴأһѾȴеȺˣɿ״ֱ̬ӾͻῪʼļع + //当前文件下载完毕,调整为空闲处理下一项工作(如果这里后续有新文件等待下载,一般已经存入等待队列等候处理了,调成空闲状态后直接就会开始新文件的下载工作) ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } else { - // װô쳣 + // 装置答非所问异常 //on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_EVENTFILE)); - // ղļݴ󣬵Ϊ״̬һ + // 接收波形文件数据错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_FILEMENU: - //ȡļĿ¼ + //读取文件目录 if (udata[8] == static_cast(MsgResponseType::Response_FileDir)) { - // ṹС + // 计算结构体大小 const size_t struct_size = sizeof(tag_dir_info); const uint8_t* data_ptr = parser.RecvData.data(); size_t data_size = parser.RecvData.size(); std::vector FileList; - // յ + // 遍历接收到的数据 for (size_t i = 0; i < data_size; i += struct_size) { if (i + struct_size > data_size) break; tag_dir_info dir_info; memcpy(&dir_info, data_ptr + i, struct_size); - // ֽת ( -> С) + // 字节序转换 (大端 -> 小端) dir_info.flag = ntohl(dir_info.flag); dir_info.size = ntohl(dir_info.size); std::string gbk_name(dir_info.name, strnlen(dir_info.name, sizeof(dir_info.name))); - // ӡļ + // 打印文件名 std::cout << "file name:" << gbk_name << std::endl; - // ӵļб + // 添加到文件列表 FileList.push_back(dir_info); } - // ӷļб߼ + // 这里可以添加发送文件列表的逻辑 //send_file_list(id,FileList);//lnk20250813 filemenu_cache_put(id,FileList); - // ɺ״̬ + // 处理完成后重置状态 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_FILEMENU)); - // Ŀ¼ݴ󣬵Ϊ״̬һ + // 接收目录数据错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_FILEDATA: - //ļ ̬ļعͬһ + //下载文件数据 和暂态文件下载共用同一功能码 if (udata[8] == static_cast(MsgResponseType::Response_File_Download)) { - // ȡǰ֡ţ12-15ֽڣ + // 提取当前帧序号(12-15字节,大端序) int current_frame = (static_cast(udata[12]) << 24) | (static_cast(udata[13]) << 16) | (static_cast(udata[14]) << 8) | static_cast(udata[15]); - // ȡ֡16-19ֽڣ + // 提取总帧数(16-19字节,大端序) int total_frames = (static_cast(udata[16]) << 24) | (static_cast(udata[17]) << 16) | (static_cast(udata[18]) << 8) | static_cast(udata[19]); - //ȡ + //提取数据 const uint8_t* data_ptr = parser.RecvData.data() + 14; size_t data_size = parser.RecvData.size() - 14; - // ǵһ֡¼ļ + // 如果是第一帧,记录文件名 if (current_frame == 1) { ClientManager::DownloadInfo info; if (ClientManager::instance().parse_download_packet(id, info)) { ClientManager::instance().update_current_filename(id, info.filename); } } - // ȡļ + // 获取文件名 std::string filename = ClientManager::instance().get_current_filename(id); - // ӵ + // 添加到缓存 ClientManager::instance().add_file_packet_to_device(id, current_frame, data_ptr, data_size); - //жǷȫδȫͱģȫȡлװļأϢ + //判断是否收全,未收全则继续发送报文,收全则取出所有缓存组装文件并保存至本地,推送消息 if (current_frame < total_frames) { - // δȫ֡Ų״̬,ȴԶ޸ĵ± + // 未收全,更新帧序号并保持状态,等待后续自动发送已修改的新报文 int nextframe = current_frame + 1; auto downloadMsg = generate_downloadfile_message(nextframe, filename); ClientManager::instance().change_device_state(id, DeviceState::READING_FILEDATA, downloadMsg); } else { - // ȫڴ˴ļ + // 已收全,在此处处理文件 std::cout << "mac: " << mac << " fileinfo: " << filename << std::endl; - // ȡезƬ + // 获取缓存中的所有分片 auto packets = ClientManager::instance().get_and_clear_file_packets(id); - // ϲļ + // 合并文件内容 std::vector file_data; for (const auto& packet : packets) { file_data.insert(file_data.end(), packet.begin(), packet.end()); } - // ļ - std::string wavefile = "download"; // ʹMACַΪĿ¼ - // Ŀ¼ڣ + // 保存文件 + std::string wavefile = "download"; // 使用MAC地址作为目录名 + // 创建目录(如果不存在) if (mkdir(wavefile.c_str(), 0777) != 0 && errno != EEXIST) { std::cerr << "Failed to create directory: " << wavefile << std::endl; } - // ļ - std::string mac_dir = wavefile + "/" + mac; // ʹMACַΪĿ¼ - // Ŀ¼ڣ + // 保存文件 + std::string mac_dir = wavefile + "/" + mac; // 使用MAC地址作为目录名 + // 创建目录(如果不存在) if (mkdir(mac_dir.c_str(), 0777) != 0 && errno != EEXIST) { std::cerr << "Failed to create directory: " << mac_dir << std::endl; } @@ -859,12 +952,12 @@ void process_received_message(string mac, string id,const char* data, size_t len file_data.size()); std::cout << "File saved: " << file_path << std::endl; - //ʹýӿļlnk20250826 + //使用接口上送文件lnk20250826 std::string filename; - SendFileWeb(WEB_FILEUPLOAD, file_path, file_path, filename);//DzļأغҲֱϴϴɹ²״̬ + SendFileWeb(WEB_FILEUPLOAD, file_path, file_path, filename);//如果是补招文件的下载,下载后也是直接上传,上传成功后更新补招状态即可 std::cout << "File upload: " << filename << std::endl; - //֪ͨļϴ + //通知文件上传 on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_FILEDATA)); } @@ -874,23 +967,23 @@ void process_received_message(string mac, string id,const char* data, size_t len << ", Error: " << strerror(errno) << std::endl; } - //ǰļϣΪдһļȴأһѾȴеȺˣɿ״ֱ̬ӾͻῪʼļع + //当前文件下载完毕,调整为空闲处理下一项工作(如果这里后续有新文件等待下载,一般已经存入等待队列等候处理了,调成空闲状态后直接就会开始新文件的下载工作) ClientManager::instance().change_device_state(id, DeviceState::READING_FILEDATA); } } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_FILEDATA)); - // ļݴ󣬵Ϊ״̬һ + // 下载文件数据错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_FIXEDVALUE: - //ȡָ㶨ֵ + //读取指定测点定值数据 if (udata[8] == static_cast(MsgResponseType::Response_FixValue)) { - // ȷݳ㹻 + // 确保数据长度足够包含测点序号 if (parser.RecvData.size() < 1) { std::cout << "Invalid fix value data length" << std::endl; on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_FIXEDVALUE)); @@ -898,15 +991,15 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // ȡ (һֽ) + // 提取测点序号 (第一个字节) uint8_t monitor_index = parser.RecvData[0]; std::cout << "Monitor Index: " << static_cast(monitor_index) << std::endl; - // Чݳ (ų) + // 计算有效数据长度 (排除测点序号) size_t bufflen = parser.RecvData.size() - 1; - const size_t structlen = 4; // ÿռ4ֽ + const size_t structlen = 4; // 每个浮点数占4字节 - // ݳǷϷ + // 检查数据长度是否合法 if (bufflen % structlen != 0) { std::cout << "Invalid fix value data length: " << bufflen << " (not multiple of 4)" << std::endl; @@ -915,13 +1008,13 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // 洢ֵ + // 存储浮点值的容器 std::vector fList; - fList.reserve(bufflen / structlen); // Ԥռ + fList.reserve(bufflen / structlen); // 预分配空间 - // (ӵڶֽڿʼ) + // 解析浮点数据 (从第二个字节开始) for (size_t i = 1; i < parser.RecvData.size(); i += structlen) { - // 4ֽ + // 复制4字节数据 uint8_t bytes[4] = { parser.RecvData[i], parser.RecvData[i + 1], @@ -929,48 +1022,48 @@ void process_received_message(string mac, string id,const char* data, size_t len parser.RecvData[i + 3] }; - // תֽ (תС) + // 翻转字节序 (大端转小端) std::swap(bytes[0], bytes[3]); std::swap(bytes[1], bytes[2]); - // תΪfloat + // 转换为float float value; memcpy(&value, bytes, sizeof(float)); fList.push_back(value); } - // ӡ + // 打印解析结果 std::cout << "Parsed " << fList.size() << " fix values:" << std::endl; for (size_t j = 0; j < fList.size(); ++j) { std::cout << " Value[" << j << "]: " << fList[j] << std::endl; } - //洢ֵlnk20250827 + //存储定值lnk20250827 save_set_value(id, monitor_index, fList); - //Զֵ޸Ĺ + //测试定值修改功能 //ClientManager::instance().set_fixedvalue_action_to_device(id, monitor_index, fList); - //ֵȡϣΪУ + //定值读取完毕,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_FIXEDVALUE)); - // ȡֵ󣬵Ϊ״̬һ + // 读取定值错误,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_FIXEDVALUEDES: - //ȡָ㶨ֵ + //读取指定测点定值描述 if (udata[8] == static_cast(MsgResponseType::Response_FixDes)) { - // ṹС + // 计算结构体大小 const size_t structlen = sizeof(DZ_TAB_STRUCT); const size_t bufflen = parser.RecvData.size(); - // ݳǷЧ + // 检查数据长度是否有效 if (bufflen == 0 || bufflen % structlen != 0) { std::cerr << "Invalid fixdes data length: " << bufflen << " (expected multiple of " << structlen << ")" << std::endl; @@ -979,17 +1072,17 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // 洢нĶֵ + // 存储所有解析出的定值描述 std::vector dz_list; dz_list.reserve(bufflen / structlen); - // жֵṹ + // 遍历所有定值描述结构体 for (size_t i = 0, j = 1; i < bufflen; i += structlen, j++) { - // ݵʱ + // 复制数据到临时缓冲区 std::vector buff(structlen); memcpy(buff.data(), parser.RecvData.data() + i, structlen); - // ִֽתC#ͬ + // 执行字节序转换(与C#相同) ReversalBuff(buff.data(), 0, 2); // LN_Num ReversalBuff(buff.data(), 2, 2); // DZ_Num ReversalBuff(buff.data(), 70, 2); // DZ_Type @@ -997,11 +1090,11 @@ void process_received_message(string mac, string id,const char* data, size_t len ReversalBuff(buff.data(), 76, 4); // DZ_Max ReversalBuff(buff.data(), 80, 4); // DZ_Default - // Ϊṹ + // 解析为结构体 DZ_TAB_STRUCT dz_info; memcpy(&dz_info, buff.data(), structlen); - // ȷַ - ҵһ'\0'Ϊ + // 正确处理字符串 - 查找第一个'\0'作为结束符 auto find_string_end = [](const char* arr, size_t max_len) -> size_t { for (size_t i = 0; i < max_len; i++) { if (arr[i] == '\0') return i; @@ -1009,18 +1102,18 @@ void process_received_message(string mac, string id,const char* data, size_t len return max_len; }; - // ȡԭʼGBKַ + // 提取原始GBK字符串 size_t name_len = find_string_end(dz_info.DZ_Name, sizeof(dz_info.DZ_Name)); size_t unit_len = find_string_end(dz_info.DZ_UNIT, sizeof(dz_info.DZ_UNIT)); - // תΪɴӡַѡ(GBK) + // 转换为可打印字符串(可选)(GBK编码) std::string dz_name(dz_info.DZ_Name, name_len); std::string dz_unit(dz_info.DZ_UNIT, unit_len); - // 浽 + // 保存到上下文 dz_list.push_back(dz_info); - // ѡ + // 调试输出(可选) std::cout << "Parsed DZ entry #" << j << ": " << "LN=" << dz_info.LN_Num << ", ID=" << dz_info.DZ_Num @@ -1033,50 +1126,50 @@ void process_received_message(string mac, string id,const char* data, size_t len } //lnk20250828 - // ȡ (һֽ) + // 提取测点序号 (第一个字节) uint8_t monitor_index = parser.RecvData[0]; std::cout << "Monitor Index: " << static_cast(monitor_index) << std::endl; send_set_value_reply(id, monitor_index, dz_list); on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_FIXEDVALUE)); - //ֵȡϣΪУ + //定值描述读取完毕,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR),id,0,static_cast(DeviceState::READING_FIXEDVALUEDES)); - // ȡֵΪ״̬һ + // 读取定值描述,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::SET_FIXEDVALUE: - //װöֵ + //设置装置定值 if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { std::cout << "set success" << mac << std::endl; - //Ӧlnk20250828 + //响应lnk20250828 on_device_response_minimal(static_cast(ResponseCode::OK),id,0,static_cast(DeviceState::SET_FIXEDVALUE)); - //ֵóɹΪУ + //定值设置成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { std::cout << "set error" << mac << std::endl; - // װ÷Ӧ𣬶ֵʧ + // 装置否定应答,定值设置失败 - //Ӧlnk20250828 + //响应lnk20250828 on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST),id,0,static_cast(DeviceState::SET_FIXEDVALUE)); - // װöֵʧܣΪ״̬һ + // 设置装置定值失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 - // װöֵʧܣΪ״̬һ + // 装置答非所问异常 + // 设置装置定值失败,调整为空闲状态,处理下一项工作。 - //Ӧlnk20250828 + //响应lnk20250828 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR),id,0,static_cast(DeviceState::SET_FIXEDVALUE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); @@ -1084,70 +1177,70 @@ void process_received_message(string mac, string id,const char* data, size_t len break; case DeviceState::READING_INTERFIXEDVALUE: - //ȡڲֵ + //读取内部定值 if (udata[8] == static_cast(MsgResponseType::Response_Read_InterFix)) { - // ȡݳ + // 获取数据长度 size_t bufflen = parser.RecvData.size(); - const size_t structlen = 2; // ÿushortռ2ֽ + const size_t structlen = 2; // 每个ushort占2字节 - // 洢 + // 存储解析结果的容器 std::vector fList; - fList.reserve(bufflen / structlen); // Ԥռ + fList.reserve(bufflen / structlen); // 预分配空间 - // ÿushort + // 解析每个ushort数据 for (size_t i = 0; i < bufflen; i += structlen) { - // 2ֽ + // 复制2字节数据 uint8_t bytes[2] = { parser.RecvData[i], parser.RecvData[i + 1] }; - // תֽ (תС) + // 翻转字节序 (大端转小端) std::swap(bytes[0], bytes[1]); - // תΪushort - ʹmemcpyȷȷֽ + // 转换为ushort - 使用memcpy确保正确处理字节序 ushort value; memcpy(&value, bytes, sizeof(ushort)); fList.push_back(value); } - // ӡã + // 打印解析结果(调试用) std::cout << "Parsed " << fList.size() << " internal fixed values:" << std::endl; for (size_t j = 0; j < fList.size(); ++j) { std::cout << " Value[" << j << "]: " << fList[j] << std::endl; } - //洢ֵlnk20250827 + //存储定值lnk20250827 save_internal_value(id, fList); - //ڲֵ޸IJ + //内部定值修改测试 //ClientManager::instance().set_interfixedvalue_action_to_device(id, fList); - //ڲֵȡϣΪУ + //内部定值获取完毕,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_INTERFIXEDVALUE)); - // ȡװڲֵʧܣΪ״̬һ + // 读取装置内部定值失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_INTERFIXEDVALUEDES: - //ȡڲֵ + //读取内部定值描述 if (udata[8] == static_cast(MsgResponseType::Response_Read_InterFixDes)) { - // ȡ + // 获取接收数据 std::vector& recvData = parser.RecvData; size_t bufflen = recvData.size(); const size_t structlen = sizeof(NameFixValue); - // 洢 + // 存储解析结果的向量 std::vector fixValueList; - // ݳǷϷ + // 检查数据长度是否合法 if (bufflen == 0 || bufflen % structlen != 0) { std::cerr << "Invalid internal fixdes data length: " << bufflen << " (expected multiple of " << structlen << ")" << std::endl; @@ -1157,34 +1250,34 @@ void process_received_message(string mac, string id,const char* data, size_t len } else { - // ṹ + // 计算结构体数量 size_t structCount = bufflen / structlen; fixValueList.reserve(structCount); - // нṹ + // 遍历所有结构体 for (size_t i = 0, k = 1; i < bufflen; i += structlen, k++) { - // Ƶǰṹݵ + // 复制当前结构体数据到缓冲区 std::vector buff(structlen); memcpy(buff.data(), recvData.data() + i, structlen); - // תDataType (ƫ22, 2ֽ) + // 翻转数据类型DataType (偏移22, 2字节) ReversalBuff(buff.data(), 22, 2); - // תСֵMinValue (ƫ24, 2ֽ) + // 翻转最小值MinValue (偏移24, 2字节) ReversalBuff(buff.data(), 24, 2); - // תֵMaxValue (ƫ26, 2ֽ) + // 翻转最大值MaxValue (偏移26, 2字节) ReversalBuff(buff.data(), 26, 2); - // תȱʡֵDefaultValue (ƫ28, 2ֽ) + // 翻转缺省值DefaultValue (偏移28, 2字节) ReversalBuff(buff.data(), 28, 2); - // Ϊṹ + // 解析为结构体 NameFixValue dz_info; memcpy(&dz_info, buff.data(), structlen); - // ӵб + // 添加到结果列表 fixValueList.push_back(dz_info); - // + // 调试输出 std::string fixName(dz_info.sFixValueName, strnlen(dz_info.sFixValueName, sizeof(dz_info.sFixValueName))); std::string dimension(dz_info.sDimension, @@ -1203,27 +1296,27 @@ void process_received_message(string mac, string id,const char* data, size_t len //lnk20250905 save_internal_info(id, fixValueList); - //ڲֵȡϣΪ״̬һ + //内部定值描述获取完毕,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_INTERFIXEDVALUEDES)); - // ȡװڲֵʧܣΪ״̬һ + // 读取装置内部定值描述失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_CONTROLWORD: - //ȡ + //读取控制字描述 if (udata[8] == static_cast(MsgResponseType::Response_Read_InterFixDes)) { - // ṹС + // 计算结构体大小 const size_t structlen = sizeof(DZ_kzz_bit); const size_t bufflen = parser.RecvData.size(); - // ݳǷЧ + // 检查数据长度是否有效 if (bufflen == 0 || bufflen % structlen != 0) { std::cerr << "Invalid control word data length: " << bufflen << " (expected multiple of " << structlen << ")" << std::endl; @@ -1232,21 +1325,21 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // 洢 + // 存储解析结果 std::vector control_words; control_words.reserve(bufflen / structlen); - // пṹ + // 遍历所有控制字描述结构体 for (size_t i = 0; i < bufflen; i += structlen) { - // ݵʱ + // 复制数据到临时缓冲区 std::vector buff(structlen); memcpy(buff.data(), parser.RecvData.data() + i, structlen); - // Ϊṹ + // 解析为结构体 DZ_kzz_bit dz_info; memcpy(&dz_info, buff.data(), structlen); - // ȷַ - ҵһ'\0'Ϊ + // 正确处理字符串 - 查找第一个'\0'作为结束符 auto find_string_end = [](const char* arr, size_t max_len) -> size_t { for (size_t i = 0; i < max_len; i++) { if (arr[i] == '\0') return i; @@ -1254,14 +1347,14 @@ void process_received_message(string mac, string id,const char* data, size_t len return max_len; }; - // ȡԭʼGBKַ + // 提取原始GBK字符串 size_t name_len = find_string_end(dz_info.kzz_bit, sizeof(dz_info.kzz_bit)); - // ֱӴ洢ԭʼGBKݣתUTF-8 + // 直接存储原始GBK数据(不转换UTF-8) control_words.push_back(dz_info); - // ѡ + // 调试输出(可选) std::string gbk_name(dz_info.kzz_bit,name_len); std::cout << "Control word: " << gbk_name << ", enable: " << static_cast(dz_info.bit_enable) << std::endl; @@ -1270,22 +1363,22 @@ void process_received_message(string mac, string id,const char* data, size_t len send_internal_value_reply(id, control_words); on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_INTERFIXEDVALUE)); - // ȡϣΪУ + // 控制字描述读取完毕,调整为空闲,处理后续工作 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_CONTROLWORD)); - // ȡװÿʧܣΪ״̬һ + // 读取装置控制字描述失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::SET_INTERFIXEDVALUE: - //ڲֵ + //设置内部定值 if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { std::cout << "set success" << mac << std::endl; - //ڲֵóɹΪУ + //内部定值设置成功,调整为空闲,处理后续工作。 on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SET_INTERFIXEDVALUE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); @@ -1295,27 +1388,27 @@ void process_received_message(string mac, string id,const char* data, size_t len std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; - // װ÷Ӧڲֵʧ + // 装置否定应答,内部定值设置失败 on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SET_INTERFIXEDVALUE)); - // װڲֵʧܣΪ״̬һ + // 设置装置内部定值失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 + // 装置答非所问异常 on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_INTERFIXEDVALUE)); - // װڲֵʧܣΪ״̬һ + // 设置装置内部定值失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_RUNNINGINFORMATION_1: - //ȡװϢ() + //读取装置运行信息(主动触发) if (udata[8] == static_cast(MsgResponseType::Response_Read_RunningInformation)) { - // ȡ + // 获取解析后的数据体 std::vector& recvData = parser.RecvData; - // ݳǷ㹻 + // 检查数据长度是否足够 if (recvData.size() < 2) { std::cerr << "Invalid running information data: too short (" << recvData.size() << " bytes)" << std::endl; @@ -1323,10 +1416,10 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // ȡЧغɳ + // 提取有效载荷长度 size_t payloadLength = recvData.size() - 2; - // Чغ + // 复制有效载荷数据 std::vector payloadBytes(payloadLength); if (recvData.size() >= 2 + payloadLength) { std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin()); @@ -1338,10 +1431,10 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // תΪUTF-8ַ + // 转换为UTF-8字符串 std::string payload(payloadBytes.begin(), payloadBytes.end()); - // New_MachMessageĽṹ + // 定义类似New_MachMessage的结构体 struct RunningInformation { std::string Time; std::string CpuLoad; @@ -1355,7 +1448,7 @@ void process_received_message(string mac, string id,const char* data, size_t len std::string SignalStrength; } result; - // ȥַ˵ + // 辅助函数:去除字符串两端的引号 auto trimQuotes = [](const std::string& str) -> std::string { if (str.size() >= 2 && str.front() == '"' && str.back() == '"') { return str.substr(1, str.size() - 2); @@ -1363,11 +1456,11 @@ void process_received_message(string mac, string id,const char* data, size_t len return str; }; - // CPUֵ + // 辅助函数:处理CPU负载值 auto processCpuLoad = [](const std::string& cpuValue) -> std::string { if (cpuValue.empty()) return cpuValue; - // ˸ʽ"39_38" + // 处理多核格式(如"39_38") if (cpuValue.find('_') != std::string::npos) { std::vector cores; size_t start = 0, end; @@ -1375,21 +1468,21 @@ void process_received_message(string mac, string id,const char* data, size_t len cores.push_back(cpuValue.substr(start, end - start)); start = end + 1; } - cores.push_back(cpuValue.substr(start)); // һ + cores.push_back(cpuValue.substr(start)); // 添加最后一部分 for (auto& core : cores) { - // ֶתstd::stoi + // 手动转换整数(替代std::stoi) const char* str = core.c_str(); char* endptr = nullptr; long value = strtol(str, &endptr, 10); - // תǷЧ + // 检查转换是否有效 if (endptr != str && *endptr == '\0') { - // УΧֵ + // 校正超范围值 if (value > 100) value /= 100; core = std::to_string(value); } - // תʧܱԭֵ + // 转换失败保持原值 } std::string result; @@ -1399,13 +1492,13 @@ void process_received_message(string mac, string id,const char* data, size_t len } return result; } - // ˸ʽ + // 处理单核格式 else { const char* str = cpuValue.c_str(); char* endptr = nullptr; long value = strtol(str, &endptr, 10); - // תǷЧ + // 检查转换是否有效 if (endptr != str && *endptr == '\0') { if (value > 100) value /= 100; return std::to_string(value); @@ -1414,7 +1507,7 @@ void process_received_message(string mac, string id,const char* data, size_t len } }; - // ֶָβ + // 分割字段并处理 std::vector fields; size_t start = 0; while (start < payload.length()) { @@ -1428,44 +1521,44 @@ void process_received_message(string mac, string id,const char* data, size_t len } for (const auto& field : fields) { - // ֶ + // 跳过空字段 if (field.empty()) continue; - // ðλ + // 查找冒号位置 size_t colonPos = field.find(':'); if (colonPos == std::string::npos || colonPos == 0 || colonPos == field.length() - 1) { continue; } - // ֵָ + // 分割键值对 std::string key = field.substr(0, colonPos); std::string value = field.substr(colonPos + 1); - // ȥĿհ + // 去除键的空白 size_t keyStart = key.find_first_not_of(" \t"); size_t keyEnd = key.find_last_not_of(" \t"); if (keyStart != std::string::npos && keyEnd != std::string::npos) { key = key.substr(keyStart, keyEnd - keyStart + 1); } - // ȥֵĿհ + // 去除值的空白 size_t valStart = value.find_first_not_of(" \t"); size_t valEnd = value.find_last_not_of(" \t"); if (valStart != std::string::npos && valEnd != std::string::npos) { value = value.substr(valStart, valEnd - valStart + 1); } - // ȥֵ˵ + // 去除值两端的引号 if (value.size() >= 2 && value.front() == '"' && value.back() == '"') { value = value.substr(1, value.size() - 2); } - // ԽתΪ + // 尝试将键转换为整数 const char* keyStr = key.c_str(); char* endPtr = nullptr; long fieldId = strtol(keyStr, &endPtr, 10); - // תǷЧ + // 检查转换是否有效 if (endPtr != keyStr && *endPtr == '\0' && fieldId >= 1 && fieldId <= 10) { switch (fieldId) { case 1: result.Time = value; break; @@ -1483,10 +1576,10 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - // ⴦CPU + // 特殊处理CPU负载 result.CpuLoad = processCpuLoad(result.CpuLoad); - // ӡʵӦп滻Ϊ߼ + // 打印解析结果(实际应用中可替换为其他处理逻辑) std::cout << "Device Running Information (" << mac << "):\n" << " Time: " << result.Time << "\n" << " CPU Load: " << result.CpuLoad << "\n" @@ -1497,23 +1590,23 @@ void process_received_message(string mac, string id,const char* data, size_t len << ", Cloud=" << result.CloudTimeSync << "\n" << " Signal: " << result.SignalStrength << std::endl; - //ȡװϢ()ɹΪУ + //读取装置运行信息(主动触发)成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 - // ȡװϢ()ʧܣΪ״̬һ + // 装置答非所问异常 + // 读取装置运行信息(主动触发)失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_RUNNINGINFORMATION_2: - //ȡװϢ(ʱ) һ£޸ݷͲ + //读取装置运行信息(定时触发) 接收与解析和主动触发一致,仅修改数据发送部分 if (udata[8] == static_cast(MsgResponseType::Response_Read_RunningInformation)) { - // ȡ + // 获取解析后的数据体 std::vector& recvData = parser.RecvData; - // ݳǷ㹻 + // 检查数据长度是否足够 if (recvData.size() < 2) { std::cerr << "Invalid running information data: too short (" << recvData.size() << " bytes)" << std::endl; @@ -1521,10 +1614,10 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // ȡЧغɳ + // 提取有效载荷长度 size_t payloadLength = recvData.size() - 2; - // Чغ + // 复制有效载荷数据 std::vector payloadBytes(payloadLength); if (recvData.size() >= 2 + payloadLength) { std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin()); @@ -1536,10 +1629,10 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // תΪUTF-8ַ + // 转换为UTF-8字符串 std::string payload(payloadBytes.begin(), payloadBytes.end()); - // New_MachMessageĽṹ + // 定义类似New_MachMessage的结构体 struct RunningInformation { std::string Time; std::string CpuLoad; @@ -1553,7 +1646,7 @@ void process_received_message(string mac, string id,const char* data, size_t len std::string SignalStrength; } result; - // ȥַ˵ + // 辅助函数:去除字符串两端的引号 auto trimQuotes = [](const std::string& str) -> std::string { if (str.size() >= 2 && str.front() == '"' && str.back() == '"') { return str.substr(1, str.size() - 2); @@ -1561,11 +1654,11 @@ void process_received_message(string mac, string id,const char* data, size_t len return str; }; - // CPUֵ + // 辅助函数:处理CPU负载值 auto processCpuLoad = [](const std::string& cpuValue) -> std::string { if (cpuValue.empty()) return cpuValue; - // ˸ʽ"39_38" + // 处理多核格式(如"39_38") if (cpuValue.find('_') != std::string::npos) { std::vector cores; size_t start = 0, end; @@ -1573,21 +1666,21 @@ void process_received_message(string mac, string id,const char* data, size_t len cores.push_back(cpuValue.substr(start, end - start)); start = end + 1; } - cores.push_back(cpuValue.substr(start)); // һ + cores.push_back(cpuValue.substr(start)); // 添加最后一部分 for (auto& core : cores) { - // ֶתstd::stoi + // 手动转换整数(替代std::stoi) const char* str = core.c_str(); char* endptr = nullptr; long value = strtol(str, &endptr, 10); - // תǷЧ + // 检查转换是否有效 if (endptr != str && *endptr == '\0') { - // УΧֵ + // 校正超范围值 if (value > 100) value /= 100; core = std::to_string(value); } - // תʧܱԭֵ + // 转换失败保持原值 } std::string result; @@ -1597,13 +1690,13 @@ void process_received_message(string mac, string id,const char* data, size_t len } return result; } - // ˸ʽ + // 处理单核格式 else { const char* str = cpuValue.c_str(); char* endptr = nullptr; long value = strtol(str, &endptr, 10); - // תǷЧ + // 检查转换是否有效 if (endptr != str && *endptr == '\0') { if (value > 100) value /= 100; return std::to_string(value); @@ -1612,7 +1705,7 @@ void process_received_message(string mac, string id,const char* data, size_t len } }; - // ֶָβ + // 分割字段并处理 std::vector fields; size_t start = 0; while (start < payload.length()) { @@ -1626,44 +1719,44 @@ void process_received_message(string mac, string id,const char* data, size_t len } for (const auto& field : fields) { - // ֶ + // 跳过空字段 if (field.empty()) continue; - // ðλ + // 查找冒号位置 size_t colonPos = field.find(':'); if (colonPos == std::string::npos || colonPos == 0 || colonPos == field.length() - 1) { continue; } - // ֵָ + // 分割键值对 std::string key = field.substr(0, colonPos); std::string value = field.substr(colonPos + 1); - // ȥĿհ + // 去除键的空白 size_t keyStart = key.find_first_not_of(" \t"); size_t keyEnd = key.find_last_not_of(" \t"); if (keyStart != std::string::npos && keyEnd != std::string::npos) { key = key.substr(keyStart, keyEnd - keyStart + 1); } - // ȥֵĿհ + // 去除值的空白 size_t valStart = value.find_first_not_of(" \t"); size_t valEnd = value.find_last_not_of(" \t"); if (valStart != std::string::npos && valEnd != std::string::npos) { value = value.substr(valStart, valEnd - valStart + 1); } - // ȥֵ˵ + // 去除值两端的引号 if (value.size() >= 2 && value.front() == '"' && value.back() == '"') { value = value.substr(1, value.size() - 2); } - // ԽתΪ + // 尝试将键转换为整数 const char* keyStr = key.c_str(); char* endPtr = nullptr; long fieldId = strtol(keyStr, &endPtr, 10); - // תǷЧ + // 检查转换是否有效 if (endPtr != keyStr && *endPtr == '\0' && fieldId >= 1 && fieldId <= 10) { switch (fieldId) { case 1: result.Time = value; break; @@ -1681,10 +1774,10 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - // ⴦CPU + // 特殊处理CPU负载 result.CpuLoad = processCpuLoad(result.CpuLoad); - // ӡʵӦп滻Ϊ߼ + // 打印解析结果(实际应用中可替换为其他处理逻辑) std::cout << "Device Running Information (" << mac << "):\n" << " Time: " << result.Time << "\n" << " CPU Load: " << result.CpuLoad << "\n" @@ -1695,23 +1788,23 @@ void process_received_message(string mac, string id,const char* data, size_t len << ", Cloud=" << result.CloudTimeSync << "\n" << " Signal: " << result.SignalStrength << std::endl; - //ȡװϢ()ɹΪУ + //读取装置运行信息(主动触发)成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 - // ȡװϢ(ʱ)ʧܣΪ״̬һ + // 装置答非所问异常 + // 读取装置运行信息(定时触发)失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_DEVVERSION: - //ȡװð汾ϢͬϢȡ(άЭȷ϶ʱ汾Ƶгأ̬ȡ汾) + //读取装置版本配置信息(功能码同运行信息读取)(运维协议确认对时版本,电度与高频谐波开关,稳态间隔获取,版本配置上送) if (udata[8] == static_cast(MsgResponseType::Response_Read_RunningInformation)) { - // ȡ + // 获取解析后的数据体 std::vector& recvData = parser.RecvData; - // ݳǷ㹻 + // 检查数据长度是否足够 if (recvData.size() < 2) { std::cerr << "Invalid running information data: too short (" << recvData.size() << " bytes)" << std::endl; @@ -1719,10 +1812,10 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // ȡЧغɳ + // 提取有效载荷长度 size_t payloadLength = recvData.size() - 2; - // Чغ + // 复制有效载荷数据 std::vector payloadBytes(payloadLength); if (recvData.size() >= 2 + payloadLength) { std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin()); @@ -1734,41 +1827,41 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // תΪUTF-8ַ + // 转换为UTF-8字符串 std::string payload(payloadBytes.begin(), payloadBytes.end()); - // 洢װð汾ϢĽṹ + // 定义存储装置版本信息的结构体 struct DeviceVersionInfo { - std::string BaseModel; // 1: װûͺ - std::string CloudProtocolVer; // 2: ƷЭ汾 - std::string AppVersion; // 3: Ӧó汾 - std::string AppDate; // 4: Ӧó汾 - std::string AppChecksum; // 5: ӦóУ - std::string VoltageWiring; // 6: ѹ߷ʽ - std::string CurrentBSynthetic; // 7: BǷϳ - int DataStatInterval = 0; // 8: ͳʱӣ - float RatedVoltage = 0.0f; // 9: ѹֵλV - float PTRatio = 0.0f; // 10: PT - float CTRatio = 0.0f; // 11: CT - std::string SntpIP; // 12: sntpʱIP - int SntpPort = 0; // 13: sntpʱ˿ - int SntpInterval = 0; // 14: sntpʱӣ - int WebPort = 0; // 15: Web˿ - int FtpPort = 0; // 16: ftp˿ - int PqdifInterval = 0; // 17: PqdifļʱСʱ - int WaveFileTypeCount = 0; // 18: ¼ļļ - std::string SpecialVersion; // 19: 汾Ϣ - std::string DeviceModel; // 20: װͺ - int HarmonicEnergyFlag = 0; // 21: гȰ汾־ - std::string PhysicalName; // 22: 豸 - std::string WaveLDName; // 23: ¼LD - int HighFreqHarmonicFlag = 0; // 24: Ƶгܱ־ - unsigned int CommProtocols = 0; // 51: ͶͨѶЭ - unsigned int TimeSyncMethods = 0;// 52: ͶĶʱʽ - unsigned int DeviceFunctions = 0;// 53: װù + std::string BaseModel; // 1: 装置基础型号 + std::string CloudProtocolVer; // 2: 云服务协议版本 + std::string AppVersion; // 3: 应用程序版本号 + std::string AppDate; // 4: 应用程序版本日期 + std::string AppChecksum; // 5: 应用程序校验码 + std::string VoltageWiring; // 6: 电压接线方式 + std::string CurrentBSynthetic; // 7: 电流B相是否合成 + int DataStatInterval = 0; // 8: 数据统计时间间隔(分钟) + float RatedVoltage = 0.0f; // 9: 额定电压(二次值,单位V) + float PTRatio = 0.0f; // 10: PT变比 + float CTRatio = 0.0f; // 11: CT变比 + std::string SntpIP; // 12: sntp对时IP + int SntpPort = 0; // 13: sntp对时端口 + int SntpInterval = 0; // 14: sntp对时间隔(分钟) + int WebPort = 0; // 15: Web端口 + int FtpPort = 0; // 16: ftp端口 + int PqdifInterval = 0; // 17: Pqdif文件时间间隔(小时) + int WaveFileTypeCount = 0; // 18: 录波文件包含文件类型数 + std::string SpecialVersion; // 19: 特殊程序版本信息 + std::string DeviceModel; // 20: 装置型号 + int HarmonicEnergyFlag = 0; // 21: 谐波电度版本标志 + std::string PhysicalName; // 22: 物理设备名称 + std::string WaveLDName; // 23: 录波LD名称 + int HighFreqHarmonicFlag = 0; // 24: 高频谐波功能标志 + unsigned int CommProtocols = 0; // 51: 投入的通讯协议 + unsigned int TimeSyncMethods = 0;// 52: 投入的对时方式 + unsigned int DeviceFunctions = 0;// 53: 装置功能配置 } versionInfo; - // ֶָ + // 分割字段 std::vector fields; size_t start = 0; while (start < payload.length()) { @@ -1781,18 +1874,18 @@ void process_received_message(string mac, string id,const char* data, size_t len start = end + 1; } - // ÿֶ + // 处理每个字段 for (const auto& field : fields) { if (field.empty()) continue; - // ֵָ + // 分割键值对 size_t colonPos = field.find(':'); if (colonPos == std::string::npos || colonPos == 0) continue; std::string key = field.substr(0, colonPos); std::string value = field.substr(colonPos + 1); - // ȥֵ˵Ŀհ׺ + // 去除键值两端的空白和引号 auto trim = [](std::string str) -> std::string { size_t start = str.find_first_not_of(" \t\""); size_t end = str.find_last_not_of(" \t\""); @@ -1801,11 +1894,11 @@ void process_received_message(string mac, string id,const char* data, size_t len key = trim(key); value = trim(value); - // תΪϢID + // 转换为信息编码ID try { int fieldId = std::stoi(key); switch (fieldId) { - // ֶַ + // 字符串类型字段 case 1: versionInfo.BaseModel = value; break; case 2: versionInfo.CloudProtocolVer = value; break; case 3: versionInfo.AppVersion = value; break; @@ -1819,7 +1912,7 @@ void process_received_message(string mac, string id,const char* data, size_t len case 22: versionInfo.PhysicalName = value; break; case 23: versionInfo.WaveLDName = value; break; - // ֵֶ + // 数值类型字段 case 8: versionInfo.DataStatInterval = std::stoi(value); break; case 9: versionInfo.RatedVoltage = std::stof(value); break; case 10: versionInfo.PTRatio = std::stof(value); break; @@ -1833,7 +1926,7 @@ void process_received_message(string mac, string id,const char* data, size_t len case 21: versionInfo.HarmonicEnergyFlag = std::stoi(value); break; case 24: versionInfo.HighFreqHarmonicFlag = std::stoi(value); break; - // ʮֶΣ51+ + // 十六进制字段(51+) case 51: case 52: case 53: { @@ -1855,11 +1948,11 @@ void process_received_message(string mac, string id,const char* data, size_t len } } - //Э汾ǿֵδֵʹĬϵV1.0 + //云协议版本非空则赋值,未赋值则使用默认的V1.0 if (!versionInfo.CloudProtocolVer.empty()) { ClientManager::instance().set_versioninformation(id, versionInfo.CloudProtocolVer); } - // ӡ + // 打印解析结果 std::cout << "Device Version Info (" << mac << "):\n" << " Base Model: " << versionInfo.BaseModel << "\n" << " Cloud Protocol: " << versionInfo.CloudProtocolVer << "\n" @@ -1872,21 +1965,21 @@ void process_received_message(string mac, string id,const char* data, size_t len << " Time Sync Methods: 0x" << versionInfo.TimeSyncMethods << "\n" << " Device Functions: 0x" << versionInfo.DeviceFunctions << std::dec << "\n"; - //ȡװð汾ϢɹΪУ + //读取装置版本配置信息成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 - // ȡװð汾ϢʧܣΪ״̬һ + // 装置答非所问异常 + // 读取装置版本配置信息失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::SET_RIGHTTIME: - //װöʱ + //设置装置对时 if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { std::cout << "set success" << mac << std::endl; - //ʱóɹΪУ + //对时设置成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { @@ -1894,99 +1987,99 @@ void process_received_message(string mac, string id,const char* data, size_t len std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; - // װ÷Ӧ𣬶ʱʧ - // öʱʧܣΪ״̬һ + // 装置否定应答,对时设置失败 + // 设置对时失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { - // װô쳣 - // öʱʧܣΪ״̬һ + // 装置答非所问异常 + // 设置对时失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::READING_EVENTLOG: - //װ־ + //补招装置日志 if (udata[8] == static_cast(MsgResponseType::Response_Read_Event)) { std::cout << "set success" << mac << std::endl; std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; if (parser.RecvData.size() >= 14) { - // ȡǰ֡ + // 提取当前帧 int current_frame = 0; if (parser.RecvData.size() >= 4) { std::vector frame_data(parser.RecvData.begin(), parser.RecvData.begin() + 4); - std::reverse(frame_data.begin(), frame_data.end()); // ֽڷת + std::reverse(frame_data.begin(), frame_data.end()); // 字节反转 current_frame = *reinterpret_cast(frame_data.data()); } - // ȡ֡ + // 提取总帧数 int total_frames = 0; if (parser.RecvData.size() >= 8) { std::vector total_frame_data(parser.RecvData.begin() + 4, parser.RecvData.begin() + 8); - std::reverse(total_frame_data.begin(), total_frame_data.end()); // ֽڷת + std::reverse(total_frame_data.begin(), total_frame_data.end()); // 字节反转 total_frames = *reinterpret_cast(total_frame_data.data()); } - // ȡļܴС + // 提取文件总大小 int file_size = 0; if (parser.RecvData.size() >= 12) { std::vector size_data(parser.RecvData.begin() + 8, parser.RecvData.begin() + 12); - std::reverse(size_data.begin(), size_data.end()); // ֽڷת + std::reverse(size_data.begin(), size_data.end()); // 字节反转 file_size = *reinterpret_cast(size_data.data()); } - // ȡCRCУ + // 提取CRC校验码 uint16_t crc = 0; if (parser.RecvData.size() >= 14) { std::vector crc_data(parser.RecvData.begin() + 12, parser.RecvData.begin() + 14); - std::reverse(crc_data.begin(), crc_data.end()); // ֽڷת + std::reverse(crc_data.begin(), crc_data.end()); // 字节反转 crc = *reinterpret_cast(crc_data.data()); } - // ȡļ + // 提取文件数据 std::vector file_data; if (parser.RecvData.size() > 14) { file_data.assign(parser.RecvData.begin() + 14, parser.RecvData.end()); } - // ӵ棨ʹREADING_STATS߼ + // 将数据添加到缓存(使用类似READING_STATS的逻辑) bool complete = ClientManager::instance().add_eventlog_packet_to_device( id, file_data, current_frame, total_frames ); std::cout << "event log:" << current_frame << "/" << total_frames << std::endl; - // Ƿȫ֡ + // 检查是否收全所有帧 if (complete) { - // 1. ȡջݰ + // 1. 获取并清空缓存数据包 auto packets = ClientManager::instance().get_and_clear_event_packets(id); - // 2. ֡ + // 2. 按帧序号排序 std::sort(packets.begin(), packets.end(), [](const ClientContext::StatPacket& a, const ClientContext::StatPacket& b) { return a.packet_index < b.packet_index; }); - // 3. ÿ֡ݲȡ + // 3. 解析每帧数据并提取数据体 std::vector full_data; for (const auto& packet : packets) { - // ӵ + // 将数据体添加到完整序列 full_data.insert(full_data.end(), packet.data.begin(), packet.data.end()); } - //ȷϴ // ȡ + //确认待补招序号 // 获取测点参数 int event_lineid = 0; - std::string strScale;//ѹȼ - int nPTType;//߷ʽ + std::string strScale;//电压等级 + int nPTType;//接线方式 float fPT = 1.0f; float fCT = 1.0f; if (!ClientManager::instance().get_event_lineid(id, event_lineid)) { - //ȡʧܣ̬н - //װ־ȡϣΪ״̬һ + //取出补招序号失败!暂态补招结束 + //补招装置日志获取完毕,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); break; } @@ -1996,26 +2089,26 @@ void process_received_message(string mac, string id,const char* data, size_t len event_lineid, strScale, nPTType) || !ClientManager::instance().get_pt_ct_ratio(id, event_lineid, fPT, fCT)) { - //ȡʽPTCT,ѹȼʧܣ̬н - //װ־ȡϣΪ״̬һ + //取出解析方式,PTCT,电压等级失败!暂态补招结束 + //补招装置日志获取完毕,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); break; } - // ========== full_dataеNewTaglogbufferб ========== + // ========== 新增:解析full_data中的NewTaglogbuffer对象列表 ========== std::list eventList; size_t offset = 0; const size_t headSize = sizeof(NewHeadTaglogbuffer); const size_t bodyItemSize = sizeof(NewBodyTaglogbuffer); while (offset + headSize <= full_data.size()) { - // ȡͷ + // 读取头部 NewHeadTaglogbuffer head; memcpy(&head, full_data.data() + offset, headSize); - head.convertByteOrder(); // תֽ + head.convertByteOrder(); // 转换字节序 uint32_t logParaNum = head.LogParaNum; - // 岿full_dataռõĿռ䣨4Ŀռ䣩 + // 计算身体部分在full_data中占用的空间(最少4个身体项的空间) size_t bodySpace; if (logParaNum <= 4) { bodySpace = 4 * bodyItemSize; @@ -2024,18 +2117,18 @@ void process_received_message(string mac, string id,const char* data, size_t len bodySpace = logParaNum * bodyItemSize; } - // ʣǷ㹻 + // 检查剩余数据是否足够 if (offset + headSize + bodySpace > full_data.size()) { std::cerr << "Insufficient data for event body at offset " << offset << std::endl; break; } - // ¼ͷ + // 创建事件对象并设置头部 NewTaglogbuffer event; event.head = head; event.bodyList.resize(logParaNum); - // 岿 + // 解析身体部分 const uint8_t* bodyData = full_data.data() + offset + headSize; for (uint32_t i = 0; i < logParaNum; ++i) { memcpy(&event.bodyList[i], bodyData, bodyItemSize); @@ -2043,16 +2136,16 @@ void process_received_message(string mac, string id,const char* data, size_t len bodyData += bodyItemSize; } - //ǰ¼ʹвһ£ + //当前解析事件和待补招测点一致,则加入队列 if (event.head.name == event_lineid) { eventList.push_back(event); } - // ƶƫͷռÿռ䣨䣩 + // 移动偏移量,跳过头部和身体占用空间(包括填充) offset += headSize + bodySpace; } - // eventListан¼󣬿д + // 现在eventList中包含所有解析的事件对象,可以在这里进行处理 std::cout << "Parsed " << eventList.size() << " events from event log." << std::endl; std::list recordlist; @@ -2060,11 +2153,11 @@ void process_received_message(string mac, string id,const char* data, size_t len QVVRRecord record = DynamicLog_GetQVVRRecordFromLogBuffer( strScale, nPTType, fPT, event); - // ʹü¼ݣʾӡ̨ - std::cout << "¼: " << record.nType - << ", ʱ: " << record.fPersisstime << "s" - << ", ֵ: " << record.fMagntitude << " pu" - << ", ʱ: " << record.triggerTimeMs << "ms" << std::endl; + // 使用记录数据(示例:打印到控制台) + std::cout << "事件类型: " << record.nType + << ", 持续时间: " << record.fPersisstime << "s" + << ", 特征幅值: " << record.fMagntitude << " pu" + << ", 时间戳: " << record.triggerTimeMs << "ms" << std::endl; recordlist.push_back(record); } @@ -2072,36 +2165,36 @@ void process_received_message(string mac, string id,const char* data, size_t len - //ʱƳCRCУ - //// ========== CRC ֤ ========== + //暂时移除CRC校验相关 + //// ========== 新增 CRC 验证 ========== //if (!full_data.empty()) { - // // ݵ CRC + // // 计算接收数据的 CRC // uint16_t calculated_crc = crc_16_new(full_data.data(), full_data.size()); - // // Ƚϼ CRC ʹӱȡ CRC + // // 比较计算出的 CRC 和从报文中提取的 CRC // if (calculated_crc == crc) { // std::cout << "CRC verification passed for event log data." << std::endl; - // // Լ + // // 这里可以继续处理完整数据 // } // else { // std::cerr << "CRC verification failed! Expected: " << crc // << ", Calculated: " << calculated_crc << std::endl; - // // CRC Уʧܵ + // // 处理 CRC 校验失败的情况 // } //} //else { - // //ȡļ쳣д + // //收取缓存文件异常,结束补招处理 // std::cerr << "No data received for event log." << std::endl; //} } else { - //δȫֱӽȴӦ + //未收全则直接结束处理,等待后续报文应答 return; } } - //װ־ȡϣΪ״̬һ + //补招装置日志获取完毕,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { @@ -2110,35 +2203,35 @@ void process_received_message(string mac, string id,const char* data, size_t len std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; if (udata[10] == static_cast(0x0c)) { - //0x0cѯ̬ݲڣ֪ͨǰ̨ǰʱ̬ + //0x0c错误码代表询问暂态数据不存在,通知前台当前时间段无暂态 std::cout << "not find event " << mac << std::endl; } else if (udata[10] == static_cast(0x06)) { - //0x0cз֪ͨǰ̨쳣 + //0x0c错误码代表补招方法参数错误,通知前台参数异常 } else { - //쳣 + //其余错误码代表异常情况 } - // װ÷ - // װ־ʧܣΪ״̬һ + // 装置否定 + // 补招装置日志失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { std::cout << "set unknow error" << mac << std::endl; std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; - // װô쳣 - // װ־ʧܣΪ״̬һ + // 装置答非所问异常 + // 补招装置日志失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; case DeviceState::CUSTOM_ACTION: - // Զ嶯״̬ + // 自定义动作状态 std::cout << "CUSTOM_ACTION state: Processing custom response from " << mac << std::endl; - // ӴԶ嶯Ӧ߼ + // 这里添加处理自定义动作响应的逻辑 - // ɺ״̬ + // 处理完成后标记状态完成 ClientManager::instance().change_device_state(id, DeviceState::IDLE); break; @@ -2148,7 +2241,7 @@ void process_received_message(string mac, string id,const char* data, size_t len break; } - // ۺ״̬ɺ󴥷״̬ + // 无论何种状态,处理完成后触发后续状态处理 ClientManager::instance().post_message_processing(id); }