修改了socket通讯框架,添加了统计数据时间获取,统计数据数据读取
This commit is contained in:
@@ -7,8 +7,22 @@
|
|||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "client2.h"
|
#include "client2.h"
|
||||||
#include "PQSMsg.h"
|
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
float IntToFloat(int num) {
|
||||||
|
return static_cast<float>(num) / 65536.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ShorToFloat100(short num) {
|
||||||
|
return static_cast<float>(num) / 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ShorToFloat1000(short num) {
|
||||||
|
return static_cast<float>(num) / 1000.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ShorToFloat10000(short num) {
|
||||||
|
return static_cast<float>(num) / 10000.0f;
|
||||||
|
}
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MAC<41><43>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>䵽<EFBFBD><E4B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MAC<41><43>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>䵽<EFBFBD><E4B5BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
|
void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_t startIndex) {
|
||||||
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>пո<D0BF><D5B8>Ͷ̺<CDB6><CCBA><EFBFBD>
|
// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>пո<D0BF><D5B8>Ͷ̺<CDB6><CCBA><EFBFBD>
|
||||||
@@ -50,6 +64,69 @@ void GetMAC(const std::string& strMAC, std::vector<unsigned char>& packet, size_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRC<52><43><EFBFBD>㺯<EFBFBD><E3BAAF>
|
||||||
|
unsigned char GetCrcSum(const std::vector<unsigned char>& Check, int nOffset, int nLen) {
|
||||||
|
unsigned char reg_b = 0x00;
|
||||||
|
for (int i = 0; i < nLen; ++i) {
|
||||||
|
if (static_cast<size_t>(i + nOffset) >= Check.size()) {
|
||||||
|
throw std::out_of_range("Index out of range in GetCrcSum");
|
||||||
|
}
|
||||||
|
reg_b += Check[i + nOffset];
|
||||||
|
}
|
||||||
|
return reg_b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
|
||||||
|
std::vector<unsigned char> GetMsg(const std::vector<unsigned char>& SrcData, unsigned char nType) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (SrcData.empty() ||
|
||||||
|
((nType < 0x01 || nType > 0xA4) && nType != 0xFF)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD>ͷ(6) + <20><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>(2) + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(1) + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + CRC+<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(2)
|
||||||
|
const size_t total_len = 6 + 2 + 1 + SrcData.size() + 2;
|
||||||
|
std::vector<unsigned char> msg(total_len);
|
||||||
|
|
||||||
|
// <20><>װ<EFBFBD><D7B0><EFBFBD><EFBFBD>ͷ (6<>ֽ<EFBFBD>)
|
||||||
|
msg[0] = 0xEB; // <20><><EFBFBD><EFBFBD>ͷ
|
||||||
|
msg[1] = 0x90; // <20><><EFBFBD><EFBFBD>ͷ
|
||||||
|
msg[2] = 0x00; // <20><><EFBFBD><EFBFBD>
|
||||||
|
msg[3] = 0x00; // <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>ֶΣ<D6B6><CEA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>峤<EFBFBD><E5B3A4>+<2B><><EFBFBD><EFBFBD><EFBFBD>룩
|
||||||
|
uint16_t data_len = static_cast<uint16_t>(SrcData.size() + 1);
|
||||||
|
msg[4] = static_cast<unsigned char>(data_len >> 8); // <20><><EFBFBD>ȸ<EFBFBD><C8B8>ֽ<EFBFBD>
|
||||||
|
msg[5] = static_cast<unsigned char>(data_len & 0xFF); // <20><><EFBFBD>ȵ<EFBFBD><C8B5>ֽ<EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD> (2<>ֽ<EFBFBD>)
|
||||||
|
msg[6] = 0x00; // <20><><EFBFBD><EFBFBD>
|
||||||
|
msg[7] = 0xFF; // <20><><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
msg[8] = nType;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (!SrcData.empty()) {
|
||||||
|
std::copy(SrcData.begin(), SrcData.end(), msg.begin() + 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>CRC<52><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>+<2B><><EFBFBD><EFBFBD><EFBFBD>壩
|
||||||
|
unsigned char crc = GetCrcSum(msg, 8, 1 + SrcData.size());
|
||||||
|
msg[msg.size() - 2] = crc;
|
||||||
|
msg[msg.size() - 1] = 0x16; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex) {
|
||||||
|
throw std::runtime_error(std::string("Exception in GetMsg: ") + ex.what());
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
throw std::runtime_error("Unknown exception in GetMsg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>
|
// <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)
|
std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac)
|
||||||
{
|
{
|
||||||
@@ -89,3 +166,42 @@ std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>䱨<EFBFBD><E4B1A8>
|
||||||
|
std::vector<unsigned char> generate_statequerytime_message() {
|
||||||
|
// <20><><EFBFBD><EFBFBD>2<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0<CEAA><30>
|
||||||
|
std::vector<unsigned char> DataBuf(2, 0x00);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>GetMsg<73><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_StatTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
|
||||||
|
std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD>С<EFBFBD><D0A1>3(<28><><EFBFBD><EFBFBD>) + 2(nDeviceNo) + 2(nDataType) + time<6D>ṹ<EFBFBD><E1B9B9>С
|
||||||
|
const size_t totalSize = 3 + 2 * sizeof(uint16_t) + time.GetSize();
|
||||||
|
std::vector<unsigned char> DataBuf(totalSize, 0x00); // <20><>ʼ<EFBFBD><CABC>Ϊȫ0
|
||||||
|
|
||||||
|
size_t offset = 0;
|
||||||
|
|
||||||
|
// 1. <20><><EFBFBD><EFBFBD>3<EFBFBD>ֽڱ<D6BD><DAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѳ<EFBFBD>ʼ<EFBFBD><CABC>Ϊ0<CEAA><30>
|
||||||
|
offset += 3;
|
||||||
|
|
||||||
|
// 2. д<><D0B4>nDeviceNo<4E><6F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
uint16_t netDeviceNo = htons(nDeviceNo);
|
||||||
|
memcpy(DataBuf.data() + offset, &netDeviceNo, sizeof(uint16_t));
|
||||||
|
offset += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// 3. д<><D0B4>nDataType<70><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
uint16_t netDataType = htons(nDataType);
|
||||||
|
memcpy(DataBuf.data() + offset, &netDataType, sizeof(uint16_t));
|
||||||
|
offset += sizeof(uint16_t);
|
||||||
|
|
||||||
|
// 4. д<><D0B4>time<6D>ṹ<EFBFBD><E1B9B9><EFBFBD>ڲ<EFBFBD><DAB2>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
time.GetStructBuf(DataBuf.data(), DataBuf.size(), offset);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Stat));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,800 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdlib>
|
#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>8Ԫ<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>
|
// <20><><EFBFBD>ɴ<EFBFBD>Э<EFBFBD><D0AD>ͷ<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ʊ<EFBFBD><C6B1><EFBFBD>
|
||||||
std::vector<unsigned char> generate_binary_message(
|
std::vector<unsigned char> generate_binary_message(
|
||||||
uint16_t msg_type,
|
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>
|
// <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);
|
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);
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
#include "client2.h"
|
#include "client2.h"
|
||||||
#include "PQSMsg.h"
|
|
||||||
#include "dealMsg.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -11,7 +9,7 @@
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
// 配置参数
|
// 配置参数
|
||||||
constexpr int BASE_RECONNECT_DELAY = 5000; // 基础重连延迟(ms)
|
constexpr int BASE_RECONNECT_DELAY = 20000; // 基础重连延迟(ms)
|
||||||
constexpr int MAX_RECONNECT_DELAY = 60000; // 最大重连延迟(ms)
|
constexpr int MAX_RECONNECT_DELAY = 60000; // 最大重连延迟(ms)
|
||||||
constexpr const char* SERVER_IP = "101.132.39.45"; // 目标服务器IP"101.132.39.45"
|
constexpr const char* SERVER_IP = "101.132.39.45"; // 目标服务器IP"101.132.39.45"
|
||||||
constexpr int SERVER_PORT = 1056; // 目标服务器端口1056
|
constexpr int SERVER_PORT = 1056; // 目标服务器端口1056
|
||||||
@@ -23,7 +21,8 @@ extern SafeMessageQueue message_queue;
|
|||||||
// ClientContext 实现
|
// ClientContext 实现
|
||||||
ClientContext::ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index)
|
ClientContext::ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index)
|
||||||
: loop(loop), state(ConnectionState::DISCONNECTED),
|
: loop(loop), state(ConnectionState::DISCONNECTED),
|
||||||
reconnect_attempts(0), shutdown(false), device_info(device), index_(index) {
|
reconnect_attempts(0), shutdown(false), device_info(device), index_(index),cloudstatus(0), current_state_(DeviceState::IDLE),
|
||||||
|
state_start_time_(0) {
|
||||||
|
|
||||||
recv_buffer_.reserve(4096); // 预分配4KB缓冲区
|
recv_buffer_.reserve(4096); // 预分配4KB缓冲区
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ void ClientContext::init_tcp() {
|
|||||||
|
|
||||||
void ClientContext::start_timer() {
|
void ClientContext::start_timer() {
|
||||||
if (!uv_is_active((uv_handle_t*)&timer)) {
|
if (!uv_is_active((uv_handle_t*)&timer)) {
|
||||||
uv_timer_start(&timer, on_timer, 6000, 6000);
|
uv_timer_start(&timer, on_timer, 5000,5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +186,132 @@ void ClientContext::put_packet_into_queue(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增方法:改变装置状态
|
||||||
|
void ClientContext::change_state(DeviceState new_state, const std::vector<unsigned char>& packet) {
|
||||||
|
std::lock_guard<std::mutex> lock(state_mutex_);
|
||||||
|
// 直接更新状态,不调用其他锁方法
|
||||||
|
current_state_ = new_state;
|
||||||
|
current_packet_ = packet;
|
||||||
|
state_start_time_ = uv_now(loop);
|
||||||
|
|
||||||
|
std::cout << "[Device " << device_info.device_id
|
||||||
|
<< "] State changed to: " << static_cast<int>(new_state) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增方法:添加后续动作
|
||||||
|
void ClientContext::add_action(DeviceState state, const std::vector<unsigned char>& packet) {
|
||||||
|
std::lock_guard<std::mutex> lock(state_mutex_);
|
||||||
|
action_queue_.push({ state, packet });
|
||||||
|
|
||||||
|
std::cout << "[Device " << device_info.device_id
|
||||||
|
<< "] Action added to queue: " << static_cast<int>(state) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增方法:处理状态超时
|
||||||
|
void ClientContext::check_state_timeout() {
|
||||||
|
constexpr uint64_t STATE_TIMEOUT = 30000;//30秒超时
|
||||||
|
uint64_t now = uv_now(loop);
|
||||||
|
bool timed_out = false;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(state_mutex_);
|
||||||
|
if (current_state_ != DeviceState::IDLE &&
|
||||||
|
(now - state_start_time_) > STATE_TIMEOUT)
|
||||||
|
{
|
||||||
|
timed_out = true;
|
||||||
|
current_state_ = DeviceState::IDLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timed_out) {
|
||||||
|
process_next_action(); // 在锁外调用
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增方法:处理下一个动作
|
||||||
|
void ClientContext::process_next_action() {
|
||||||
|
StateAction next;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(state_mutex_);
|
||||||
|
if (current_state_ != DeviceState::IDLE || action_queue_.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
next = action_queue_.front();
|
||||||
|
action_queue_.pop();
|
||||||
|
} // 提前释放锁
|
||||||
|
|
||||||
|
// 在锁外调用可能阻塞的函数
|
||||||
|
change_state(next.state, next.packet);
|
||||||
|
send_current_packet();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增方法:发送当前状态对应的报文
|
||||||
|
void ClientContext::send_current_packet() {
|
||||||
|
if (!current_packet_.empty()) {
|
||||||
|
send_binary_data(this, current_packet_.data(), current_packet_.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientContext::add_stat_packet(const std::vector<unsigned char>& packet, int current_packet, int total_packets) {
|
||||||
|
std::lock_guard<std::mutex> lock(stat_cache_mutex_);
|
||||||
|
|
||||||
|
// 如果是第一帧,初始化缓存
|
||||||
|
if (current_packet == 1) {
|
||||||
|
stat_packets_cache_.clear();
|
||||||
|
expected_total_packets_ = total_packets;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加到缓存
|
||||||
|
stat_packets_cache_.push_back({ current_packet, packet });
|
||||||
|
|
||||||
|
// 检查是否收齐所有帧
|
||||||
|
return (stat_packets_cache_.size() >= expected_total_packets_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ClientContext::StatPacket> ClientContext::get_and_clear_stat_packets() {
|
||||||
|
std::lock_guard<std::mutex> lock(stat_cache_mutex_);
|
||||||
|
auto packets = std::move(stat_packets_cache_);
|
||||||
|
stat_packets_cache_.clear();
|
||||||
|
expected_total_packets_ = 0;
|
||||||
|
return packets;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientContext::clear_stat_cache() {
|
||||||
|
std::lock_guard<std::mutex> lock(stat_cache_mutex_);
|
||||||
|
stat_packets_cache_.clear();
|
||||||
|
expected_total_packets_ = 0;
|
||||||
|
}
|
||||||
|
// 添加浮点数据到缓存
|
||||||
|
bool ClientContext::add_float_data(ushort point_id, int data_type, const tagPqData_Float& float_data) {
|
||||||
|
if (data_type < 0 || data_type > 3) return false;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(float_cache_mutex_);
|
||||||
|
auto& cache = point_float_cache_[point_id];
|
||||||
|
cache.data[data_type] = float_data;
|
||||||
|
cache.received[data_type] = true;
|
||||||
|
|
||||||
|
// 检查是否四种数据类型都已接收
|
||||||
|
return cache.received[0] && cache.received[1] &&
|
||||||
|
cache.received[2] && cache.received[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取并清除指定测点的完整浮点数据
|
||||||
|
std::array<tagPqData_Float, 4> ClientContext::get_and_clear_float_data(ushort point_id) {
|
||||||
|
std::lock_guard<std::mutex> lock(float_cache_mutex_);
|
||||||
|
auto it = point_float_cache_.find(point_id);
|
||||||
|
if (it == point_float_cache_.end()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto data = it->second.data;
|
||||||
|
point_float_cache_.erase(it);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除所有浮点数据缓存
|
||||||
|
void ClientContext::clear_float_cache() {
|
||||||
|
std::lock_guard<std::mutex> lock(float_cache_mutex_);
|
||||||
|
point_float_cache_.clear();
|
||||||
|
}
|
||||||
/* 缓冲区分配回调 */
|
/* 缓冲区分配回调 */
|
||||||
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
void alloc_buffer(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
|
||||||
buf->base = new char[suggested_size];
|
buf->base = new char[suggested_size];
|
||||||
@@ -230,24 +355,33 @@ void on_write(uv_write_t* req, int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 定时发送回调 */
|
/* 定时发送回调 */
|
||||||
|
//5秒执行一次定时器
|
||||||
void on_timer(uv_timer_t* handle) {
|
void on_timer(uv_timer_t* handle) {
|
||||||
ClientContext* ctx = static_cast<ClientContext*>(handle->data);
|
ClientContext* ctx = static_cast<ClientContext*>(handle->data);
|
||||||
|
|
||||||
if (ctx->state != ConnectionState::CONNECTED) {
|
if (ctx->state != ConnectionState::CONNECTED) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << "on_timer: " << ctx->device_info.mac << " send!"<< std::endl;
|
|
||||||
// 使用装置自己的MAC地址生成登录报文
|
|
||||||
auto binary_data = generate_frontlogin_message(ctx->device_info.mac);
|
|
||||||
|
|
||||||
// 调用发送函数
|
static int statequerytime = 0;//询问统计数据时间标志 20秒执行一次
|
||||||
send_binary_data(ctx, binary_data.data(), binary_data.size());
|
|
||||||
|
|
||||||
//ClientManager::instance().send_to_device(ctx->device_info.mac, binary_data.data(), binary_data.size());
|
// 检查状态超时 30秒状态未更新则重置为空闲状态
|
||||||
|
ctx->check_state_timeout();
|
||||||
|
|
||||||
// 根据装置状态发送其他数据
|
// 装置登录成功后,只在空闲状态处理后续动作
|
||||||
if (ctx->device_info.status == 1) { // 在线状态
|
if (ctx->cloudstatus == 1) {
|
||||||
// 可以发送装置配置信息或测点数据
|
|
||||||
|
//20秒一次 执行统计数据时间询问
|
||||||
|
if (++statequerytime >= 4 && ctx->current_state_ == DeviceState::IDLE) {
|
||||||
|
statequerytime = 0;//重置计时
|
||||||
|
auto sendbuff = generate_statequerytime_message();//组装询问统计数据时间报文
|
||||||
|
ctx->add_action(DeviceState::READING_STATS_TIME, sendbuff);//将该状态以及待发送报文存入队列
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理后续工作队列的工作 取出一个并执行
|
||||||
|
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||||
|
ctx->process_next_action();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,6 +417,18 @@ void on_close(uv_handle_t* handle) {
|
|||||||
std::cerr << "[Device " << ctx->device_info.device_id << "] Connection closed" << std::endl;
|
std::cerr << "[Device " << ctx->device_info.device_id << "] Connection closed" << std::endl;
|
||||||
|
|
||||||
ctx->stop_timers();
|
ctx->stop_timers();
|
||||||
|
// 清空缓存
|
||||||
|
ctx->clear_stat_cache();
|
||||||
|
// 清除浮点数据缓存
|
||||||
|
ctx->clear_float_cache();
|
||||||
|
|
||||||
|
ctx->cloudstatus = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> state_lock(ctx->state_mutex_);
|
||||||
|
ctx->current_state_ = DeviceState::IDLE; // 直接修改状态
|
||||||
|
std::queue<StateAction> empty;
|
||||||
|
std::swap(ctx->action_queue_, empty);
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx->shutdown) {
|
if (!ctx->shutdown) {
|
||||||
int delay = BASE_RECONNECT_DELAY * pow(2, ctx->reconnect_attempts);
|
int delay = BASE_RECONNECT_DELAY * pow(2, ctx->reconnect_attempts);
|
||||||
@@ -344,6 +490,11 @@ void on_connect(uv_connect_t* req, int status) {
|
|||||||
ctx->state = ConnectionState::CONNECTED;
|
ctx->state = ConnectionState::CONNECTED;
|
||||||
ctx->reconnect_attempts = 0;
|
ctx->reconnect_attempts = 0;
|
||||||
|
|
||||||
|
//客户端连接完毕后,发送装置登陆消息
|
||||||
|
std::cout << "connected: " << ctx->device_info.mac << " send login msg!" << std::endl;
|
||||||
|
auto binary_data = generate_frontlogin_message(ctx->device_info.mac);
|
||||||
|
send_binary_data(ctx, binary_data.data(), binary_data.size());
|
||||||
|
|
||||||
uv_read_start((uv_stream_t*)&ctx->client, alloc_buffer, on_read);
|
uv_read_start((uv_stream_t*)&ctx->client, alloc_buffer, on_read);
|
||||||
ctx->start_timer();
|
ctx->start_timer();
|
||||||
}
|
}
|
||||||
@@ -493,4 +644,333 @@ void ClientManager::stop_all() {
|
|||||||
pair.second->close_handles();
|
pair.second->close_handles();
|
||||||
}
|
}
|
||||||
clients_.clear();
|
clients_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在ClientManager成员函数实现中添加方法实现
|
||||||
|
void ClientManager::restart_device(const std::string& device_id) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
ClientContext* target_ctx = nullptr;
|
||||||
|
|
||||||
|
// 查找匹配的设备(支持device_id或mac地址)
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == device_id ||
|
||||||
|
ctx->device_info.mac == device_id) {
|
||||||
|
target_ctx = ctx.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!target_ctx) {
|
||||||
|
std::cerr << "[restart_device] Device not found: " << device_id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[restart_device] Restarting device: " << device_id << std::endl;
|
||||||
|
|
||||||
|
// 确保不处于关闭状态
|
||||||
|
target_ctx->shutdown = false;
|
||||||
|
|
||||||
|
// 停止所有定时器
|
||||||
|
target_ctx->stop_timers();
|
||||||
|
|
||||||
|
// 重置重连计数器
|
||||||
|
target_ctx->reconnect_attempts = 0;
|
||||||
|
|
||||||
|
// 关闭TCP连接(会触发on_close回调)
|
||||||
|
if (!uv_is_closing((uv_handle_t*)&target_ctx->client)) {
|
||||||
|
uv_close((uv_handle_t*)&target_ctx->client, on_close);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 如果已经在关闭过程中,直接触发重连
|
||||||
|
target_ctx->state = ConnectionState::DISCONNECTED;
|
||||||
|
target_ctx->start_reconnect_timer(0); // 立即重连
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//修改客户端云前置登录状态
|
||||||
|
bool ClientManager::set_cloud_status(const std::string& identifier, int status) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
// 匹配装置ID或MAC地址
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
// 修改云前置登录状态
|
||||||
|
ctx->cloudstatus = status;
|
||||||
|
std::cout << "[Device " << identifier
|
||||||
|
<< "] Cloud status updated to: " << status << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[set_cloud_status] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientManager::add_action_to_device(const std::string& identifier,
|
||||||
|
DeviceState state,
|
||||||
|
const std::vector<unsigned char>& packet) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
ctx->add_action(state, packet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[add_action_to_device] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientManager::change_device_state(const std::string& identifier,
|
||||||
|
DeviceState new_state,
|
||||||
|
const std::vector<unsigned char>& packet) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
ctx->change_state(new_state, packet);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[change_device_state] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientManager::clear_action_queue(const std::string& identifier) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> state_lock(ctx->state_mutex_);
|
||||||
|
std::queue<StateAction> empty;
|
||||||
|
std::swap(ctx->action_queue_, empty);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[clear_action_queue] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientManager::get_device_state(const std::string& identifier, DeviceState& out_state) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> state_lock(ctx->state_mutex_);
|
||||||
|
out_state = ctx->current_state_;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[get_device_state] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientManager::post_message_processing(const std::string& identifier) {
|
||||||
|
ClientContext* target = nullptr;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
target = pair.second.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // 提前释放manager锁
|
||||||
|
|
||||||
|
if (!target) {
|
||||||
|
std::cerr << "Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接操作client,避免嵌套锁
|
||||||
|
if (target->current_state_ == DeviceState::IDLE) {
|
||||||
|
//空闲状态执行下一项工作
|
||||||
|
target->process_next_action();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//非空闲状态执行当前工作
|
||||||
|
target->send_current_packet();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//通过id或者mac读取装置下属测点信息
|
||||||
|
bool ClientManager::get_device_points(const std::string& identifier,
|
||||||
|
std::vector<PointInfo>& out_points) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (const auto& pair : clients_) {
|
||||||
|
const auto& ctx = pair.second;
|
||||||
|
// 匹配装置ID或MAC地址
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
// 复制测点信息到输出参数
|
||||||
|
out_points = ctx->device_info.points;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[get_device_points] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//保存多帧报文至缓存区等待收全
|
||||||
|
bool ClientManager::add_stat_packet_to_device(const std::string& identifier,
|
||||||
|
const std::vector<unsigned char>& packet,
|
||||||
|
int current_packet,
|
||||||
|
int total_packets) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
return ctx->add_stat_packet(packet, current_packet, total_packets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[add_stat_packet_to_device] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取缓存区内所有多帧报文并清空缓存
|
||||||
|
std::vector<ClientContext::StatPacket> ClientManager::get_and_clear_stat_packets(const std::string& identifier) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
return ctx->get_and_clear_stat_packets();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[get_and_clear_stat_packets] Device not found: " << identifier << std::endl;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
//清空所有缓存区
|
||||||
|
bool ClientManager::clear_stat_cache(const std::string& identifier) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
ctx->clear_stat_cache();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[clear_stat_cache] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取pt和CT变比
|
||||||
|
bool ClientManager::get_pt_ct_ratio(const std::string& identifier,
|
||||||
|
int16_t nCpuNo,
|
||||||
|
float& pt_ratio,
|
||||||
|
float& ct_ratio) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
// 匹配装置ID或MAC地址
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
|
||||||
|
// 遍历装置的所有测点
|
||||||
|
for (const auto& point : ctx->device_info.points) {
|
||||||
|
// 匹配测点序号
|
||||||
|
if (point.nCpuNo == nCpuNo) {
|
||||||
|
// 计算PT变比 (PT1/PT2)
|
||||||
|
pt_ratio = (point.PT2 != 0.0) ?
|
||||||
|
static_cast<float>(point.PT1 / point.PT2) : 1.0f;
|
||||||
|
|
||||||
|
// 计算CT变比 (CT1/CT2)
|
||||||
|
ct_ratio = (point.CT2 != 0.0) ?
|
||||||
|
static_cast<float>(point.CT1 / point.CT2) : 1.0f;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << "[get_pt_ct_ratio] Point not found for CPU: "
|
||||||
|
<< nCpuNo << " in device: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[get_pt_ct_ratio] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加浮点数据到指定设备的缓存
|
||||||
|
bool ClientManager::add_float_data_to_device(const std::string& identifier,
|
||||||
|
ushort point_id,
|
||||||
|
int data_type,
|
||||||
|
const tagPqData_Float& float_data) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
return ctx->add_float_data(point_id, data_type, float_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取并清除指定测点的完整浮点数据
|
||||||
|
std::array<tagPqData_Float, 4> ClientManager::get_and_clear_float_data(
|
||||||
|
const std::string& identifier, ushort point_id) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
return ctx->get_and_clear_float_data(point_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除设备的所有浮点缓存
|
||||||
|
bool ClientManager::clear_float_cache(const std::string& identifier) {
|
||||||
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
|
|
||||||
|
for (auto& pair : clients_) {
|
||||||
|
auto& ctx = pair.second;
|
||||||
|
if (ctx->device_info.device_id == identifier ||
|
||||||
|
ctx->device_info.mac == identifier) {
|
||||||
|
ctx->clear_float_cache();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,15 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include "dealMsg.h"
|
||||||
|
#include "PQSMsg.h"
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
||||||
struct PointInfo {
|
struct PointInfo {
|
||||||
std::string point_id; // <20><><EFBFBD><EFBFBD>ID
|
std::string point_id; // <20><><EFBFBD><EFBFBD>ID
|
||||||
std::string name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
std::string name; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
std::string device_id; // <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>ID
|
std::string device_id; // <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>ID
|
||||||
|
ushort nCpuNo; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-6
|
||||||
double PT1; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>1
|
double PT1; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>1
|
||||||
double PT2; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>2
|
double PT2; // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD>2
|
||||||
double CT1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
double CT1; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1
|
||||||
@@ -32,6 +35,21 @@ enum class ConnectionState {
|
|||||||
CONNECTED
|
CONNECTED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ӵ<EFBFBD>״̬ö<CCAC><C3B6>
|
||||||
|
enum class DeviceState {
|
||||||
|
IDLE, // <20><><EFBFBD><EFBFBD>״̬
|
||||||
|
READING_STATS, // <20><>ȡͳ<C8A1><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
READING_STATS_TIME, // <20><>ȡͳ<C8A1><CDB3>ʱ<EFBFBD><CAB1>
|
||||||
|
// <20>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>״̬
|
||||||
|
CUSTOM_ACTION // <20>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF>
|
||||||
|
};
|
||||||
|
|
||||||
|
// ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>ṹ<EFBFBD><E1B9B9>
|
||||||
|
struct StateAction {
|
||||||
|
DeviceState state;
|
||||||
|
std::vector<unsigned char> packet; // <20><>״̬<D7B4><CCAC>Ҫ<EFBFBD><D2AA><EFBFBD>͵ı<CDB5><C4B1><EFBFBD>
|
||||||
|
};
|
||||||
|
|
||||||
class ClientContext {
|
class ClientContext {
|
||||||
public:
|
public:
|
||||||
uv_loop_t* loop;
|
uv_loop_t* loop;
|
||||||
@@ -41,18 +59,65 @@ public:
|
|||||||
ConnectionState state;
|
ConnectionState state;
|
||||||
int reconnect_attempts;
|
int reconnect_attempts;
|
||||||
volatile bool shutdown;
|
volatile bool shutdown;
|
||||||
DeviceInfo device_info; // װ<><D7B0><EFBFBD><EFBFBD>Ϣ
|
|
||||||
|
DeviceInfo device_info; // װ<><D7B0><EFBFBD><EFBFBD>Ϣ
|
||||||
|
int cloudstatus; // <20><>ǰ<EFBFBD>õ<EFBFBD>¼״̬<D7B4><CCAC>0<EFBFBD><30>δ<EFBFBD><CEB4>¼ 1<><31><EFBFBD>ѵ<EFBFBD>¼<EFBFBD><C2BC>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա
|
||||||
|
DeviceState current_state_; // <20><>ǰװ<C7B0><D7B0>״̬
|
||||||
|
uint64_t state_start_time_; // ״̬<D7B4><CCAC>ʼʱ<CABC><CAB1>(ms)
|
||||||
|
std::queue<StateAction> action_queue_; // ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::mutex state_mutex_; // ״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::vector<unsigned char> current_packet_; // <20><>ǰ״̬<D7B4><CCAC>Ҫ<EFBFBD><D2AA><EFBFBD>͵ı<CDB5><C4B1><EFBFBD>
|
||||||
|
|
||||||
ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index);
|
ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index);
|
||||||
~ClientContext();
|
~ClientContext();
|
||||||
|
|
||||||
void init_tcp();
|
void init_tcp();//<2F><>ʼ<EFBFBD><CABC><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
void start_timer();
|
void start_timer();//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧװ<D3A6>ü<EFBFBD>ʱ<EFBFBD><CAB1> 5<><35>ִ<EFBFBD><D6B4>һ<EFBFBD><D2BB>
|
||||||
void start_reconnect_timer(int delay);
|
void start_reconnect_timer(int delay);//<2F><><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
||||||
void stop_timers();
|
void stop_timers();//ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
void close_handles();
|
void close_handles();//<2F>رտͻ<D5BF><CDBB>˸<EFBFBD><CBB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>붨ʱ<EBB6A8><CAB1>
|
||||||
void append_and_process_data(const char* data, size_t len);
|
void append_and_process_data(const char* data, size_t len);//<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD>뻺<EFBFBD><EBBBBA>
|
||||||
void put_packet_into_queue(const std::vector<unsigned char>& packet);
|
void put_packet_into_queue(const std::vector<unsigned char>& packet);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
void change_state(DeviceState new_state, const std::vector<unsigned char>& packet = {});//<2F>ı<EFBFBD>װ<EFBFBD><D7B0>״̬<D7B4>͵<EFBFBD>ǰ״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>
|
||||||
|
void add_action(DeviceState state, const std::vector<unsigned char>& packet = {});//<2F><><EFBFBD>Ӻ<EFBFBD><D3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void check_state_timeout();//װ<><D7B0>״̬<D7B4><CCAC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
|
||||||
|
void process_next_action();//װ<><D7B0>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4>
|
||||||
|
void send_current_packet();//<2F><><EFBFBD>͵<EFBFBD>ǰ״̬<D7B4>ı<EFBFBD><C4B1><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>: <20><>֡<EFBFBD><D6A1><EFBFBD>ݱ<EFBFBD><DDB1>Ļ<EFBFBD><C4BB><EFBFBD>
|
||||||
|
struct StatPacket {
|
||||||
|
int packet_index;
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<StatPacket> stat_packets_cache_; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||||
|
int expected_total_packets_ = 0; // Ԥ<><D4A4><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>
|
||||||
|
std::mutex stat_cache_mutex_; // <20><><EFBFBD>滥<EFBFBD><E6BBA5><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool add_stat_packet(const std::vector<unsigned char>& packet, int current_packet, int total_packets);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::vector<StatPacket> get_and_clear_stat_packets();//ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD>
|
||||||
|
void clear_stat_cache();//<2F><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD>
|
||||||
|
|
||||||
|
// ͳ<><CDB3><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
||||||
|
struct PointFloatCache {
|
||||||
|
std::array<tagPqData_Float, 4> data; // <20>洢<EFBFBD><E6B4A2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(0-3)
|
||||||
|
std::array<bool, 4> received = { false }; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ѽ<EFBFBD><D1BD><EFBFBD>
|
||||||
|
};
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>ͳ<EFBFBD>Ƹ<EFBFBD><C6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||||
|
std::unordered_map<ushort, PointFloatCache> point_float_cache_;
|
||||||
|
std::mutex float_cache_mutex_; // <20><><EFBFBD>㻺<EFBFBD>滥<EFBFBD><E6BBA5><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool add_float_data(ushort point_id, int data_type, const tagPqData_Float& float_data);
|
||||||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::array<tagPqData_Float, 4> get_and_clear_float_data(ushort point_id);
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
|
||||||
|
void clear_float_cache();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int index_;
|
int index_;
|
||||||
@@ -76,16 +141,69 @@ public:
|
|||||||
loop_ = loop;
|
loop_ = loop;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_device(const DeviceInfo& device);
|
void add_device(const DeviceInfo& device);//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
void remove_device(const std::string& device_id);
|
void remove_device(const std::string& device_id);//ɾ<><C9BE>һ<EFBFBD><D2BB>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
bool send_to_device(const std::string& identifier, const unsigned char* data, size_t size);
|
bool send_to_device(const std::string& identifier, const unsigned char* data, size_t size);//ѡ<><D1A1>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>װ<EFBFBD>÷<EFBFBD><C3B7><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
void stop_all();
|
void restart_device(const std::string& device_id);//<2F>ر<EFBFBD>ָ<EFBFBD><D6B8>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
void stop_all();//ֹͣ<CDA3><D6B9><EFBFBD>пͻ<D0BF><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool set_cloud_status(const std::string& identifier, int status);//<2F><EFBFBD><DEB8><EFBFBD>ǰ<EFBFBD>õ<EFBFBD>¼״̬
|
||||||
|
bool post_message_processing(const std::string& identifier);// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<C9BA>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
|
||||||
|
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
|
||||||
|
bool add_action_to_device(const std::string& identifier,
|
||||||
|
DeviceState state,
|
||||||
|
const std::vector<unsigned char>& packet = {});
|
||||||
|
|
||||||
|
// <20>ı<EFBFBD>װ<EFBFBD>õ<EFBFBD>ǰ״̬
|
||||||
|
bool change_device_state(const std::string& identifier,
|
||||||
|
DeviceState new_state,
|
||||||
|
const std::vector<unsigned char>& packet = {});
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD><C3B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool clear_action_queue(const std::string& identifier);
|
||||||
|
|
||||||
|
// <20><>ȡװ<C8A1>õ<EFBFBD>ǰ״̬
|
||||||
|
bool get_device_state(const std::string& identifier, DeviceState& out_state);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD>ȡװ<C8A1>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
bool get_device_points(const std::string& identifier,std::vector<PointInfo>& out_points);
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>ͻ<EFBFBD><CDBB>˵Ķ<CBB5>֡<EFBFBD><D6A1><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>뻺<EFBFBD><EBBBBA><EFBFBD><EFBFBD>
|
||||||
|
bool add_stat_packet_to_device(const std::string& identifier,
|
||||||
|
const std::vector<unsigned char>& packet,
|
||||||
|
int current_packet,
|
||||||
|
int total_packets);
|
||||||
|
|
||||||
|
//<2F><>ȡָ<C8A1><D6B8><EFBFBD>ͻ<EFBFBD><CDBB>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>л<EFBFBD><D0BB>汨<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::vector<ClientContext::StatPacket> get_and_clear_stat_packets(const std::string& identifier);
|
||||||
|
|
||||||
|
//<2F><><EFBFBD>ն<EFBFBD>֡<EFBFBD><D6A1><EFBFBD>ı<EFBFBD><C4B1>滺<EFBFBD><E6BBBA><EFBFBD><EFBFBD>
|
||||||
|
bool clear_stat_cache(const std::string& identifier);
|
||||||
|
|
||||||
|
// <20><>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PT<50><54>CT<43><54><EFBFBD><EFBFBD>ֵ
|
||||||
|
bool get_pt_ct_ratio(const std::string& identifier,
|
||||||
|
int16_t nCpuNo,
|
||||||
|
float& pt_ratio,
|
||||||
|
float& ct_ratio);
|
||||||
|
|
||||||
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><>ȡ<EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
size_t client_count() {
|
size_t client_count() {
|
||||||
std::lock_guard<std::mutex> lock(mutex_);
|
std::lock_guard<std::mutex> lock(mutex_);
|
||||||
return clients_.size();
|
return clients_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD>ָ<EFBFBD><D6B8><EFBFBD>豸<EFBFBD>Ļ<EFBFBD><C4BB><EFBFBD>
|
||||||
|
bool add_float_data_to_device(const std::string& identifier,
|
||||||
|
ushort point_id,
|
||||||
|
int data_type,
|
||||||
|
const tagPqData_Float& float_data);
|
||||||
|
|
||||||
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::array<tagPqData_Float, 4> get_and_clear_float_data(
|
||||||
|
const std::string& identifier, ushort point_id);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8>㻺<EFBFBD><E3BBBA>
|
||||||
|
bool clear_float_cache(const std::string& identifier);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientManager() : loop_(nullptr) {}
|
ClientManager() : loop_(nullptr) {}
|
||||||
std::unordered_map<std::string, std::unique_ptr<ClientContext>> clients_;
|
std::unordered_map<std::string, std::unique_ptr<ClientContext>> clients_;
|
||||||
|
|||||||
@@ -7,9 +7,7 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "PQSMsg.h"
|
|
||||||
#include "client2.h"
|
#include "client2.h"
|
||||||
#include "dealMsg.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -22,7 +20,226 @@ void process_received_message(string mac, string id,const char* data, size_t len
|
|||||||
// ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// ʾ<><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
// ע<>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>ʵ<EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>
|
// ע<>⣺<EFBFBD><E2A3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><D0AD>ʵ<EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
//<2F><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
if (length > 0) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>תΪ<D7AA><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա㴦<D4B1><E3B4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||||
|
const unsigned char* udata = reinterpret_cast<const unsigned char*>(data);
|
||||||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ij<EFBFBD><C4B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--<2D><>¼<EFBFBD><C2BC><EFBFBD>ĸ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
MessageParser parser;
|
||||||
|
bool bool_msgset = parser.SetMsg(udata, length);
|
||||||
|
|
||||||
|
//<2F>Ʒ<EFBFBD><C6B7><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>
|
||||||
|
if (udata[0] == 0xEB && udata[1] == 0x90 && udata[2] == 0xEB && udata[3] == 0x90) {
|
||||||
|
//ͨѶ״̬<D7B4><CCAC><EFBFBD><EFBFBD>
|
||||||
|
if (udata[8] == 0x01) {
|
||||||
|
std::cout << "cloud login: " << mac << " state: " << static_cast<int>(udata[16]) << static_cast<int>(udata[17]) << static_cast<int>(udata[18]) << static_cast<int>(udata[19]) << std::endl;
|
||||||
|
if (udata[19] == 0x10) {
|
||||||
|
std::cout << "cloud login: " << mac << " state: success!" << std::endl;
|
||||||
|
//װ<>õ<EFBFBD>¼<EFBFBD>ɹ<EFBFBD>
|
||||||
|
ClientManager::instance().set_cloud_status(id, 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>õ<EFBFBD>¼״̬Ϊ<CCAC>ѵ<EFBFBD>¼
|
||||||
|
}
|
||||||
|
if (udata[19] == 0x00) {
|
||||||
|
std::cout << "cloud login: " << mac << " state: fail!" << std::endl;
|
||||||
|
//װ<>õ<EFBFBD>¼ʧ<C2BC><CAA7> <20>رտͻ<D5BF><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>20<32><30><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>¼
|
||||||
|
ClientManager::instance().restart_device(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cout << "cloud login: " << mac << " state: error!"<< std::endl;
|
||||||
|
//װ<>õ<EFBFBD>¼ʧ<C2BC><CAA7> <20>رտͻ<D5BF><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>20<32><30><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>¼
|
||||||
|
ClientManager::instance().restart_device(id);
|
||||||
|
}
|
||||||
|
//<2F><>¼<EFBFBD><C2BC><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//<2F><><EFBFBD><EFBFBD>ͨѶ<CDA8><D1B6><EFBFBD><EFBFBD>
|
||||||
|
{
|
||||||
|
DeviceState currentState = DeviceState::IDLE;//<2F><>ȡ<EFBFBD><C8A1>ǰװ<C7B0>õ<EFBFBD>״̬
|
||||||
|
if (!ClientManager::instance().get_device_state(id, currentState)) {
|
||||||
|
std::cerr << "Failed to get device state for: " << id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
switch (currentState) {
|
||||||
|
case DeviceState::IDLE:
|
||||||
|
// <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::cout << "IDLE state: Received active report from " << mac << std::endl;
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD><CFB1><EFBFBD><EFBFBD>ݵ<EFBFBD><DDB5><EFBFBD>
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceState::READING_STATS:
|
||||||
|
// <20><>ȡͳ<C8A1><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬
|
||||||
|
std::cout << "READING_STATS state: Processing stats data from " << mac << std::endl;
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1>ĵ<EFBFBD><C4B5><EFBFBD>
|
||||||
|
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Stat)) {
|
||||||
|
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD>գ<EFBFBD><D5A3><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD> һ֡1K ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
//<2F><>ǰ֡δ<D6A1><CEB4>ȫ<EFBFBD><C8AB>ֱ<EFBFBD><D6B1><EFBFBD>˳<EFBFBD><CBB3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>֡
|
||||||
|
std::cout << "mac: " << mac << " count" << static_cast<int>(udata[10]) << std::endl;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>Ϣ (<28><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||||
|
int current_packet = static_cast<int>(udata[10]); // <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
|
||||||
|
int total_packets = Stat_PacketNum; // <20><>֡<EFBFBD><D6A1>
|
||||||
|
std::vector<unsigned char> packet_data(udata, udata + length);
|
||||||
|
bool complete = ClientManager::instance().add_stat_packet_to_device(
|
||||||
|
id, packet_data, current_packet, total_packets
|
||||||
|
);
|
||||||
|
//<2F>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ
|
||||||
|
if (complete) {
|
||||||
|
// 1. <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
|
||||||
|
auto packets = ClientManager::instance().get_and_clear_stat_packets(id);
|
||||||
|
|
||||||
|
// 2. <20><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::sort(packets.begin(), packets.end(),
|
||||||
|
[](const ClientContext::StatPacket& a, const ClientContext::StatPacket& b) {
|
||||||
|
return a.packet_index < b.packet_index;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 3. <20><><EFBFBD><EFBFBD>ÿ֡<C3BF><D6A1><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::vector<unsigned char> full_data;
|
||||||
|
MessageParser parser;
|
||||||
|
|
||||||
|
for (const auto& packet : packets) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
|
||||||
|
if (!parser.SetMsg(packet.data.data(), packet.data.size())) {
|
||||||
|
std::cerr << "Failed to parse packet " << packet.packet_index
|
||||||
|
<< " for device " << id << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
full_data.insert(full_data.end(),
|
||||||
|
parser.RecvData.begin(),
|
||||||
|
parser.RecvData.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. <20><>װ tagPqData <20><><EFBFBD><EFBFBD>
|
||||||
|
tagPqData pq_data;
|
||||||
|
if (!pq_data.SetStructBuf(full_data.data(), full_data.size())) {
|
||||||
|
std::cerr << "Failed to assemble tagPqData for device " << id << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// <20>ɹ<EFBFBD><C9B9><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9> pq_data <20><><EFBFBD><EFBFBD>
|
||||||
|
std::cout << "Successfully assembled tagPqData for device: "
|
||||||
|
<< id << std::endl;
|
||||||
|
|
||||||
|
float fPT = 1.0f;
|
||||||
|
float fCT = 1.0f;
|
||||||
|
if (ClientManager::instance().get_pt_ct_ratio(id, pq_data.name, fPT, fCT)) {
|
||||||
|
// ʹ<>û<EFBFBD>ȡ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
||||||
|
tagPqData_Float float_data;
|
||||||
|
float_data.SetFloatValue(pq_data, fPT, fCT);
|
||||||
|
float_data.name = pq_data.name;
|
||||||
|
float_data.Data_Type = pq_data.Data_Type;
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
// <20><><EFBFBD>ӵ<EFBFBD><D3B5><EFBFBD><EFBFBD>沢<EFBFBD><E6B2A2><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫ
|
||||||
|
bool complete = ClientManager::instance().add_float_data_to_device(
|
||||||
|
id, pq_data.name, pq_data.Data_Type, float_data);
|
||||||
|
|
||||||
|
if (complete) {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::array<tagPqData_Float, 4> all_data =
|
||||||
|
ClientManager::instance().get_and_clear_float_data(id, pq_data.name);
|
||||||
|
|
||||||
|
if (!all_data.empty()) {
|
||||||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4<><34><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
tagPqData_Float max_data = all_data[0];
|
||||||
|
tagPqData_Float min_data = all_data[1];
|
||||||
|
tagPqData_Float avg_data = all_data[2];
|
||||||
|
tagPqData_Float cp95_data = all_data[3];
|
||||||
|
|
||||||
|
// ת<><D7AA>ΪBase64<36>ַ<EFBFBD><D6B7><EFBFBD>
|
||||||
|
std::string base64Str = max_data.ConvertToBase64();
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::cout << "Base64 Encoded Data (" << max_data.CalculateFloatCount()
|
||||||
|
<< " floats): " << base64Str << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵʧ<D6B5>ܵ<EFBFBD><DCB5><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
std::cerr << "Failed to get PT/CT ratio for device: "
|
||||||
|
<< mac << " lineno: " << pq_data.name << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ϣ<EFBFBD><CFA3><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>״̬<D7B4>ȴ<EFBFBD><C8B4><EFBFBD>һ<EFBFBD><EFBFBD><EEB9A4>
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//δ<><CEB4>ȫ<EFBFBD><C8AB>ֱ<EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// װ<>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||||
|
// <20><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><F3A3ACB5><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EEB9A4><EFBFBD><EFBFBD>
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceState::READING_STATS_TIME:
|
||||||
|
// <20><>ȡͳ<C8A1><CDB3>ʱ<EFBFBD><CAB1>״̬
|
||||||
|
std::cout << "READING_STATS_TIME state: Processing stats time from " << mac << std::endl;
|
||||||
|
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_StatTime)) {
|
||||||
|
std::vector<PointInfo> points;//װ<>ò<EFBFBD><C3B2><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
if (ClientManager::instance().get_device_points(mac, points)) {
|
||||||
|
// <20>ɹ<EFBFBD><C9B9><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD>õ<EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
|
tagTime t3;
|
||||||
|
t3.SetStructBuf(parser.RecvData.data(), parser.RecvData.size());
|
||||||
|
int first = 0;//<2F><>һ<EFBFBD>α<EFBFBD><CEB1><EFBFBD>
|
||||||
|
for (const auto& point : points) {
|
||||||
|
for (ushort i = 0; i < 4; i++)//ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>ٻ<EFBFBD><D9BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ƽ<EFBFBD><C6BD><EFBFBD><EFBFBD>95<39><35><EFBFBD><EFBFBD>ֵ
|
||||||
|
{
|
||||||
|
auto sendbuff = generate_statequerystat_message(t3, point.nCpuNo, i);//<2F><>װѯ<D7B0><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
|
||||||
|
if (first == 0) {
|
||||||
|
//<2F>״γ<D7B4><CEB3><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD> ֱ<>ӽ<EFBFBD><D3BD><EFBFBD>ǰ״̬<D7B4><CCAC><EFBFBD><EFBFBD> <20><><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
first++;
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::READING_STATS, sendbuff);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//<2F><><EFBFBD>״ν<D7B4><CEBD>룬<EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еȴ<D0B5>
|
||||||
|
ClientManager::instance().add_action_to_device(id, DeviceState::READING_STATS, sendbuff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// δ<>ҵ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||||
|
// <20><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F3A3ACB5><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EEB9A4><EFBFBD><EFBFBD>
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// װ<>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||||
|
// <20><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><F3A3ACB5><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EEB9A4><EFBFBD><EFBFBD>
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DeviceState::CUSTOM_ACTION:
|
||||||
|
// <20>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF>״̬
|
||||||
|
std::cout << "CUSTOM_ACTION state: Processing custom response from " << mac << std::endl;
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><D3B4><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
|
||||||
|
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
std::cerr << "Unknown state: " << static_cast<int>(currentState)
|
||||||
|
<< " for device " << id << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <20><><EFBFBD>ۺ<EFBFBD><DBBA><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<C9BA><F3B4A5B7><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>
|
||||||
|
ClientManager::instance().post_message_processing(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <string>
|
#include <string>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
//ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
#pragma once
|
||||||
|
class PointInfo;
|
||||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||||
#define MESSAGE_QUEUE_SIZE 10000 // <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
#define MESSAGE_QUEUE_SIZE 10000 // <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "PQSMsg.h"
|
|
||||||
#include "client2.h"
|
#include "client2.h"
|
||||||
#include "dealMsg.h"
|
|
||||||
|
|
||||||
#include "cloudfront/code/interface.h"
|
#include "cloudfront/code/interface.h"
|
||||||
|
|
||||||
@@ -52,6 +50,7 @@ std::vector<DeviceInfo> generate_test_devices(int count) {
|
|||||||
"P" + dev_id.substr(1) + "01", // <20><><EFBFBD><EFBFBD>ID<49><44> P00101
|
"P" + dev_id.substr(1) + "01", // <20><><EFBFBD><EFBFBD>ID<49><44> P00101
|
||||||
"Voltage " + dev_name,
|
"Voltage " + dev_name,
|
||||||
dev_id,
|
dev_id,
|
||||||
|
1,
|
||||||
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹֵ
|
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹֵ
|
||||||
0.0,
|
0.0,
|
||||||
100.0,
|
100.0,
|
||||||
@@ -61,6 +60,7 @@ std::vector<DeviceInfo> generate_test_devices(int count) {
|
|||||||
"P" + dev_id.substr(1) + "02", // <20><><EFBFBD><EFBFBD>ID<49><44> P00102
|
"P" + dev_id.substr(1) + "02", // <20><><EFBFBD><EFBFBD>ID<49><44> P00102
|
||||||
"Current " + dev_name,
|
"Current " + dev_name,
|
||||||
dev_id,
|
dev_id,
|
||||||
|
2,
|
||||||
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||||
0.0,
|
0.0,
|
||||||
20.0,
|
20.0,
|
||||||
@@ -82,37 +82,6 @@ std::vector<DeviceInfo> generate_test_devices(int count) {
|
|||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳߳<DFB3>*/
|
|
||||||
void* work_thread(void* arg) {
|
|
||||||
int index = *(int*)arg; // <20><>ȡ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
free(arg); // <20>ͷŶ<CDB7>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>
|
|
||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>״̬Ϊ<CCAC><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
||||||
pthread_mutex_lock(&thread_info[index].lock);
|
|
||||||
printf("Thread %d started\n", index);
|
|
||||||
thread_info[index].state = THREAD_RUNNING;
|
|
||||||
pthread_mutex_unlock(&thread_info[index].lock);
|
|
||||||
|
|
||||||
// ģ<><EFBFBD><E2B9A4>ѭ<EFBFBD><D1AD>(5<><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|
||||||
while (1) {
|
|
||||||
sleep(5);
|
|
||||||
|
|
||||||
// 10%<25><><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD>̹߳<DFB3><CCB9><EFBFBD>
|
|
||||||
if (rand() % 10 == 0) {
|
|
||||||
pthread_mutex_lock(&thread_info[index].lock);
|
|
||||||
printf("Thread %d simulated failure\n", index);
|
|
||||||
pthread_mutex_unlock(&thread_info[index].lock);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// <20>߳<EFBFBD><DFB3><EFBFBD>ֹ<EFBFBD><D6B9><EFBFBD><EFBFBD>
|
|
||||||
pthread_mutex_lock(&thread_info[index].lock);
|
|
||||||
thread_info[index].state = THREAD_STOPPED;
|
|
||||||
printf("Thread %d stopped\n", index);
|
|
||||||
pthread_mutex_unlock(&thread_info[index].lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
|
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<><30><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
|
||||||
/* <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>*/
|
/* <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>*/
|
||||||
void* client_manager_thread(void* arg) {
|
void* client_manager_thread(void* arg) {
|
||||||
@@ -129,14 +98,14 @@ void* client_manager_thread(void* arg) {
|
|||||||
|
|
||||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
std::vector<PointInfo> points1 = {
|
std::vector<PointInfo> points1 = {
|
||||||
{"P001", "Main Voltage", "D001", 10.0, 0.0, 100.0, 0.0},
|
{"P001", "Main Voltage", "D001",1 ,1, 1, 1, 1},
|
||||||
{"P002", "Backup Voltage", "D001", 5.0, 0.0, 50.0, 0.0}
|
{"P002", "Backup Voltage", "D001",2 ,1, 1, 1, 1}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<PointInfo> points2 = {
|
std::vector<PointInfo> points2 = {
|
||||||
{"P101", "Generator Output", "D002", 20.0, 0.0, 200.0, 0.0}
|
{"P101", "Generator Output", "D002",1 ,1, 1, 1, 1}
|
||||||
};
|
};
|
||||||
|
//00-B7-8D-A8-00-D6
|
||||||
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>б<EFBFBD>
|
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>б<EFBFBD>
|
||||||
std::vector<DeviceInfo> devices = {
|
std::vector<DeviceInfo> devices = {
|
||||||
{
|
{
|
||||||
@@ -144,7 +113,7 @@ void* client_manager_thread(void* arg) {
|
|||||||
1, points1
|
1, points1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"D002", "Backup Device", "Model-Y", "00-B7-8D-A8-00-D6",
|
"D002", "Backup Device", "Model-Y", "00-B7-8D-01-79-06",
|
||||||
1, points2
|
1, points2
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user