#include #include #include #include #include #include #include #include #include #include // 字节序转换 #include #include using namespace std; float IntToFloat(int num); float ShorToFloat100(short num); float ShorToFloat1000(short num); float ShorToFloat10000(short num); // 发送报文功能码枚举 enum class MsgRequestType : unsigned char { //询问统计数据时间 Request_StatTime = 0x8b, //询问统计数据 Request_Stat = 0x8a, //询问实时数据 Request_New_3S = 0x04, //下载装置文件 Request_File_Download = 0x07, //询问文件目录 Request_FileDir = 0x02, //询问装置定值 Request_FixValue = 0x20, //询问装置定值描述 Request_FixDes = 0x21, //设置装置定值 Request_Set_Fix = 0x22, //询问内部定值 Request_Read_InterFix = 0x23, //询问内部定值描述 内部定值or控制字 Request_Read_InterFixDes = 0x24, //设置内部定值 Request_Set_InterFix = 0x25, //询问装置运行信息 Request_Read_RunningInformation = 0x0e, //设置装置对时 Request_RightTime = 0x86, //补招事件日志 Request_Read_Event = 0x0D }; // 接收报文功能码枚举 enum class MsgResponseType : unsigned char { //询问统计数据时间 Response_StatTime = 0x27, //询问统计数据 Response_Stat = 0x26, //询问实时数据 Response_New_3S = 0x84, //主动上送的暂态事件 Response_Event = 0x16, //主动上送的波形文件信息事件 Response_ActiveSOEInfo = 0x17, //下载装置文件 Response_File_Download = 0x87, //询问文件目录 Response_FileDir = 0x82, //询问装置定值 Response_FixValue = 0xA0, //询问装置定值描述 Response_FixDes = 0xA1, //设置装置定值(未使用,采用默认肯定与否定应答) Response_Set_Fix = 0xA2, //询问内部定值 Response_Read_InterFix = 0xA3, //询问内部定值描述 Response_Read_InterFixDes = 0xA4, //设置内部定值(未使用,采用默认肯定与否定应答) Response_Set_InterFix = 0xA5, //询问装置运行信息 Response_Read_RunningInformation = 0x8e, //设置装置对时(未使用,采用默认肯定与否定应答) Response_RightTime = 0x86, //补招事件日志 Response_Read_Event = 0x8D, //默认肯定应答 Response_NewACK = 0x40, //默认否定应答 Response_NewNACK = 0x41 }; //基础消息结构 class MessageParser { public: // 成员变量 uint8_t msgType; //功能码 std::vector RecvData; //数据体 int nMsgLen; //功能码+帧序号+数据体 int nRecvDataLen; //数据体长度 // 主处理函数 - 返回bool类型 bool SetMsg(const uint8_t* udata, size_t data_size) { // 1. 检查空指针 if (udata == nullptr) { return false; // 数据处理失败 } // 2. 检查最小长度(6字节头部) constexpr size_t MIN_HEADER_SIZE = 6; if (data_size < MIN_HEADER_SIZE) { return false; // 头部长度不足 } // 3. 提取报文长度(大端序) nMsgLen = (static_cast(udata[4]) << 8) | udata[5]; // 4. 验证完整报文长度 (8 + nMsgLen) if (data_size < 8 + nMsgLen) { return false; // 报文不完整 } // 5. 计算数据区长度 删除了功能码和帧序号4字节 nRecvDataLen = nMsgLen - 4; // 6. CRC校验(根据实际需要实现) /* if (!ValidateCRC(udata, 8 + nMsgLen)) { return false; // CRC校验失败 } */ // 7. 提取消息类型 (索引位置 6 + 2 = 8) msgType = udata[8]; // 8. 提取数据区 (索引位置12开始) RecvData.clear(); if (nRecvDataLen > 0) { // 确保不越界(nRecvDataLen = nMsgLen - 4) RecvData.assign(udata + 12, udata + 12 + nRecvDataLen); } return true; // 数据处理成功 } }; //接收装置时标对象 class tagTime { public: uint16_t DeviceYear; uint16_t DeviceMonth; uint16_t DeviceDay; uint16_t DeviceHour; uint16_t DeviceMinute; uint16_t DeviceSecond; // 返回结构体二进制大小 static constexpr size_t GetSize() { return 6 * sizeof(uint16_t); } // 默认构造函数 tagTime() : DeviceYear(1970), DeviceMonth(1), DeviceDay(1), DeviceHour(0), DeviceMinute(0), DeviceSecond(0) {} // 从std::tm构造 explicit tagTime(const std::tm& dt) : DeviceYear(static_cast(dt.tm_year + 1900)), DeviceMonth(static_cast(dt.tm_mon + 1)), DeviceDay(static_cast(dt.tm_mday)), DeviceHour(static_cast(dt.tm_hour)), DeviceMinute(static_cast(dt.tm_min)), DeviceSecond(static_cast(dt.tm_sec)) {} // 复制函数 void Clone(const tagTime& src) { DeviceYear = src.DeviceYear; DeviceMonth = src.DeviceMonth; DeviceDay = src.DeviceDay; DeviceHour = src.DeviceHour; DeviceMinute = src.DeviceMinute; DeviceSecond = src.DeviceSecond; } // 从二进制流解析(网络字节序) bool SetStructBuf(const uint8_t* bArray, size_t bufSize, size_t offset = 0) { if (bufSize - offset < GetSize()) { return false; } const uint8_t* ptr = bArray + offset; DeviceYear = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(uint16_t); DeviceMonth = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(uint16_t); DeviceDay = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(uint16_t); DeviceHour = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(uint16_t); DeviceMinute = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(uint16_t); DeviceSecond = ntohs(*reinterpret_cast(ptr)); return true; } // 序列化为二进制流(网络字节序) size_t GetStructBuf(uint8_t* bArray, size_t bufSize, size_t offset = 0) const { if (bufSize - offset < GetSize()) { return 0; } uint8_t* ptr = bArray + offset; *reinterpret_cast(ptr) = htons(DeviceYear); ptr += sizeof(uint16_t); *reinterpret_cast(ptr) = htons(DeviceMonth); ptr += sizeof(uint16_t); *reinterpret_cast(ptr) = htons(DeviceDay); ptr += sizeof(uint16_t); *reinterpret_cast(ptr) = htons(DeviceHour); ptr += sizeof(uint16_t); *reinterpret_cast(ptr) = htons(DeviceMinute); ptr += sizeof(uint16_t); *reinterpret_cast(ptr) = htons(DeviceSecond); return GetSize(); } }; //谐波间谐波序列长度 默认50 constexpr int HARMNUM = 50; // 间谐波数据结构 struct tagInHarmData { int32_t Val; int32_t f; static constexpr size_t GetSize() { return sizeof(Val) + sizeof(f); } // 从网络字节序解析 bool SetStructBuf(const uint8_t* ptr) { Val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); f = ntohl(*reinterpret_cast(ptr)); return true; } }; // 功率数据结构 struct tagPowerData { int32_t P; int32_t Q; int32_t S; static constexpr size_t GetSize() { return sizeof(P) + sizeof(Q) + sizeof(S); } // 从网络字节序解析 bool SetStructBuf(const uint8_t* ptr) { P = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); Q = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); S = ntohl(*reinterpret_cast(ptr)); return true; } }; // 主数据结构 (使用1字节对齐) #pragma pack(push, 1) class tagPqData { public: int16_t name; // 监测点号 int16_t Data_Type; // 数据类型 tagTime time; // 时间 // 各种数据数组 std::array Rms; // 电压/电流有效值 std::array UU_Deviation; // 电压上偏差 std::array UL_Deviation; // 电压下偏差 std::array F_Deviation; // 频率偏差 std::array, 2> UI_Seq; // 电压电流序量 std::array, 6> FuHarm; // 整次谐波 std::array, 6> FuHarmPhase; // 谐波相角 std::array, 6> InHarm; // 间谐波 std::array, 4> Total_Power; // 总功率 std::array, 4> Harm_Power; // 谐波功率 std::array, 6> Harm_Contain; // 谐波含有率 std::array Harm_Aberrance; // 谐波畸变率 std::array Cos_PF; // 视在功率因数 std::array Cos_DF; // 位移功率因数 std::array U_Fluctuation; // 电压波动 std::array U_Flicker; // 电压闪变 std::array UL_Flicker; // 电压长闪变 // 构造函数 tagPqData() : name(0), Data_Type(0) { // 所有数组初始化为0 Rms.fill(0); UU_Deviation.fill(0); UL_Deviation.fill(0); F_Deviation.fill(0); for (auto& arr : UI_Seq) arr.fill(0); for (auto& arr : FuHarm) arr.fill(0); for (auto& arr : FuHarmPhase) arr.fill(0); for (auto& arr : Harm_Contain) arr.fill(0); Harm_Aberrance.fill(0); Cos_PF.fill(0); Cos_DF.fill(0); U_Fluctuation.fill(0); U_Flicker.fill(0); UL_Flicker.fill(0); } // 获取结构体大小 static constexpr size_t GetSize() { return sizeof(name) + sizeof(Data_Type) + tagTime::GetSize() + sizeof(Rms) + sizeof(UU_Deviation) + sizeof(UL_Deviation) + sizeof(F_Deviation) + sizeof(UI_Seq) + sizeof(FuHarm) + sizeof(FuHarmPhase) + sizeof(InHarm) + sizeof(Total_Power) + sizeof(Harm_Power) + sizeof(Harm_Contain) + sizeof(Harm_Aberrance) + sizeof(Cos_PF) + sizeof(Cos_DF) + sizeof(U_Fluctuation) + sizeof(U_Flicker) + sizeof(UL_Flicker); } // 从网络字节序解析二进制数据 bool SetStructBuf(const uint8_t* bArray, size_t bufSize, size_t offset = 0) { if (bufSize - offset < GetSize()) { return false; } const uint8_t* ptr = bArray + offset; size_t remaining = bufSize - offset; // 解析基本字段 name = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(name); remaining -= sizeof(name); Data_Type = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(Data_Type); remaining -= sizeof(Data_Type); // 解析时间结构 if (!time.SetStructBuf(ptr, remaining)) { return false; } ptr += tagTime::GetSize(); remaining -= tagTime::GetSize(); // 解析一维int32数组 - 使用显式循环 for (auto& val : Rms) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } for (auto& val : UU_Deviation) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } for (auto& val : UL_Deviation) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } for (auto& val : F_Deviation) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } // 解析二维int32数组 - 使用显式循环 for (auto& arr : UI_Seq) { for (auto& val : arr) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } } for (auto& arr : FuHarm) { for (auto& val : arr) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } } for (auto& arr : FuHarmPhase) { for (auto& val : arr) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } } // 解析间谐波数据 for (auto& arr : InHarm) { for (auto& item : arr) { if (remaining < tagInHarmData::GetSize()) return false; item.SetStructBuf(ptr); ptr += tagInHarmData::GetSize(); remaining -= tagInHarmData::GetSize(); } } // 解析总功率 for (auto& arr : Total_Power) { for (auto& val : arr) { if (remaining < sizeof(int32_t)) return false; val = ntohl(*reinterpret_cast(ptr)); ptr += sizeof(int32_t); remaining -= sizeof(int32_t); } } // 解析谐波功率数据 for (auto& arr : Harm_Power) { for (auto& item : arr) { if (remaining < tagPowerData::GetSize()) return false; item.SetStructBuf(ptr); ptr += tagPowerData::GetSize(); remaining -= tagPowerData::GetSize(); } } // 解析二维int16数组 - 使用显式循环 for (auto& arr : Harm_Contain) { for (auto& val : arr) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } } // 解析一维int16数组 - 使用显式循环 for (auto& val : Harm_Aberrance) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } for (auto& val : Cos_PF) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } for (auto& val : Cos_DF) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } for (auto& val : U_Fluctuation) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } for (auto& val : U_Flicker) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } for (auto& val : UL_Flicker) { if (remaining < sizeof(int16_t)) return false; val = ntohs(*reinterpret_cast(ptr)); ptr += sizeof(int16_t); remaining -= sizeof(int16_t); } return true; } }; #pragma pack(pop) // 间谐波浮点结构 struct tagInHarmData_float { float Val; float f; }; // 功率浮点结构 struct tagPowerData_float { float P; float Q; float S; }; // PQ数据浮点结构 class tagPqData_Float { public: short name; // 监测点号 short Data_Type; // 数据类型 tagTime time; // 时间 // 各种浮点数组 std::array Rms; std::array UU_Deviation; std::array UL_Deviation; std::array F_Deviation; std::array, 2> UI_Seq; std::array, 6> FuHarm; std::array, 6> FuHarmPhase; std::array, 6> InHarm; std::array, 4> Total_Power; std::array, 4> Harm_Power; std::array, 6> Harm_Contain; std::array Harm_Aberrance; // 注意:C#中是8元素 std::array Cos_PF; std::array Cos_DF; std::array U_Fluctuation; std::array U_Flicker; std::array UL_Flicker; // 构造函数初始化数组 tagPqData_Float() { Rms.fill(0.0f); UU_Deviation.fill(0.0f); UL_Deviation.fill(0.0f); F_Deviation.fill(0.0f); for (auto& arr : UI_Seq) arr.fill(0.0f); for (auto& arr : FuHarm) arr.fill(0.0f); for (auto& arr : FuHarmPhase) arr.fill(0.0f); for (auto& arr : Harm_Contain) arr.fill(0.0f); Harm_Aberrance.fill(0.0f); Cos_PF.fill(0.0f); Cos_DF.fill(0.0f); U_Fluctuation.fill(0.0f); U_Flicker.fill(0.0f); UL_Flicker.fill(0.0f); // 初始化嵌套结构 for (auto& arr : InHarm) { for (auto& item : arr) { item = tagInHarmData_float{ 0.0f, 0.0f }; } } for (auto& arr : Harm_Power) { for (auto& item : arr) { item = tagPowerData_float{ 0.0f, 0.0f, 0.0f }; } } } // 转换函数 void SetFloatValue(const tagPqData& SrcData, float fPT, float fCT) { time.Clone(SrcData.time); // F_Deviation for (int i = 0; i < 2; i++) { F_Deviation[i] = IntToFloat(SrcData.F_Deviation[i]); } // UI_Seq for (int i = 0; i < 2; i++) { for (int j = 0; j < 4; j++) { if (i == 0) { // 电压 if (j == 2) { // 正序 UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fPT; } else if (j < 3) { UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fPT * 1000.0f; } else { UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]); } } else { // 电流 if (j < 3) { UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fCT; } else { UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]); } } } } // 波动和闪变 for (int i = 0; i < 3; i++) { U_Fluctuation[i] = ShorToFloat1000(SrcData.U_Fluctuation[i]); U_Flicker[i] = ShorToFloat1000(SrcData.U_Flicker[i]); UL_Flicker[i] = ShorToFloat1000(SrcData.UL_Flicker[i]); } // 功率因数 for (int i = 0; i < 4; i++) { Cos_PF[i] = ShorToFloat10000(SrcData.Cos_PF[i]); Cos_DF[i] = ShorToFloat10000(SrcData.Cos_DF[i]); } // 总功率 for (int i = 0; i < 4; i++) { for (int j = 0; j < 3; j++) { Total_Power[i][j] = IntToFloat(SrcData.Total_Power[i][j]) * fPT * fCT; } } // 谐波功率 for (int i = 0; i < 4; i++) { for (int j = 0; j < HARMNUM; j++) { Harm_Power[i][j].P = IntToFloat(SrcData.Harm_Power[i][j].P) * fPT * fCT; Harm_Power[i][j].Q = IntToFloat(SrcData.Harm_Power[i][j].Q) * fPT * fCT; Harm_Power[i][j].S = IntToFloat(SrcData.Harm_Power[i][j].S) * fPT * fCT; } } // 谐波相关数据 for (int i = 0; i < 6; i++) { UU_Deviation[i] = IntToFloat(SrcData.UU_Deviation[i]); UL_Deviation[i] = IntToFloat(SrcData.UL_Deviation[i]); Harm_Aberrance[i] = ShorToFloat100(SrcData.Harm_Aberrance[i]); for (int j = 0; j < HARMNUM; j++) { if (i < 3) { // 电压谐波 FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]) * fPT; } else { // 电流谐波 FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]) * fCT; } FuHarmPhase[i][j] = IntToFloat(SrcData.FuHarmPhase[i][j]); InHarm[i][j].Val = IntToFloat(SrcData.InHarm[i][j].Val); Harm_Contain[i][j] = ShorToFloat100(SrcData.Harm_Contain[i][j]); } } // RMS值 for (int i = 0; i < 9; i++) { if (i > 2 && i < 6) { // 电流 (索引3,4,5) Rms[i] = IntToFloat(SrcData.Rms[i]) * fCT; } else { // 电压和其他 Rms[i] = IntToFloat(SrcData.Rms[i]) * fPT; } } } // 将浮点字段转换为Base64字符串 std::string ConvertToBase64() const { // 1. 计算总浮点数 const size_t total_floats = CalculateFloatCount(); // 2. 创建缓冲区并填充数据 std::vector float_buffer; float_buffer.reserve(total_floats); SerializeFloats(float_buffer); // 3. 将浮点缓冲区转换为字节数据 const size_t byte_size = float_buffer.size() * sizeof(float); const unsigned char* byte_data = reinterpret_cast(float_buffer.data()); // 4. Base64编码 return base64_encode(byte_data, byte_size); } // 计算浮点字段总数 size_t CalculateFloatCount() const { size_t count = 0; // 基本数组 count += Rms.size(); count += UU_Deviation.size(); count += UL_Deviation.size(); count += F_Deviation.size(); // 二维数组 for (const auto& arr : UI_Seq) count += arr.size(); for (const auto& arr : FuHarm) count += arr.size(); for (const auto& arr : FuHarmPhase) count += arr.size(); // 嵌套结构数组 for (const auto& arr : InHarm) { for (const auto& item : arr) { count += 2; // 每个tagInHarmData_float包含2个float } } // 功率数组 for (const auto& arr : Total_Power) count += arr.size(); for (const auto& arr : Harm_Power) { for (const auto& item : arr) { count += 3; // 每个tagPowerData_float包含3个float } } // 其他数组 for (const auto& arr : Harm_Contain) count += arr.size(); count += Harm_Aberrance.size(); count += Cos_PF.size(); count += Cos_DF.size(); count += U_Fluctuation.size(); count += U_Flicker.size(); count += UL_Flicker.size(); return count; } //角型接线转换 std::string ConvertToBase64_Delta() const { std::vector float_buffer; // 0-8位从Rms取0-8 for (int i = 0; i < 9; ++i) { float_buffer.push_back(Rms[i]); } // 9-11位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 12-14位从UU_Deviation和UL_Deviation各自取前三个,取不为0的值 for (int i = 0; i < 3; ++i) { float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i]; float_buffer.push_back(val); } // 15-16位从F_Deviation中取0-1 for (int i = 0; i < 2; ++i) { float_buffer.push_back(F_Deviation[i]); } // 再后8位从UI_Seq取0-7 for (int i = 0; i < 2; ++i) { for (int j = 0; j < 4; ++j) { if (i * 4 + j < 8) { // 只取前8个 float_buffer.push_back(UI_Seq[i][j]); } } } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后49位从FuHarm的3中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[3][i]); } // 再后49位从FuHarm的4中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[4][i]); } // 再后49位从FuHarm的5中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[5][i]); } // 再后49*3位从FuHarm的0-2中取1-49位 for (int j = 0; j < 3; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[j][i]); } } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后49*3位依次从FuHarmPhase的3-5中取1-49位 for (int j = 3; j < 6; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarmPhase[j][i]); } } // 再后49*3位依次从FuHarmPhase的0-2中取1-49位 for (int j = 0; j < 3; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarmPhase[j][i]); } } // 再后50*3位置位3.1415表示空置 for (int i = 0; i < 50 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后50*3位依次从InHarm的3-5中取0-49位中的val指标 for (int j = 3; j < 6; ++j) { for (int i = 0; i < HARMNUM; ++i) { float_buffer.push_back(InHarm[j][i].Val); } } // 再后50*3位依次从InHarm的0-2中取0-49位中的val指标 for (int j = 0; j < 3; ++j) { for (int i = 0; i < HARMNUM; ++i) { float_buffer.push_back(InHarm[j][i].Val); } } // 再后12位依次从Total_Power的0-3中取0-2位 for (int j = 0; j < 4; ++j) { for (int i = 0; i < 3; ++i) { float_buffer.push_back(Total_Power[j][i]); } } // 再后49位从Harm_Power中取0的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].P); } // 再后49位从Harm_Power中取0的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].Q); } // 再后49位从Harm_Power中取0的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].S); } // 再后49位从Harm_Power中取1的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].P); } // 再后49位从Harm_Power中取1的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].Q); } // 再后49位从Harm_Power中取1的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].S); } // 再后49位从Harm_Power中取2的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].P); } // 再后49位从Harm_Power中取2的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].Q); } // 再后49位从Harm_Power中取2的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].S); } // 再后49位从Harm_Power中取3的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].P); } // 再后49位从Harm_Power中取3的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].Q); } // 再后49位从Harm_Power中取3的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].S); } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后49*3位从Harm_Contain中的3-5中取1-49位 for (int j = 3; j < 6; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Contain[j][i]); } } // 再后49*3位从Harm_Contain中的0-2中取1-49位 for (int j = 0; j < 3; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Contain[j][i]); } } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从Harm_Aberrance中的3-5中取值 for (int i = 3; i < 6; ++i) { float_buffer.push_back(Harm_Aberrance[i]); } // 再后3位从Harm_Aberrance中的0-2中取值 for (int i = 0; i < 3; ++i) { float_buffer.push_back(Harm_Aberrance[i]); } // 再后4位从Cos_PF中取0-3 for (int i = 0; i < 4; ++i) { float_buffer.push_back(Cos_PF[i]); } // 再后4位从Cos_DF中取0-3 for (int i = 0; i < 4; ++i) { float_buffer.push_back(Cos_DF[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从U_Fluctuation中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(U_Fluctuation[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从U_Flicker中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(U_Flicker[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从UL_Flicker中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(UL_Flicker[i]); } // 转换为Base64 const size_t byte_size = float_buffer.size() * sizeof(float); const unsigned char* byte_data = reinterpret_cast(float_buffer.data()); return base64_encode(byte_data, byte_size); } //星型接线转换 std::string ConvertToBase64_Star() const { std::vector float_buffer; // 0-8位从Rms取0-8 for (int i = 0; i < 9; ++i) { float_buffer.push_back(Rms[i]); } // 9-11位从UU_Deviation和UL_Deviation各自取前三个,取不为0的值 for (int i = 0; i < 3; ++i) { float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i]; float_buffer.push_back(val); } // 12-14位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 15-16位从F_Deviation中取0-1 for (int i = 0; i < 2; ++i) { float_buffer.push_back(F_Deviation[i]); } // 再后8位从UI_Seq取0-7 for (int i = 0; i < 2; ++i) { for (int j = 0; j < 4; ++j) { if (i * 4 + j < 8) { // 只取前8个 float_buffer.push_back(UI_Seq[i][j]); } } } // 再后49位从FuHarm的0中取1-49位 (注意数组从0开始) for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[0][i]); } // 再后49位从FuHarm的1中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[1][i]); } // 再后49位从FuHarm的2中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[2][i]); } // 再后49位从FuHarm的3中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[3][i]); } // 再后49位从FuHarm的4中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[4][i]); } // 再后49位从FuHarm的5中取1-49位 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarm[5][i]); } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后49*3位依次从FuHarmPhase的0-2中取1-49位 for (int j = 0; j < 3; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarmPhase[j][i]); } } // 再后49*3位依次从FuHarmPhase的3-5中取1-49位 for (int j = 3; j < 6; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(FuHarmPhase[j][i]); } } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后50*6位依次从InHarm的0-5中取0-49位中的val指标 for (int j = 0; j < 6; ++j) { for (int i = 0; i < HARMNUM; ++i) { float_buffer.push_back(InHarm[j][i].Val); } } // 再后50*3位置位3.1415表示空置 for (int i = 0; i < 50 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后12位依次从Total_Power的0-3中取0-2位 for (int j = 0; j < 4; ++j) { for (int i = 0; i < 3; ++i) { float_buffer.push_back(Total_Power[j][i]); } } // 再后49位从Harm_Power中取0的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].P); } // 再后49位从Harm_Power中取0的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].Q); } // 再后49位从Harm_Power中取0的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[0][i].S); } // 再后49位从Harm_Power中取1的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].P); } // 再后49位从Harm_Power中取1的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].Q); } // 再后49位从Harm_Power中取1的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[1][i].S); } // 再后49位从Harm_Power中取2的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].P); } // 再后49位从Harm_Power中取2的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].Q); } // 再后49位从Harm_Power中取2的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[2][i].S); } // 再后49位从Harm_Power中取3的1-49中的P值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].P); } // 再后49位从Harm_Power中取3的1-49中的Q值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].Q); } // 再后49位从Harm_Power中取3的1-49中的S值 for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Power[3][i].S); } // 再后49*6位从Harm_Contain中的0-5中取1-49位 for (int j = 0; j < 6; ++j) { for (int i = 1; i < HARMNUM; ++i) { float_buffer.push_back(Harm_Contain[j][i]); } } // 再后49*3位置位3.1415表示空置 for (int i = 0; i < 49 * 3; ++i) { float_buffer.push_back(3.14159f); } // 再后6位从Harm_Aberrance中的0-5中取值 for (int i = 0; i < 6; ++i) { float_buffer.push_back(Harm_Aberrance[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后4位从Cos_PF中取0-3 for (int i = 0; i < 4; ++i) { float_buffer.push_back(Cos_PF[i]); } // 再后4位从Cos_DF中取0-3 for (int i = 0; i < 4; ++i) { float_buffer.push_back(Cos_DF[i]); } // 再后3位从U_Fluctuation中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(U_Fluctuation[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从U_Flicker中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(U_Flicker[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 再后3位从UL_Flicker中取0-2 for (int i = 0; i < 3; ++i) { float_buffer.push_back(UL_Flicker[i]); } // 再后3位置位3.1415表示空置 for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 转换为Base64 const size_t byte_size = float_buffer.size() * sizeof(float); const unsigned char* byte_data = reinterpret_cast(float_buffer.data()); return base64_encode(byte_data, byte_size); } //传入接线方式选择转换方式 std::string ConvertToBase64(int type) const { //1为角型接线,不符合则默认走星型转换逻辑 if (type == 1) { return ConvertToBase64_Delta(); } else { return ConvertToBase64_Star(); } } private: // 序列化浮点数据到缓冲区 void SerializeFloats(std::vector& buffer) const { // 基本数组 for (const auto& val : Rms) buffer.push_back(val); for (const auto& val : UU_Deviation) buffer.push_back(val); for (const auto& val : UL_Deviation) buffer.push_back(val); for (const auto& val : F_Deviation) buffer.push_back(val); // 二维数组 for (const auto& arr : UI_Seq) { for (const auto& val : arr) buffer.push_back(val); } for (const auto& arr : FuHarm) { for (const auto& val : arr) buffer.push_back(val); } for (const auto& arr : FuHarmPhase) { for (const auto& val : arr) buffer.push_back(val); } // 嵌套结构数组 for (const auto& arr : InHarm) { for (const auto& item : arr) { buffer.push_back(item.Val); buffer.push_back(item.f); } } // 功率数组 for (const auto& arr : Total_Power) { for (const auto& val : arr) buffer.push_back(val); } for (const auto& arr : Harm_Power) { for (const auto& item : arr) { buffer.push_back(item.P); buffer.push_back(item.Q); buffer.push_back(item.S); } } // 其他数组 for (const auto& arr : Harm_Contain) { for (const auto& val : arr) buffer.push_back(val); } for (const auto& val : Harm_Aberrance) buffer.push_back(val); for (const auto& val : Cos_PF) buffer.push_back(val); for (const auto& val : Cos_DF) buffer.push_back(val); for (const auto& val : U_Fluctuation) buffer.push_back(val); for (const auto& val : U_Flicker) buffer.push_back(val); for (const auto& val : UL_Flicker) buffer.push_back(val); } // Base64编码函数 static std::string base64_encode(const unsigned char* bytes_to_encode, size_t in_len) { static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (i = 0; i < 4; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for (j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; j < i + 1; j++) ret += base64_chars[char_array_4[j]]; while (i++ < 3) ret += '='; } return ret; } }; //计算报文帧长度 1帧1024为1K 统计数据相关 constexpr int PqDataLen = tagPqData::GetSize(); constexpr int Stat_PacketNum = (PqDataLen / 1024 > 0) ? (PqDataLen / 1024 + 1) : (PqDataLen / 1024); //实时数据结构(1字节对齐) #pragma pack(push, 1) class RealtagPqDate_float { public: tagTime time; // 时间 //实时数据各浮点数组 std::array Rms; //相电压、线电压、电流有效值 std::array UU_Deviation; //相电压、线电压上偏差 std::array UL_Deviation; //相电压、线电压下偏差 std::array THD; //电压电流畸变率 std::array FREQ; //频率及频率偏差 std::array, 2> UI_Seq;//电压电流序分量及不平衡度 std::array, 4> TOTAL_POWER;//分相及总功率P、Q、S std::array COS_PF; //视在功率因数 std::array COS_DF; //位移功率因数 //----------- 报文一包含时间和以上数据 std::array, 3> HARMV;//谐波电压含有率 //----------- 报文二包含时间和以上数据 std::array, 3> HARMI;//谐波电流幅值 //----------- 报文三包含时间和以上数据 std::array, 3> HARMVP;//谐波电压相位 //----------- 报文四包含时间和以上数据 std::array, 3> HARMIP;//谐波电流相位 //----------- 报文五包含时间和以上数据 std::array, 3> INHARMV;//间谐波电压幅值 //----------- 报文六包含时间和以上数据 // 构造函数 - 初始化所有数据 RealtagPqDate_float() { // 初始化时间 time = tagTime(); // 调用tagTime的默认构造函数 // 初始化基本数组 Rms.fill(0.0f); UU_Deviation.fill(0.0f); UL_Deviation.fill(0.0f); THD.fill(0.0f); FREQ.fill(0.0f); COS_PF.fill(0.0f); COS_DF.fill(0.0f); // 初始化二维数组 for (auto& arr : UI_Seq) { arr.fill(0.0f); } for (auto& arr : TOTAL_POWER) { arr.fill(0.0f); } // 初始化谐波相关数组 for (auto& arr : HARMV) { arr.fill(0.0f); } for (auto& arr : HARMI) { arr.fill(0.0f); } for (auto& arr : HARMVP) { arr.fill(0.0f); } for (auto& arr : HARMIP) { arr.fill(0.0f); } for (auto& arr : INHARMV) { arr.fill(0.0f); } } // 辅助函数:从网络字节序读取float float read_net_float(const uint8_t* ptr) { uint32_t temp; memcpy(&temp, ptr, sizeof(uint32_t)); temp = ntohl(temp); float result; memcpy(&result, &temp, sizeof(float)); return result; } // 实时数据结构的分包解析方法 bool ParsePacket1(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 后续数据(59个float * 4 = 236字节) = 248字节 const size_t min_size = tagTime::GetSize() + 59 * sizeof(float); if (size < min_size) { return false; } // 解析时间 if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析Rms (9个float) for (int i = 0; i < 9; ++i) { Rms[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析UU_Deviation (6个float) for (int i = 0; i < 6; ++i) { UU_Deviation[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析UL_Deviation (6个float) for (int i = 0; i < 6; ++i) { UL_Deviation[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析THD (6个float) for (int i = 0; i < 6; ++i) { THD[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析FREQ (2个float) for (int i = 0; i < 2; ++i) { FREQ[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析UI_Seq (2x5个float) for (int i = 0; i < 2; ++i) { for (int j = 0; j < 5; ++j) { UI_Seq[i][j] = read_net_float(ptr); ptr += sizeof(float); } } // 解析TOTAL_POWER (4x3个float) for (int i = 0; i < 4; ++i) { for (int j = 0; j < 3; ++j) { TOTAL_POWER[i][j] = read_net_float(ptr); ptr += sizeof(float); } } // 解析COS_PF (4个float) for (int i = 0; i < 4; ++i) { COS_PF[i] = read_net_float(ptr); ptr += sizeof(float); } // 解析COS_DF (4个float) for (int i = 0; i < 4; ++i) { COS_DF[i] = read_net_float(ptr); ptr += sizeof(float); } return true; } bool ParsePacket2(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 谐波电压(150个float * 4 = 600字节) = 612字节 const size_t min_size = tagTime::GetSize() + 3 * HARMNUM * sizeof(float); if (size < min_size) { return false; } // 解析时间(覆盖之前的时间) if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析HARMV (3xHARMNUM个float) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { HARMV[i][j] = read_net_float(ptr); ptr += sizeof(float); } } return true; } bool ParsePacket3(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 谐波电流(150个float * 4 = 600字节) = 612字节 const size_t min_size = tagTime::GetSize() + 3 * HARMNUM * sizeof(float); if (size < min_size) { return false; } if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析HARMI (3xHARMNUM个float) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { HARMI[i][j] = read_net_float(ptr); ptr += sizeof(float); } } return true; } bool ParsePacket4(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 谐波电压相位(150个float * 4 = 600字节) = 612字节 const size_t min_size = tagTime::GetSize() + 3 * HARMNUM * sizeof(float); if (size < min_size) { return false; } if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析HARMVP (3xHARMNUM个float) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { HARMVP[i][j] = read_net_float(ptr); ptr += sizeof(float); } } return true; } bool ParsePacket5(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 谐波电流相位(150个float * 4 = 600字节) = 612字节 const size_t min_size = tagTime::GetSize() + 3 * HARMNUM * sizeof(float); if (size < min_size) { return false; } if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析HARMIP (3xHARMNUM个float) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { HARMIP[i][j] = read_net_float(ptr); ptr += sizeof(float); } } return true; } bool ParsePacket6(const uint8_t* data, size_t size) { // 最小长度 = 时间(12字节) + 间谐波电压(150个float * 4 = 600字节) = 612字节 const size_t min_size = tagTime::GetSize() + 3 * HARMNUM * sizeof(float); if (size < min_size) { return false; } if (!time.SetStructBuf(data, size)) { return false; } const uint8_t* ptr = data + tagTime::GetSize(); // 解析INHARMV (3xHARMNUM个float) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { INHARMV[i][j] = read_net_float(ptr); ptr += sizeof(float); } } return true; } // 计算浮点字段总数 size_t CalculateFloatCount() const { size_t count = 0; // 基本数组 count += Rms.size(); count += UU_Deviation.size(); count += UL_Deviation.size(); count += THD.size(); count += FREQ.size(); count += COS_PF.size(); count += COS_DF.size(); // 二维数组 for (const auto& arr : UI_Seq) count += arr.size(); for (const auto& arr : TOTAL_POWER) count += arr.size(); for (const auto& arr : HARMV) count += arr.size(); for (const auto& arr : HARMI) count += arr.size(); for (const auto& arr : HARMVP) count += arr.size(); for (const auto& arr : HARMIP) count += arr.size(); for (const auto& arr : INHARMV) count += arr.size(); return count; } // 序列化浮点数据到缓冲区 void SerializeFloats(std::vector& buffer) const { // 基本数组 for (float val : Rms) buffer.push_back(val); for (float val : UU_Deviation) buffer.push_back(val); for (float val : UL_Deviation) buffer.push_back(val); for (float val : THD) buffer.push_back(val); for (float val : FREQ) buffer.push_back(val); // 二维数组(电压电流序) for (const auto& arr : UI_Seq) { for (float val : arr) buffer.push_back(val); } // 功率数组 for (const auto& arr : TOTAL_POWER) { for (float val : arr) buffer.push_back(val); } // 功率因数 for (float val : COS_PF) buffer.push_back(val); for (float val : COS_DF) buffer.push_back(val); // 谐波相关数组 for (const auto& arr : HARMV) { for (float val : arr) buffer.push_back(val); } for (const auto& arr : HARMI) { for (float val : arr) buffer.push_back(val); } for (const auto& arr : HARMVP) { for (float val : arr) buffer.push_back(val); } for (const auto& arr : HARMIP) { for (float val : arr) buffer.push_back(val); } for (const auto& arr : INHARMV) { for (float val : arr) buffer.push_back(val); } } // Base64编码函数(与tagPqData_Float相同) static std::string base64_encode(const unsigned char* bytes_to_encode, size_t in_len) { static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (i = 0; i < 4; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for (j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; j < i + 1; j++) ret += base64_chars[char_array_4[j]]; while (i++ < 3) ret += '='; } return ret; } // 新增Base64转换方法 std::string ConvertToBase64() const { // 1. 计算总浮点数 const size_t total_floats = CalculateFloatCount(); // 2. 创建缓冲区并填充数据 std::vector float_buffer; float_buffer.reserve(total_floats); SerializeFloats(float_buffer); // 3. 转换为字节数据并编码 const size_t byte_size = float_buffer.size() * sizeof(float); const unsigned char* byte_data = reinterpret_cast(float_buffer.data()); return base64_encode(byte_data, byte_size); } std::string floatVectorToBase64(const std::vector& float_buffer) const { const size_t byte_size = float_buffer.size() * sizeof(float); const unsigned char* byte_data = reinterpret_cast(float_buffer.data()); return base64_encode(byte_data, byte_size); } // 星型接线转换函数 std::string ConvertToBase64_Star() const { std::vector float_buffer; // 0-8: RMS值 for (int i = 0; i < 9; ++i) { float_buffer.push_back(Rms[i]); } // 9-11: 电压偏差(取不为0的值) for (int i = 0; i < 3; ++i) { float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i]; float_buffer.push_back(val); } // 12-14: 空置(线电压位置) for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 15-20: THD总畸变率(0-5) for (int i = 0; i < 6; ++i) { float_buffer.push_back(THD[i]); } // 21-23: 空置(线电压THD) for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 24-25: 频率及偏差 for (int i = 0; i < 2; ++i) { float_buffer.push_back(FREQ[i]); } // 26-33: 电压电流序分量(前8个元素) for (int i = 0; i < 2; ++i) { for (int j = 0; j < 4; ++j) { // 取每行的前4个元素 float_buffer.push_back(UI_Seq[i][j]); } } // 34-45: 总功率 for (int i = 0; i < 4; ++i) { for (int j = 0; j < 3; ++j) { float_buffer.push_back(TOTAL_POWER[i][j]); } } // 46-49: 视在功率因数 for (int i = 0; i < 4; ++i) { float_buffer.push_back(COS_PF[i]); } // 50-53: 位移功率因数 for (int i = 0; i < 4; ++i) { float_buffer.push_back(COS_DF[i]); } // 54-200: 电压谐波含有率(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMV[i][j]); } } // 201-347: 空置(线电压谐波) for (int i = 0; i < 3 * 49; ++i) { float_buffer.push_back(3.14159f); } // 348-494: 电流谐波幅值(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMI[i][j]); } } // 495-641: 电压谐波相位(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMVP[i][j]); } } // 642-788: 空置(线电压谐波相位) for (int i = 0; i < 3 * 49; ++i) { float_buffer.push_back(3.14159f); } // 789-935: 电流谐波相位(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMIP[i][j]); } } // 936-1085: 电压间谐波幅值(0-49次) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { float_buffer.push_back(INHARMV[i][j]); } } // 1086-1235: 空置(线电压间谐波) for (int i = 0; i < 3 * 50; ++i) { float_buffer.push_back(3.14159f); } // 转换为Base64 return floatVectorToBase64(float_buffer); } // 角型接线转换函数 std::string ConvertToBase64_Delta() const { std::vector float_buffer; // 0-8: RMS值 for (int i = 0; i < 9; ++i) { float_buffer.push_back(Rms[i]); } // 9-11: 空置(相电压位置) for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 12-14: 电压偏差(取不为0的值) for (int i = 0; i < 3; ++i) { float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i]; float_buffer.push_back(val); } // 15-17: 空置(相电压THD) for (int i = 0; i < 3; ++i) { float_buffer.push_back(3.14159f); } // 18-20: THD线电压畸变率(3-5) for (int i = 3; i < 6; ++i) { float_buffer.push_back(THD[i]); } // 21-23: THD相电压畸变率(0-2) for (int i = 0; i < 3; ++i) { float_buffer.push_back(THD[i]); } // 24-25: 频率及偏差 for (int i = 0; i < 2; ++i) { float_buffer.push_back(FREQ[i]); } // 26-33: 电压电流序分量(前8个元素) for (int i = 0; i < 2; ++i) { for (int j = 0; j < 4; ++j) { float_buffer.push_back(UI_Seq[i][j]); } } // 34-45: 总功率 for (int i = 0; i < 4; ++i) { for (int j = 0; j < 3; ++j) { float_buffer.push_back(TOTAL_POWER[i][j]); } } // 46-49: 视在功率因数 for (int i = 0; i < 4; ++i) { float_buffer.push_back(COS_PF[i]); } // 50-53: 位移功率因数 for (int i = 0; i < 4; ++i) { float_buffer.push_back(COS_DF[i]); } // 54-200: 空置(相电压谐波) for (int i = 0; i < 3 * 49; ++i) { float_buffer.push_back(3.14159f); } // 201-347: 电压谐波含有率(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMV[i][j]); } } // 348-494: 电流谐波幅值(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMI[i][j]); } } // 495-641: 空置(相电压谐波相位) for (int i = 0; i < 3 * 49; ++i) { float_buffer.push_back(3.14159f); } // 642-788: 电压谐波相位(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMVP[i][j]); } } // 789-935: 电流谐波相位(1-49次) for (int i = 0; i < 3; ++i) { for (int j = 1; j < HARMNUM; ++j) { float_buffer.push_back(HARMIP[i][j]); } } // 936-1085: 空置(线电压间谐波) for (int i = 0; i < 3 * 50; ++i) { float_buffer.push_back(3.14159f); } // 1086-1235: 电压间谐波幅值(0-49次) for (int i = 0; i < 3; ++i) { for (int j = 0; j < HARMNUM; ++j) { float_buffer.push_back(INHARMV[i][j]); } } // 转换为Base64 return floatVectorToBase64(float_buffer); } // 根据接线方式选择转换方法 std::string ConvertToBase64(int wiringType) const { // 1为角型接线,其他为星型接线 if (wiringType == 1) { return ConvertToBase64_Delta(); } else { return ConvertToBase64_Star(); } } }; #pragma pack(pop) //暂态相关结构------------------------------ #pragma pack(push, 1) // 时间结构体 struct TagMsTime { uint16_t Year; uint16_t Month; uint16_t Day; uint16_t Hour; uint16_t Min; uint16_t Sec; uint16_t Ms; void convertByteOrder() { Year = ntohs(Year); Month = ntohs(Month); Day = ntohs(Day); Hour = ntohs(Hour); Min = ntohs(Min); Sec = ntohs(Sec); Ms = ntohs(Ms); } }; // 告警事件头结构 struct NewHeadTaglogbuffer { uint16_t name; // 监测点序号 TagMsTime Devtime; // 绝对时间 uint16_t LogType; // 日志类型 uint16_t LogCode; // 日志代码 uint16_t LogLb; // 日志录波 uint16_t LogBackup; // 日志补零位 uint32_t LogParaNum; // 日志参数项数 void convertByteOrder() { name = ntohs(name); Devtime.convertByteOrder(); LogType = ntohs(LogType); LogCode = ntohs(LogCode); LogLb = ntohs(LogLb); LogBackup = ntohs(LogBackup); LogParaNum = ntohl(LogParaNum); } }; // 告警事件身体结构 struct NewBodyTaglogbuffer { uint32_t ParaCode; // 参数编码 uint32_t ParaValue; // 参数值 void convertByteOrder() { ParaCode = ntohl(ParaCode); ParaValue = ntohl(ParaValue); } }; // 告警事件完整结构 class NewTaglogbuffer { public: NewHeadTaglogbuffer head; std::vector bodyList; // 从字节流解析数据 void parseFromData(const uint8_t* data, size_t data_size) { // 解析头部 if (data_size < sizeof(NewHeadTaglogbuffer)) { throw std::runtime_error("Insufficient data for header"); } memcpy(&head, data, sizeof(NewHeadTaglogbuffer)); head.convertByteOrder(); // 解析身体部分 const size_t body_start = sizeof(NewHeadTaglogbuffer); const size_t body_size = head.LogParaNum * sizeof(NewBodyTaglogbuffer); if (data_size < body_start + body_size) { throw std::runtime_error("Insufficient data for body"); } bodyList.resize(head.LogParaNum); const uint8_t* body_data = data + body_start; for (uint32_t i = 0; i < head.LogParaNum; ++i) { memcpy(&bodyList[i], body_data, sizeof(NewBodyTaglogbuffer)); bodyList[i].convertByteOrder(); body_data += sizeof(NewBodyTaglogbuffer); } } // 创建对象的方法(类似C#的工厂方法) static NewTaglogbuffer createFromData(const uint8_t* data, size_t data_size) { NewTaglogbuffer result; result.parseFromData(data, data_size); return result; } }; #pragma pack(pop) // 定义QVVRRecord结构体 struct QVVRRecord { uint64_t triggerTimeMs; // 毫秒时间戳(UTC,从1970-01-01 00:00:00开始) int nType = 0; // 事件类型:0-未知 1-暂降 2-暂升 3-中断 4-瞬态 float fPersisstime = 0.0f; // 持续时间(秒) float fMagntitude = 0.0f; // 特征幅值(标幺值) float phase = 0.0f; // 相别(瞬态使用)0-A 1-B 2-C 3-AB 4-BC 5-CA ?-ABC float transientValue = 0.0f;// 瞬变幅度(瞬态使用) }; // 解析日志生成QVVRRecord QVVRRecord DynamicLog_GetQVVRRecordFromLogBuffer(const std::string& strScale, uint32_t nPTType, float fPT, const NewTaglogbuffer& log); //暂态相关结构------------------------------- // 定义目录信息结构体 (1字节对齐) #pragma pack(push, 1) struct tag_dir_info { int32_t flag; // 0-目录,1-文件 char name[64]; // 文件名/目录名 uint32_t size; // 文件大小 }; #pragma pack(pop) // 定值描述文件 struct DZ_TAB_STRUCT { short LN_Num; // 监测点 short DZ_Num; // 序号 char DZ_Name[66]; // 名称 short DZ_Type; // 定值类型 float DZ_Min; // 最小值 float DZ_Max; // 最大值 float DZ_Default; // 缺省值 char DZ_UNIT[10]; // 量纲 }; // 控制字描述结构体定义 #pragma pack(push, 1) // 确保内存紧凑布局 struct DZ_kzz_bit { char kzz_bit[40]; // 名称,固定40字节 char bit_enable; // 是否使用标志(1字节) }; #pragma pack(pop) // 恢复默认对齐 // 单个内部定值描述结构体 struct NameFixValue { char uNumber; // 序号 char sFixValueName[20]; // 名称 (固定20字节) char uBY; // 备用 uint16_t DataType; // 数据类型 uint16_t MinValue; // 最小值 uint16_t MaxValue; // 最大值 uint16_t DefaultValue; // 缺省值 char sDimension[4]; // 单位 (固定4字节) }; // 字节序转换函数 void ReversalBuff(uint8_t* buff, int start, int length); // 生成带协议头的二进制报文 std::vector generate_binary_message( uint16_t msg_type, const std::vector& payload); // 生成装置云服务登录报文 std::vector generate_frontlogin_message(const std::string& strMac); //生成询问统计数据时间报文 std::vector generate_statequerytime_message(); //生成询问统计数据报文 std::vector generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType); //生成询问实时数据报文 std::vector generate_realstat_message(unsigned char nCpuNo, unsigned char StaTtype, unsigned char flag); //生成文件下载请求报文 当前帧序号+文件名 std::vector generate_downloadfile_message(int frameIndex, const std::string& fileName); //文件目录读取报文 传入需要读取的文件路径 std::vector generate_getfilemenu_message(const std::string& filedir); // 请求定值报文 传入测点号 std::vector generate_requestFixValue_message(unsigned char nCpuNo); // 请求定值描述报文 std::vector generate_requestFixDes_message(); // 设置定值报文 传入测点号+修改的定值数据队列 std::vector generate_requestSetFixValue_message(unsigned char nCpuNo, const std::vector& value); /** * @brief 生成请求装置内部定值的报文 * @return 包含完整报文的字节向量 */ std::vector generate_requestinterfixvalue_message(); /** * @brief 生成请求装置内部定值描述的报文 * @param nDesCW 描述类型 (1-内部定值描述, 2-控制字描述) * @return 包含完整报文的字节向量,参数无效时返回空向量 */ std::vector generate_requestinterfixdes_message(unsigned char nDesCW); /** * @brief 生成设置装置内部定值的报文 * @param values 要设置的定值数组 (ushort值) * @return 包含完整报文的字节向量 */ std::vector generate_requestsetinterfixvalue_message(const std::vector& values); std::vector generate_requestsetinterfixvalue_message_new(const std::vector& value); /** * @brief 生成装置运行信息读取指令报文 * @return 包含完整报文的字节向量 */ std::vector generate_machinestatus_message(); /** * @brief 生成装置版本配置信息读取指令报文 * @return 包含完整报文的字节向量 */ std::vector generate_machineversion_message(); /** * @brief 生成设置装置对时的报文 * @param time 下发的对时时间 (tm值) * @return 包含完整报文的字节向量 */ std::vector generate_righttime_message(const std::tm& time); /** * @brief 生成暂降事件补招报文 * @param Time1 起始时间 * @param Time2 结束时间 * @param eventType 事件类型,默认2-暂态事件 4-告警时间 * @param monitorPoint 监测点,默认1-监测点1 1-6 对应测点 * @return 包含完整报文的字节向量 */ std::vector generate_recallevent_message(const std::tm& Time1, const std::tm& Time2, uint8_t eventType = 2, uint8_t monitorPoint = 1);