Files
front_linux/LFtid1056/PQSMsg.h

2182 lines
67 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <vector>
#include <cstdint>
#include <cstring>
#include <string>
#include <stdexcept>
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <arpa/inet.h> // 字节序转换
#include <array>
#include <cmath>
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
};
// 接收报文功能码枚举
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_NewACK = 0x40,
//默认否定应答
Response_NewNACK = 0x41
};
//基础消息结构
class MessageParser {
public:
// 成员变量
uint8_t msgType; //功能码
std::vector<uint8_t> 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<uint16_t>(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<uint16_t>(dt.tm_year + 1900)),
DeviceMonth(static_cast<uint16_t>(dt.tm_mon + 1)),
DeviceDay(static_cast<uint16_t>(dt.tm_mday)),
DeviceHour(static_cast<uint16_t>(dt.tm_hour)),
DeviceMinute(static_cast<uint16_t>(dt.tm_min)),
DeviceSecond(static_cast<uint16_t>(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<const uint16_t*>(ptr));
ptr += sizeof(uint16_t);
DeviceMonth = ntohs(*reinterpret_cast<const uint16_t*>(ptr));
ptr += sizeof(uint16_t);
DeviceDay = ntohs(*reinterpret_cast<const uint16_t*>(ptr));
ptr += sizeof(uint16_t);
DeviceHour = ntohs(*reinterpret_cast<const uint16_t*>(ptr));
ptr += sizeof(uint16_t);
DeviceMinute = ntohs(*reinterpret_cast<const uint16_t*>(ptr));
ptr += sizeof(uint16_t);
DeviceSecond = ntohs(*reinterpret_cast<const uint16_t*>(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<uint16_t*>(ptr) = htons(DeviceYear);
ptr += sizeof(uint16_t);
*reinterpret_cast<uint16_t*>(ptr) = htons(DeviceMonth);
ptr += sizeof(uint16_t);
*reinterpret_cast<uint16_t*>(ptr) = htons(DeviceDay);
ptr += sizeof(uint16_t);
*reinterpret_cast<uint16_t*>(ptr) = htons(DeviceHour);
ptr += sizeof(uint16_t);
*reinterpret_cast<uint16_t*>(ptr) = htons(DeviceMinute);
ptr += sizeof(uint16_t);
*reinterpret_cast<uint16_t*>(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<const int32_t*>(ptr));
ptr += sizeof(int32_t);
f = ntohl(*reinterpret_cast<const int32_t*>(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<const int32_t*>(ptr));
ptr += sizeof(int32_t);
Q = ntohl(*reinterpret_cast<const int32_t*>(ptr));
ptr += sizeof(int32_t);
S = ntohl(*reinterpret_cast<const int32_t*>(ptr));
return true;
}
};
// 主数据结构 (使用1字节对齐)
#pragma pack(push, 1)
class tagPqData {
public:
int16_t name; // 监测点号
int16_t Data_Type; // 数据类型
tagTime time; // 时间
// 各种数据数组
std::array<int32_t, 9> Rms; // 电压/电流有效值
std::array<int32_t, 6> UU_Deviation; // 电压上偏差
std::array<int32_t, 6> UL_Deviation; // 电压下偏差
std::array<int32_t, 2> F_Deviation; // 频率偏差
std::array<std::array<int32_t, 4>, 2> UI_Seq; // 电压电流序量
std::array<std::array<int32_t, HARMNUM>, 6> FuHarm; // 整次谐波
std::array<std::array<int32_t, HARMNUM>, 6> FuHarmPhase; // 谐波相角
std::array<std::array<tagInHarmData, HARMNUM>, 6> InHarm; // 间谐波
std::array<std::array<int32_t, 3>, 4> Total_Power; // 总功率
std::array<std::array<tagPowerData, HARMNUM>, 4> Harm_Power; // 谐波功率
std::array<std::array<int16_t, HARMNUM>, 6> Harm_Contain; // 谐波含有率
std::array<int16_t, 6> Harm_Aberrance; // 谐波畸变率
std::array<int16_t, 4> Cos_PF; // 视在功率因数
std::array<int16_t, 4> Cos_DF; // 位移功率因数
std::array<int16_t, 3> U_Fluctuation; // 电压波动
std::array<int16_t, 3> U_Flicker; // 电压闪变
std::array<int16_t, 3> 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<const int16_t*>(ptr));
ptr += sizeof(name);
remaining -= sizeof(name);
Data_Type = ntohs(*reinterpret_cast<const int16_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int32_t*>(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<const int16_t*>(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<const int16_t*>(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<const int16_t*>(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<const int16_t*>(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<const int16_t*>(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<const int16_t*>(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<const int16_t*>(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<float, 9> Rms;
std::array<float, 6> UU_Deviation;
std::array<float, 6> UL_Deviation;
std::array<float, 2> F_Deviation;
std::array<std::array<float, 4>, 2> UI_Seq;
std::array<std::array<float, HARMNUM>, 6> FuHarm;
std::array<std::array<float, HARMNUM>, 6> FuHarmPhase;
std::array<std::array<tagInHarmData_float, HARMNUM>, 6> InHarm;
std::array<std::array<float, 3>, 4> Total_Power;
std::array<std::array<tagPowerData_float, HARMNUM>, 4> Harm_Power;
std::array<std::array<float, HARMNUM>, 6> Harm_Contain;
std::array<float, 6> Harm_Aberrance; // 注意C#中是8元素
std::array<float, 4> Cos_PF;
std::array<float, 4> Cos_DF;
std::array<float, 3> U_Fluctuation;
std::array<float, 3> U_Flicker;
std::array<float, 3> 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> 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<const unsigned char*>(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> 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.1415f);
}
// 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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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<const unsigned char*>(float_buffer.data());
return base64_encode(byte_data, byte_size);
}
//星型接线转换
std::string ConvertToBase64_Star() const {
std::vector<float> 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.1415f);
}
// 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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 再后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.1415f);
}
// 转换为Base64
const size_t byte_size = float_buffer.size() * sizeof(float);
const unsigned char* byte_data = reinterpret_cast<const unsigned char*>(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<float>& 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<float, 9> Rms; //相电压、线电压、电流有效值
std::array<float, 6> UU_Deviation; //相电压、线电压上偏差
std::array<float, 6> UL_Deviation; //相电压、线电压下偏差
std::array<float, 6> THD; //电压电流畸变率
std::array<float, 2> FREQ; //频率及频率偏差
std::array<std::array<float, 5>, 2> UI_Seq;//电压电流序分量及不平衡度
std::array<std::array<float, 3>, 4> TOTAL_POWER;//分相及总功率P、Q、S
std::array<float, 4> COS_PF; //视在功率因数
std::array<float, 4> COS_DF; //位移功率因数
//----------- 报文一包含时间和以上数据
std::array<std::array<float, HARMNUM>, 3> HARMV;//谐波电压含有率
//----------- 报文二包含时间和以上数据
std::array<std::array<float, HARMNUM>, 3> HARMI;//谐波电流幅值
//----------- 报文三包含时间和以上数据
std::array<std::array<float, HARMNUM>, 3> HARMVP;//谐波电压相位
//----------- 报文四包含时间和以上数据
std::array<std::array<float, HARMNUM>, 3> HARMIP;//谐波电流相位
//----------- 报文五包含时间和以上数据
std::array<std::array<float, HARMNUM>, 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<float>& 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> 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<const unsigned char*>(float_buffer.data());
return base64_encode(byte_data, byte_size);
}
std::string floatVectorToBase64(const std::vector<float>& float_buffer) const {
const size_t byte_size = float_buffer.size() * sizeof(float);
const unsigned char* byte_data =
reinterpret_cast<const unsigned char*>(float_buffer.data());
return base64_encode(byte_data, byte_size);
}
// 星型接线转换函数
std::string ConvertToBase64_Star() const {
std::vector<float> 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.1415f);
}
// 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.1415f);
}
// 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个元素
if (i == 0 || j < 3) { // 确保只取8个
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.1415f);
}
// 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.1415f);
}
// 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.1415f);
}
// 转换为Base64
return floatVectorToBase64(float_buffer);
}
// 角型接线转换函数
std::string ConvertToBase64_Delta() const {
std::vector<float> 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.1415f);
}
// 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.1415f);
}
// 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) {
if (i == 0 || j < 3) {
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.1415f);
}
// 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.1415f);
}
// 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.1415f);
}
// 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<NewBodyTaglogbuffer> 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<unsigned char> generate_binary_message(
uint16_t msg_type,
const std::vector<unsigned char>& payload);
// 生成装置云服务登录报文
std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac);
//生成询问统计数据时间报文
std::vector<unsigned char> generate_statequerytime_message();
//生成询问统计数据报文
std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType);
//生成询问实时数据报文
std::vector<unsigned char> generate_realstat_message(unsigned char nCpuNo, unsigned char StaTtype, unsigned char flag);
//生成文件下载请求报文 当前帧序号+文件名
std::vector<unsigned char> generate_downloadfile_message(int frameIndex, const std::string& fileName);
//文件目录读取报文 传入需要读取的文件路径
std::vector<unsigned char> generate_getfilemenu_message(const std::string& filedir);
// 请求定值报文 传入测点号
std::vector<unsigned char> generate_requestFixValue_message(unsigned char nCpuNo);
// 请求定值描述报文
std::vector<unsigned char> generate_requestFixDes_message();
// 设置定值报文 传入测点号+修改的定值数据队列
std::vector<unsigned char> generate_requestSetFixValue_message(unsigned char nCpuNo, const std::vector<float>& value);
/**
* @brief 生成请求装置内部定值的报文
* @return 包含完整报文的字节向量
*/
std::vector<unsigned char> generate_requestinterfixvalue_message();
/**
* @brief 生成请求装置内部定值描述的报文
* @param nDesCW 描述类型 (1-内部定值描述, 2-控制字描述)
* @return 包含完整报文的字节向量,参数无效时返回空向量
*/
std::vector<unsigned char> generate_requestinterfixdes_message(unsigned char nDesCW);
/**
* @brief 生成设置装置内部定值的报文
* @param values 要设置的定值数组 (ushort值)
* @return 包含完整报文的字节向量
*/
std::vector<unsigned char> generate_requestsetinterfixvalue_message(const std::vector<uint16_t>& values);
std::vector<unsigned char> generate_requestsetinterfixvalue_message_new(const std::vector<uint16_t>& value);
/**
* @brief 生成装置运行信息读取指令报文
* @return 包含完整报文的字节向量
*/
std::vector<unsigned char> generate_machinestatus_message();
/**
* @brief 生成装置版本配置信息读取指令报文
* @return 包含完整报文的字节向量
*/
std::vector<unsigned char> generate_machineversion_message();