2080 lines
64 KiB
C++
2080 lines
64 KiB
C++
#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
|
||
};
|
||
// 接收报文功能码枚举
|
||
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
|
||
};
|
||
//基础消息结构
|
||
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)
|
||
|
||
// 生成带协议头的二进制报文
|
||
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); |