修改了socket通讯框架,添加了统计数据时间获取,统计数据数据读取

This commit is contained in:
zw
2025-07-03 11:13:16 +08:00
parent 7fdc689f4e
commit 50b21bcd3e
7 changed files with 1761 additions and 69 deletions

View File

@@ -6,11 +6,800 @@
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <arpa/inet.h> // <20>ֽ<EFBFBD><D6BD><EFBFBD>ת<EFBFBD><D7AA>
#include <array>
using namespace std;
float IntToFloat(int num);
float ShorToFloat100(short num);
float ShorToFloat1000(short num);
float ShorToFloat10000(short num);
// <20><><EFBFBD>ͱ<EFBFBD><CDB1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
enum class MsgRequestType : unsigned char {
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
Request_StatTime = 0x8b,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Request_Stat = 0x8a
};
// <20><><EFBFBD>ձ<EFBFBD><D5B1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
enum class MsgResponseType : unsigned char {
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
Response_StatTime = 0x27,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Response_Stat = 0x26
};
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>
class MessageParser {
public:
// <20><>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD>
uint8_t msgType; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<uint8_t> RecvData; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int nMsgLen; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><><D6A1><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int nRecvDataLen; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E5B3A4>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD>bool<6F><6C><EFBFBD><EFBFBD>
bool SetMsg(const uint8_t* udata, size_t data_size) {
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
if (udata == nullptr) {
return false; // <20><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD>ʧ<EFBFBD><CAA7>
}
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ȣ<EFBFBD>6<EFBFBD>ֽ<EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>
constexpr size_t MIN_HEADER_SIZE = 6;
if (data_size < MIN_HEADER_SIZE) {
return false; // ͷ<><CDB7><EFBFBD><EFBFBD><EFBFBD>Ȳ<EFBFBD><C8B2><EFBFBD>
}
// 3. <20><>ȡ<EFBFBD><C8A1><EFBFBD>ij<EFBFBD><C4B3>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
nMsgLen = (static_cast<uint16_t>(udata[4]) << 8) | udata[5];
// 4. <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD> (8 + nMsgLen)
if (data_size < 8 + nMsgLen) {
return false; // <20><><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>
}
// 5. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ɾ<><C9BE><EFBFBD>˹<EFBFBD><CBB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>4<EFBFBD>ֽ<EFBFBD>
nRecvDataLen = nMsgLen - 4;
// 6. CRCУ<43><EFBFBD><E9A3A8><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD>Ҫʵ<D2AA>֣<EFBFBD>
/*
if (!ValidateCRC(udata, 8 + nMsgLen)) {
return false; // CRCУ<43><D0A3>ʧ<EFBFBD><CAA7>
}
*/
// 7. <20><>ȡ<EFBFBD><C8A1>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB> 6 + 2 = 8)
msgType = udata[8];
// 8. <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>12<31><32>ʼ)
RecvData.clear();
if (nRecvDataLen > 0) {
// ȷ<><C8B7><EFBFBD><EFBFBD>Խ<EFBFBD>磨nRecvDataLen = nMsgLen - 4<><34>
RecvData.assign(udata + 12, udata + 12 + nRecvDataLen);
}
return true; // <20><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD>ɹ<EFBFBD>
}
};
//<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
class tagTime {
public:
uint16_t DeviceYear;
uint16_t DeviceMonth;
uint16_t DeviceDay;
uint16_t DeviceHour;
uint16_t DeviceMinute;
uint16_t DeviceSecond;
// <20><><EFBFBD>ؽṹ<D8BD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƴ<EFBFBD>С
static constexpr size_t GetSize() {
return 6 * sizeof(uint16_t);
}
// Ĭ<>Ϲ<EFBFBD><CFB9><EFBFBD><ECBAAF>
tagTime() :
DeviceYear(1970),
DeviceMonth(1),
DeviceDay(1),
DeviceHour(0),
DeviceMinute(0),
DeviceSecond(0) {}
// <20><>std::tm<74><6D><EFBFBD><EFBFBD>
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)) {}
// <20><><EFBFBD>ƺ<EFBFBD><C6BA><EFBFBD>
void Clone(const tagTime& src) {
DeviceYear = src.DeviceYear;
DeviceMonth = src.DeviceMonth;
DeviceDay = src.DeviceDay;
DeviceHour = src.DeviceHour;
DeviceMinute = src.DeviceMinute;
DeviceSecond = src.DeviceSecond;
}
// <20>Ӷ<EFBFBD><D3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
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;
}
// <20><><EFBFBD>л<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
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();
}
};
//г<><D0B3><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD> Ĭ<><C4AC>50
constexpr int HARMNUM = 50;
// <20><>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD>ݽṹ
struct tagInHarmData {
int32_t Val;
int32_t f;
static constexpr size_t GetSize() {
return sizeof(Val) + sizeof(f);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽṹ
struct tagPowerData {
int32_t P;
int32_t Q;
int32_t S;
static constexpr size_t GetSize() {
return sizeof(P) + sizeof(Q) + sizeof(S);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}
};
// <20><><EFBFBD><EFBFBD><EFBFBD>ݽṹ (ʹ<><CAB9>1<EFBFBD>ֽڶ<D6BD><DAB6><EFBFBD>)
#pragma pack(push, 1)
class tagPqData {
public:
int16_t name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int16_t Data_Type; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagTime time; // ʱ<><CAB1>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<int32_t, 9> Rms; // <20><>ѹ/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ
std::array<int32_t, 6> UU_Deviation; // <20><>ѹ<EFBFBD><D1B9>ƫ<EFBFBD><C6AB>
std::array<int32_t, 6> UL_Deviation; // <20><>ѹ<EFBFBD><D1B9>ƫ<EFBFBD><C6AB>
std::array<int32_t, 2> F_Deviation; // Ƶ<><C6B5>ƫ<EFBFBD><C6AB>
std::array<std::array<int32_t, 4>, 2> UI_Seq; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<std::array<int32_t, HARMNUM>, 6> FuHarm; // <20><><EFBFBD><EFBFBD>г<EFBFBD><D0B3>
std::array<std::array<int32_t, HARMNUM>, 6> FuHarmPhase; // г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<std::array<tagInHarmData, HARMNUM>, 6> InHarm; // <20><>г<EFBFBD><D0B3>
std::array<std::array<int32_t, 3>, 4> Total_Power; // <20>ܹ<EFBFBD><DCB9><EFBFBD>
std::array<std::array<tagPowerData, HARMNUM>, 4> Harm_Power; // г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<std::array<int16_t, HARMNUM>, 6> Harm_Contain; // г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<int16_t, 6> Harm_Aberrance; // г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<int16_t, 4> Cos_PF; // <20><><EFBFBD>ڹ<EFBFBD><DAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<int16_t, 4> Cos_DF; // λ<>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::array<int16_t, 3> U_Fluctuation; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
std::array<int16_t, 3> U_Flicker; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>
std::array<int16_t, 3> UL_Flicker; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><ECBAAF>
tagPqData() : name(0), Data_Type(0) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ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);
}
// <20><>ȡ<EFBFBD><EFBFBD><E1B9B9><EFBFBD><EFBFBD>С
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);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
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);
// <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>
if (!time.SetStructBuf(ptr, remaining)) {
return false;
}
ptr += tagTime::GetSize();
remaining -= tagTime::GetSize();
// <20><><EFBFBD><EFBFBD>һάint32<33><32><EFBFBD><EFBFBD> - ʹ<><CAB9><EFBFBD><EFBFBD>ʽѭ<CABD><D1AD>
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);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>άint32<33><32><EFBFBD><EFBFBD> - ʹ<><CAB9><EFBFBD><EFBFBD>ʽѭ<CABD><D1AD>
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);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (auto& arr : InHarm) {
for (auto& item : arr) {
if (remaining < tagInHarmData::GetSize()) return false;
item.SetStructBuf(ptr);
ptr += tagInHarmData::GetSize();
remaining -= tagInHarmData::GetSize();
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ܹ<EFBFBD><DCB9><EFBFBD>
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);
}
}
// <20><><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (auto& arr : Harm_Power) {
for (auto& item : arr) {
if (remaining < tagPowerData::GetSize()) return false;
item.SetStructBuf(ptr);
ptr += tagPowerData::GetSize();
remaining -= tagPowerData::GetSize();
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>άint16<31><36><EFBFBD><EFBFBD> - ʹ<><CAB9><EFBFBD><EFBFBD>ʽѭ<CABD><D1AD>
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);
}
}
// <20><><EFBFBD><EFBFBD>һάint16<31><36><EFBFBD><EFBFBD> - ʹ<><CAB9><EFBFBD><EFBFBD>ʽѭ<CABD><D1AD>
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)
// <20><>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
struct tagInHarmData_float {
float Val;
float f;
};
// <20><><EFBFBD>ʸ<EFBFBD><CAB8><EFBFBD><EFBFBD>
struct tagPowerData_float {
float P;
float Q;
float S;
};
// PQ<50><51><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD><EFBFBD>
class tagPqData_Float {
public:
short name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
short Data_Type; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tagTime time; // ʱ<><CAB1>
// <20><><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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#<23><><EFBFBD><EFBFBD><38><D4AA>
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;
// <20><><EFBFBD><EFBFBD><ECBAAF><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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);
// <20><>ʼ<EFBFBD><CABC>Ƕ<EFBFBD>׽ṹ
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 };
}
}
}
// ת<><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) { // <20><>ѹ
if (j == 2) { // <20><><EFBFBD><EFBFBD>
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 { // <20><><EFBFBD><EFBFBD>
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]);
}
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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]);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < 4; i++) {
Cos_PF[i] = ShorToFloat10000(SrcData.Cos_PF[i]);
Cos_DF[i] = ShorToFloat10000(SrcData.Cos_DF[i]);
}
// <20>ܹ<EFBFBD><DCB9><EFBFBD>
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;
}
}
// г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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;
}
}
// г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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) { // <20><>ѹг<D1B9><D0B3>
FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]) * fPT;
}
else { // <20><><EFBFBD><EFBFBD>г<EFBFBD><D0B3>
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) { // <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>3,4,5)
Rms[i] = IntToFloat(SrcData.Rms[i]) * fCT;
}
else { // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Rms[i] = IntToFloat(SrcData.Rms[i]) * fPT;
}
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ת<EFBFBD><D7AA>ΪBase64<36>ַ<EFBFBD><D6B7><EFBFBD>
std::string ConvertToBase64() const {
// 1. <20><><EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD><DCB8><EFBFBD><EFBFBD><EFBFBD>
const size_t total_floats = CalculateFloatCount();
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<float> float_buffer;
float_buffer.reserve(total_floats);
SerializeFloats(float_buffer);
// 3. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3BBBA><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
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<36><34><EFBFBD><EFBFBD>
return base64_encode(byte_data, byte_size);
}
// <20><><EFBFBD><EFBFBD><E3B8A1><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD>
size_t CalculateFloatCount() const {
size_t count = 0;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
count += Rms.size();
count += UU_Deviation.size();
count += UL_Deviation.size();
count += F_Deviation.size();
// <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
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();
// Ƕ<>׽ṹ<D7BD><E1B9B9><EFBFBD><EFBFBD>
for (const auto& arr : InHarm) {
for (const auto& item : arr) {
count += 2; // ÿ<><C3BF>tagInHarmData_float<61><74><EFBFBD><EFBFBD>2<EFBFBD><32>float
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (const auto& arr : Total_Power) count += arr.size();
for (const auto& arr : Harm_Power) {
for (const auto& item : arr) {
count += 3; // ÿ<><C3BF>tagPowerData_float<61><74><EFBFBD><EFBFBD>3<EFBFBD><33>float
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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:
// <20><><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void SerializeFloats(std::vector<float>& buffer) const {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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);
// <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
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);
}
// Ƕ<>׽ṹ<D7BD><E1B9B9><EFBFBD><EFBFBD>
for (const auto& arr : InHarm) {
for (const auto& item : arr) {
buffer.push_back(item.Val);
buffer.push_back(item.f);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
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<36><34><EFBFBD><EFBFBD><EBBAAF>
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;
}
};
//<2F><><EFBFBD><EFBFBD><E3B1A8>֡<EFBFBD><D6A1><EFBFBD><EFBFBD> 1֡1024Ϊ1K
constexpr int PqDataLen = tagPqData::GetSize();
constexpr int Stat_PacketNum = (PqDataLen / 1024 > 0) ? (PqDataLen / 1024 + 1) : (PqDataLen / 1024);
// <20><><EFBFBD>ɴ<EFBFBD>Э<EFBFBD><D0AD>ͷ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
std::vector<unsigned char> generate_binary_message(
uint16_t msg_type,
const std::vector<unsigned char> & payload);
const std::vector<unsigned char>& payload);
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>
std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac);
//<2F><><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><E4B1A8>
std::vector<unsigned char> generate_statequerytime_message();
//<2F><><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType);