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);
}