Files
front_linux/LFtid1056/PQSMsg.h

1220 lines
38 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>
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
};
// 接收报文功能码枚举
enum class MsgResponseType : unsigned char {
//询问统计数据时间
Response_StatTime = 0x27,
//询问统计数据
Response_Stat = 0x26,
//询问实时数据
Response_New_3S = 0x84
};
//基础消息结构
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;
}
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);
}
};
#pragma pack(pop)
// 生成带协议头的二进制报文
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);