装置运行信息报文与装置版本配置信息报文读取
This commit is contained in:
@@ -352,7 +352,7 @@ std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac
|
||||
//GetMAC(strMac, packet, 20);
|
||||
//lnk20250808
|
||||
std::string err;
|
||||
if (!GetMAC(strMac, packet, 0, &err)) {
|
||||
if (!GetMAC(strMac, packet, 20, &err)) {
|
||||
std::cerr << "[GetMAC] parse failed: " << err << "\n";
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
}
|
||||
@@ -623,3 +623,35 @@ std::vector<unsigned char> generate_requestsetinterfixvalue_message_new(const st
|
||||
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD>
|
||||
return GetMsg(dataBuf, static_cast<unsigned char>(MsgRequestType::Request_Set_InterFix));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡָ<C8A1><EFBFBD><EEB1A8>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
std::vector<unsigned char> generate_machinestatus_message()
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>10<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
|
||||
std::vector<unsigned char> DataBuf(10, 0x00);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>ֵΪ1<CEAA><31><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>ֽڣ<D6BD>
|
||||
DataBuf[3] = 0x01;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>14<31><34>Ӧװ<D3A6><D7B0>״̬<D7B4><CCAC>ȡ
|
||||
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Read_RunningInformation));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡָ<C8A1><EFBFBD><EEB1A8>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
std::vector<unsigned char> generate_machineversion_message()
|
||||
{
|
||||
// <20><><EFBFBD><EFBFBD>10<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
|
||||
std::vector<unsigned char> DataBuf(10, 0x00);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>ֵΪ1<CEAA><31><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>ֽڣ<D6BD>
|
||||
DataBuf[3] = 0x02;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>14<31><34>Ӧװ<D3A6><D7B0>״̬<D7B4><CCAC>ȡ
|
||||
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Read_RunningInformation));
|
||||
}
|
||||
@@ -39,7 +39,9 @@ enum class MsgRequestType : unsigned char {
|
||||
//ѯ<><D1AF><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20>ڲ<EFBFBD><DAB2><EFBFBD>ֵor<6F><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
Request_Read_InterFixDes = 0x24,
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ
|
||||
Request_Set_InterFix = 0x25
|
||||
Request_Set_InterFix = 0x25,
|
||||
//ѯ<><D1AF>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
Request_Read_RunningInformation = 0x0e
|
||||
};
|
||||
// <20><><EFBFBD>ձ<EFBFBD><D5B1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
|
||||
enum class MsgResponseType : unsigned char {
|
||||
@@ -69,6 +71,8 @@ enum class MsgResponseType : unsigned char {
|
||||
Response_Read_InterFixDes = 0xA4,
|
||||
//<2F><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ(δʹ<CEB4><CAB9>,<2C><><EFBFBD><EFBFBD>Ĭ<EFBFBD>Ͽ϶<CFBF><CFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>)
|
||||
Response_Set_InterFix = 0xA5,
|
||||
//ѯ<><D1AF>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
Response_Read_RunningInformation = 0x8e,
|
||||
//Ĭ<>Ͽ϶<CFBF>Ӧ<EFBFBD><D3A6>
|
||||
Response_NewACK = 0x40,
|
||||
//Ĭ<>Ϸ<EFBFBD><CFB7><EFBFBD>Ӧ<EFBFBD><D3A6>
|
||||
@@ -2166,3 +2170,13 @@ std::vector<unsigned char> generate_requestinterfixdes_message(unsigned char nDe
|
||||
*/
|
||||
std::vector<unsigned char> generate_requestsetinterfixvalue_message(const std::vector<uint16_t>& values);
|
||||
std::vector<unsigned char> generate_requestsetinterfixvalue_message_new(const std::vector<uint16_t>& value);
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡָ<C8A1><EFBFBD><EEB1A8>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
std::vector<unsigned char> generate_machinestatus_message();
|
||||
/**
|
||||
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡָ<C8A1><EFBFBD><EEB1A8>
|
||||
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
std::vector<unsigned char> generate_machineversion_message();
|
||||
@@ -377,6 +377,7 @@ void on_timer(uv_timer_t* handle) {
|
||||
ctx->add_action(DeviceState::READING_STATS_TIME, sendbuff);//将该状态以及待发送报文存入队列
|
||||
}
|
||||
//一秒一次 执行实时数据询问 仅执行指定次数
|
||||
now = uv_now(ctx->loop);
|
||||
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->real_state_query_time_ >= 1000 && ctx->real_state_count > 0) {
|
||||
// 更新实时数据执行时间和实时收发计数
|
||||
ctx->real_state_query_time_ = now;
|
||||
@@ -385,6 +386,16 @@ void on_timer(uv_timer_t* handle) {
|
||||
auto sendbuff = generate_realstat_message(static_cast<unsigned char>(ctx->real_point_id_), static_cast<unsigned char>(0x01), static_cast<unsigned char>(0x01));//组装询问实时数据报文
|
||||
ctx->add_action(DeviceState::READING_REALSTAT, sendbuff);//将该状态以及待发送报文存入队列
|
||||
}
|
||||
//30分钟一次 读取装置运行信息
|
||||
now = uv_now(ctx->loop);
|
||||
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->read_runninginformationMsg >= 60000 * 30)
|
||||
{
|
||||
// 更新运行信息最后读取时间
|
||||
ctx->read_runninginformationMsg = now;
|
||||
|
||||
auto sendbuff = generate_machinestatus_message();//组装读取装置运行信息报文
|
||||
ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_2, sendbuff);//将该状态以及待发送报文存入队列
|
||||
}
|
||||
//处理后续工作队列的工作 取出一个并执行
|
||||
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||
ctx->process_next_action();
|
||||
@@ -530,6 +541,7 @@ void on_connect(uv_connect_t* req, int status) {
|
||||
// 新增:初始化各个计时时间戳
|
||||
ctx->last_state_query_time_ = uv_now(ctx->loop);//初始化统计数据时间戳
|
||||
ctx->real_state_query_time_ = uv_now(ctx->loop);//初始化实时数据时间戳
|
||||
ctx->read_runninginformationMsg = uv_now(ctx->loop);//初始化读取装置运行信息时间戳
|
||||
ctx->real_state_count = 0;//实时数据收发计数
|
||||
//客户端连接完毕后,发送装置登陆消息
|
||||
std::cout << "connected: " << ctx->device_info.mac << " send login msg!" << std::endl;
|
||||
@@ -1250,6 +1262,59 @@ bool ClientManager::set_interfixedvalue_action_to_device(const std::string& iden
|
||||
return false; // 设备未找到
|
||||
}
|
||||
|
||||
//读取装置运行信息
|
||||
bool ClientManager::read_runninginformation_action_to_device(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)
|
||||
{
|
||||
// 生成定值描述报文
|
||||
auto packet = generate_machinestatus_message();
|
||||
|
||||
// 添加动作到队列 (状态: 读取文件目录)
|
||||
ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_1, packet);
|
||||
|
||||
// 如果当前空闲则立即执行
|
||||
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||
ctx->process_next_action();
|
||||
}
|
||||
|
||||
return true; // 成功添加
|
||||
}
|
||||
}
|
||||
return false; // 设备未找到
|
||||
}
|
||||
|
||||
//读取装置版本配置信息
|
||||
bool ClientManager::read_devversion_action_to_device(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)
|
||||
{
|
||||
// 生成定值描述报文
|
||||
auto packet = generate_machineversion_message();
|
||||
|
||||
// 添加动作到队列 (状态: 读取文件目录)
|
||||
ctx->add_action(DeviceState::READING_DEVVERSION, packet);
|
||||
|
||||
// 如果当前空闲则立即执行
|
||||
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||
ctx->process_next_action();
|
||||
}
|
||||
|
||||
return true; // 成功添加
|
||||
}
|
||||
}
|
||||
return false; // 设备未找到
|
||||
}
|
||||
//获取指定装置测点的电压等级与接线方式
|
||||
bool ClientManager::get_point_scale_and_pttype(const std::string& identifier,
|
||||
ushort nCpuNo,
|
||||
|
||||
@@ -32,6 +32,7 @@ struct DeviceInfo {
|
||||
std::string mac; // װ<><D7B0>MAC<41><43>ַ
|
||||
int status; // <20><><EFBFBD><EFBFBD>״̬ (0: <20><><EFBFBD><EFBFBD>, 1: <20><><EFBFBD><EFBFBD>)
|
||||
std::vector<PointInfo> points; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
bool righttime; //<2F><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
|
||||
};
|
||||
|
||||
enum class ConnectionState {
|
||||
@@ -56,6 +57,9 @@ enum class DeviceState {
|
||||
READING_INTERFIXEDVALUEDES, // <20><>ȡ<EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
|
||||
READING_CONTROLWORD, // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
SET_INTERFIXEDVALUE, // <20><><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ
|
||||
READING_RUNNINGINFORMATION_1,// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
READING_RUNNINGINFORMATION_2,// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><>ʱִ<CAB1><D6B4>)
|
||||
READING_DEVVERSION, // <20><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
// <20>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>״̬
|
||||
CUSTOM_ACTION // <20>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF>
|
||||
};
|
||||
@@ -79,6 +83,7 @@ public:
|
||||
uint64_t real_state_query_time_ = 0; // ʵʱ<CAB5><CAB1><EFBFBD>ݼ<EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD>
|
||||
std::atomic<int> real_state_count{ 0 };//ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD> ԭ<>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>̰߳<DFB3>ȫ
|
||||
std::atomic<ushort> real_point_id_{ 1 }; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵʱ<CAB5><CAB1><EFBFBD>ݶ<EFBFBD>ȡ<EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ţ<EFBFBD>ԭ<EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>
|
||||
uint64_t read_runninginformationMsg = 0; // װ<>ö<EFBFBD>ʱ<EFBFBD><CAB1>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʱ<CFA2><CAB1><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>
|
||||
@@ -395,6 +400,12 @@ public:
|
||||
|
||||
//<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ <20><><EFBFBD><EFBFBD>mac/id + <20>ڲ<EFBFBD><DAB2><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>
|
||||
bool set_interfixedvalue_action_to_device(const std::string& identifier, const std::vector<uint16_t>& values);
|
||||
|
||||
//<2F><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
bool read_runninginformation_action_to_device(const std::string& identifier);
|
||||
|
||||
//<2F><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
bool read_devversion_action_to_device(const std::string& identifier);
|
||||
private:
|
||||
ClientManager() : loop_(nullptr) {}
|
||||
std::unordered_map<std::string, std::unique_ptr<ClientContext>> clients_;
|
||||
|
||||
@@ -79,6 +79,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
|
||||
//ClientManager::instance().get_interfixedvalue_action_to_device(id);//װ<>û<EFBFBD>ȡ<EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD>ֵ
|
||||
//ClientManager::instance().get_fixedvalucontrolword_action_to_device(id,1);//<2F><>ȡ 1-<2D>ڲ<EFBFBD><DAB2><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> 2-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
//ClientManager::instance().set_interfixedvalue_action_to_device();װ<><D7B0><EFBFBD><EFBFBD><DEB8>ڲ<EFBFBD><DAB2><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ԣ<EFBFBD><D4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD>ṩ<EFBFBD><E1B9A9>
|
||||
//ClientManager::instance().read_runninginformation_action_to_device(id);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
ClientManager::instance().read_devversion_action_to_device(id);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
}
|
||||
if (udata[19] == 0x00) {
|
||||
std::cout << "cloud login: " << mac << " state: fail!" << std::endl;
|
||||
@@ -1179,6 +1181,575 @@ void process_received_message(string mac, string id,const char* data, size_t len
|
||||
}
|
||||
break;
|
||||
|
||||
case DeviceState::READING_RUNNINGINFORMATION_1:
|
||||
//<2F><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Read_RunningInformation)) {
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t>& recvData = parser.RecvData;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>㹻
|
||||
if (recvData.size() < 2) {
|
||||
std::cerr << "Invalid running information data: too short ("
|
||||
<< recvData.size() << " bytes)" << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>Ч<EFBFBD>غɳ<D8BA><C9B3><EFBFBD>
|
||||
size_t payloadLength = recvData.size() - 2;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>غ<EFBFBD><D8BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t> payloadBytes(payloadLength);
|
||||
if (recvData.size() >= 2 + payloadLength) {
|
||||
std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin());
|
||||
}
|
||||
else {
|
||||
std::cerr << "Invalid payload length: " << payloadLength
|
||||
<< ", available: " << (recvData.size() - 2) << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// ת<><D7AA>ΪUTF-8<>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string payload(payloadBytes.begin(), payloadBytes.end());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>New_MachMessage<67>Ľṹ<C4BD><E1B9B9>
|
||||
struct RunningInformation {
|
||||
std::string Time;
|
||||
std::string CpuLoad;
|
||||
std::string FreeMemory;
|
||||
std::string TotalMemory;
|
||||
std::string FreeStorage;
|
||||
std::string TotalStorage;
|
||||
std::string HardTimeSync;
|
||||
std::string SntpTimeSync;
|
||||
std::string CloudTimeSync;
|
||||
std::string SignalStrength;
|
||||
} result;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
auto trimQuotes = [](const std::string& str) -> std::string {
|
||||
if (str.size() >= 2 && str.front() == '"' && str.back() == '"') {
|
||||
return str.substr(1, str.size() - 2);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CPU<50><55><EFBFBD><EFBFBD>ֵ
|
||||
auto processCpuLoad = [](const std::string& cpuValue) -> std::string {
|
||||
if (cpuValue.empty()) return cpuValue;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>"39_38"<22><>
|
||||
if (cpuValue.find('_') != std::string::npos) {
|
||||
std::vector<std::string> cores;
|
||||
size_t start = 0, end;
|
||||
while ((end = cpuValue.find('_', start)) != std::string::npos) {
|
||||
cores.push_back(cpuValue.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
cores.push_back(cpuValue.substr(start)); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
|
||||
|
||||
for (auto& core : cores) {
|
||||
// <20>ֶ<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>std::stoi<6F><69>
|
||||
const char* str = core.c_str();
|
||||
char* endptr = nullptr;
|
||||
long value = strtol(str, &endptr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endptr != str && *endptr == '\0') {
|
||||
// У<><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χֵ
|
||||
if (value > 100) value /= 100;
|
||||
core = std::to_string(value);
|
||||
}
|
||||
// ת<><D7AA>ʧ<EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD>ԭֵ
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (size_t i = 0; i < cores.size(); ++i) {
|
||||
if (i > 0) result += '_';
|
||||
result += cores[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD>ʽ
|
||||
else {
|
||||
const char* str = cpuValue.c_str();
|
||||
char* endptr = nullptr;
|
||||
long value = strtol(str, &endptr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endptr != str && *endptr == '\0') {
|
||||
if (value > 100) value /= 100;
|
||||
return std::to_string(value);
|
||||
}
|
||||
return cpuValue;
|
||||
}
|
||||
};
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8>ֶβ<D6B6><CEB2><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<std::string> fields;
|
||||
size_t start = 0;
|
||||
while (start < payload.length()) {
|
||||
size_t end = payload.find(',', start);
|
||||
if (end == std::string::npos) {
|
||||
fields.push_back(payload.substr(start));
|
||||
break;
|
||||
}
|
||||
fields.push_back(payload.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
for (const auto& field : fields) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
|
||||
if (field.empty()) continue;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ð<EFBFBD><C3B0>λ<EFBFBD><CEBB>
|
||||
size_t colonPos = field.find(':');
|
||||
if (colonPos == std::string::npos || colonPos == 0 || colonPos == field.length() - 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8><EFBFBD>ֵ<EFBFBD><D6B5>
|
||||
std::string key = field.substr(0, colonPos);
|
||||
std::string value = field.substr(colonPos + 1);
|
||||
|
||||
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>Ŀհ<C4BF>
|
||||
size_t keyStart = key.find_first_not_of(" \t");
|
||||
size_t keyEnd = key.find_last_not_of(" \t");
|
||||
if (keyStart != std::string::npos && keyEnd != std::string::npos) {
|
||||
key = key.substr(keyStart, keyEnd - keyStart + 1);
|
||||
}
|
||||
|
||||
// ȥ<><C8A5>ֵ<EFBFBD>Ŀհ<C4BF>
|
||||
size_t valStart = value.find_first_not_of(" \t");
|
||||
size_t valEnd = value.find_last_not_of(" \t");
|
||||
if (valStart != std::string::npos && valEnd != std::string::npos) {
|
||||
value = value.substr(valStart, valEnd - valStart + 1);
|
||||
}
|
||||
|
||||
// ȥ<><C8A5>ֵ<EFBFBD><D6B5><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (value.size() >= 2 && value.front() == '"' && value.back() == '"') {
|
||||
value = value.substr(1, value.size() - 2);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
||||
const char* keyStr = key.c_str();
|
||||
char* endPtr = nullptr;
|
||||
long fieldId = strtol(keyStr, &endPtr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endPtr != keyStr && *endPtr == '\0' && fieldId >= 1 && fieldId <= 10) {
|
||||
switch (fieldId) {
|
||||
case 1: result.Time = value; break;
|
||||
case 2: result.CpuLoad = value; break;
|
||||
case 3: result.FreeMemory = value; break;
|
||||
case 4: result.TotalMemory = value; break;
|
||||
case 5: result.FreeStorage = value; break;
|
||||
case 6: result.TotalStorage = value; break;
|
||||
case 7: result.HardTimeSync = value; break;
|
||||
case 8: result.SntpTimeSync = value; break;
|
||||
case 9: result.CloudTimeSync = value; break;
|
||||
case 10: result.SignalStrength = value; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><E2B4A6>CPU<50><55><EFBFBD><EFBFBD>
|
||||
result.CpuLoad = processCpuLoad(result.CpuLoad);
|
||||
|
||||
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>Ӧ<EFBFBD><D3A6><EFBFBD>п<EFBFBD><D0BF>滻Ϊ<E6BBBB><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD>
|
||||
std::cout << "Device Running Information (" << mac << "):\n"
|
||||
<< " Time: " << result.Time << "\n"
|
||||
<< " CPU Load: " << result.CpuLoad << "\n"
|
||||
<< " Memory: " << result.FreeMemory << "/" << result.TotalMemory << " MB\n"
|
||||
<< " Storage: " << result.FreeStorage << "/" << result.TotalStorage << " GB\n"
|
||||
<< " Time Sync: Hard=" << result.HardTimeSync
|
||||
<< ", SNTP=" << result.SntpTimeSync
|
||||
<< ", Cloud=" << result.CloudTimeSync << "\n"
|
||||
<< " Signal: " << result.SignalStrength << std::endl;
|
||||
|
||||
//<2F><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
}
|
||||
else {
|
||||
// װ<>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||
// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)ʧ<>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><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_RUNNINGINFORMATION_2:
|
||||
//<2F><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD><C2A3><EFBFBD><EFBFBD><EFBFBD><DEB8><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7>Ͳ<EFBFBD><CDB2><EFBFBD>
|
||||
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Read_RunningInformation)) {
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t>& recvData = parser.RecvData;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>㹻
|
||||
if (recvData.size() < 2) {
|
||||
std::cerr << "Invalid running information data: too short ("
|
||||
<< recvData.size() << " bytes)" << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>Ч<EFBFBD>غɳ<D8BA><C9B3><EFBFBD>
|
||||
size_t payloadLength = recvData.size() - 2;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>غ<EFBFBD><D8BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t> payloadBytes(payloadLength);
|
||||
if (recvData.size() >= 2 + payloadLength) {
|
||||
std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin());
|
||||
}
|
||||
else {
|
||||
std::cerr << "Invalid payload length: " << payloadLength
|
||||
<< ", available: " << (recvData.size() - 2) << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// ת<><D7AA>ΪUTF-8<>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string payload(payloadBytes.begin(), payloadBytes.end());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>New_MachMessage<67>Ľṹ<C4BD><E1B9B9>
|
||||
struct RunningInformation {
|
||||
std::string Time;
|
||||
std::string CpuLoad;
|
||||
std::string FreeMemory;
|
||||
std::string TotalMemory;
|
||||
std::string FreeStorage;
|
||||
std::string TotalStorage;
|
||||
std::string HardTimeSync;
|
||||
std::string SntpTimeSync;
|
||||
std::string CloudTimeSync;
|
||||
std::string SignalStrength;
|
||||
} result;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
auto trimQuotes = [](const std::string& str) -> std::string {
|
||||
if (str.size() >= 2 && str.front() == '"' && str.back() == '"') {
|
||||
return str.substr(1, str.size() - 2);
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CPU<50><55><EFBFBD><EFBFBD>ֵ
|
||||
auto processCpuLoad = [](const std::string& cpuValue) -> std::string {
|
||||
if (cpuValue.empty()) return cpuValue;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>"39_38"<22><>
|
||||
if (cpuValue.find('_') != std::string::npos) {
|
||||
std::vector<std::string> cores;
|
||||
size_t start = 0, end;
|
||||
while ((end = cpuValue.find('_', start)) != std::string::npos) {
|
||||
cores.push_back(cpuValue.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
cores.push_back(cpuValue.substr(start)); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
|
||||
|
||||
for (auto& core : cores) {
|
||||
// <20>ֶ<EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>std::stoi<6F><69>
|
||||
const char* str = core.c_str();
|
||||
char* endptr = nullptr;
|
||||
long value = strtol(str, &endptr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endptr != str && *endptr == '\0') {
|
||||
// У<><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χֵ
|
||||
if (value > 100) value /= 100;
|
||||
core = std::to_string(value);
|
||||
}
|
||||
// ת<><D7AA>ʧ<EFBFBD>ܱ<EFBFBD><DCB1><EFBFBD>ԭֵ
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (size_t i = 0; i < cores.size(); ++i) {
|
||||
if (i > 0) result += '_';
|
||||
result += cores[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˸<EFBFBD>ʽ
|
||||
else {
|
||||
const char* str = cpuValue.c_str();
|
||||
char* endptr = nullptr;
|
||||
long value = strtol(str, &endptr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endptr != str && *endptr == '\0') {
|
||||
if (value > 100) value /= 100;
|
||||
return std::to_string(value);
|
||||
}
|
||||
return cpuValue;
|
||||
}
|
||||
};
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8>ֶβ<D6B6><CEB2><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<std::string> fields;
|
||||
size_t start = 0;
|
||||
while (start < payload.length()) {
|
||||
size_t end = payload.find(',', start);
|
||||
if (end == std::string::npos) {
|
||||
fields.push_back(payload.substr(start));
|
||||
break;
|
||||
}
|
||||
fields.push_back(payload.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
for (const auto& field : fields) {
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
|
||||
if (field.empty()) continue;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ð<EFBFBD><C3B0>λ<EFBFBD><CEBB>
|
||||
size_t colonPos = field.find(':');
|
||||
if (colonPos == std::string::npos || colonPos == 0 || colonPos == field.length() - 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8><EFBFBD>ֵ<EFBFBD><D6B5>
|
||||
std::string key = field.substr(0, colonPos);
|
||||
std::string value = field.substr(colonPos + 1);
|
||||
|
||||
// ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD>Ŀհ<C4BF>
|
||||
size_t keyStart = key.find_first_not_of(" \t");
|
||||
size_t keyEnd = key.find_last_not_of(" \t");
|
||||
if (keyStart != std::string::npos && keyEnd != std::string::npos) {
|
||||
key = key.substr(keyStart, keyEnd - keyStart + 1);
|
||||
}
|
||||
|
||||
// ȥ<><C8A5>ֵ<EFBFBD>Ŀհ<C4BF>
|
||||
size_t valStart = value.find_first_not_of(" \t");
|
||||
size_t valEnd = value.find_last_not_of(" \t");
|
||||
if (valStart != std::string::npos && valEnd != std::string::npos) {
|
||||
value = value.substr(valStart, valEnd - valStart + 1);
|
||||
}
|
||||
|
||||
// ȥ<><C8A5>ֵ<EFBFBD><D6B5><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD>
|
||||
if (value.size() >= 2 && value.front() == '"' && value.back() == '"') {
|
||||
value = value.substr(1, value.size() - 2);
|
||||
}
|
||||
|
||||
// <20><><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>
|
||||
const char* keyStr = key.c_str();
|
||||
char* endPtr = nullptr;
|
||||
long fieldId = strtol(keyStr, &endPtr, 10);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
||||
if (endPtr != keyStr && *endPtr == '\0' && fieldId >= 1 && fieldId <= 10) {
|
||||
switch (fieldId) {
|
||||
case 1: result.Time = value; break;
|
||||
case 2: result.CpuLoad = value; break;
|
||||
case 3: result.FreeMemory = value; break;
|
||||
case 4: result.TotalMemory = value; break;
|
||||
case 5: result.FreeStorage = value; break;
|
||||
case 6: result.TotalStorage = value; break;
|
||||
case 7: result.HardTimeSync = value; break;
|
||||
case 8: result.SntpTimeSync = value; break;
|
||||
case 9: result.CloudTimeSync = value; break;
|
||||
case 10: result.SignalStrength = value; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><E2B4A6>CPU<50><55><EFBFBD><EFBFBD>
|
||||
result.CpuLoad = processCpuLoad(result.CpuLoad);
|
||||
|
||||
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5>Ӧ<EFBFBD><D3A6><EFBFBD>п<EFBFBD><D0BF>滻Ϊ<E6BBBB><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD>
|
||||
std::cout << "Device Running Information (" << mac << "):\n"
|
||||
<< " Time: " << result.Time << "\n"
|
||||
<< " CPU Load: " << result.CpuLoad << "\n"
|
||||
<< " Memory: " << result.FreeMemory << "/" << result.TotalMemory << " MB\n"
|
||||
<< " Storage: " << result.FreeStorage << "/" << result.TotalStorage << " GB\n"
|
||||
<< " Time Sync: Hard=" << result.HardTimeSync
|
||||
<< ", SNTP=" << result.SntpTimeSync
|
||||
<< ", Cloud=" << result.CloudTimeSync << "\n"
|
||||
<< " Signal: " << result.SignalStrength << std::endl;
|
||||
|
||||
//<2F><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
}
|
||||
else {
|
||||
// װ<>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||
// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>)ʧ<>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><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_DEVVERSION:
|
||||
//<2F><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ȡ<EFBFBD><C8A1>(<28><>άЭ<CEAC><D0AD>ȷ<EFBFBD>϶<EFBFBD>ʱ<EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶг<C6B5><D0B3><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Read_RunningInformation)) {
|
||||
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t>& recvData = parser.RecvData;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>㹻
|
||||
if (recvData.size() < 2) {
|
||||
std::cerr << "Invalid running information data: too short ("
|
||||
<< recvData.size() << " bytes)" << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// <20><>ȡ<EFBFBD><C8A1>Ч<EFBFBD>غɳ<D8BA><C9B3><EFBFBD>
|
||||
size_t payloadLength = recvData.size() - 2;
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>غ<EFBFBD><D8BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::vector<uint8_t> payloadBytes(payloadLength);
|
||||
if (recvData.size() >= 2 + payloadLength) {
|
||||
std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin());
|
||||
}
|
||||
else {
|
||||
std::cerr << "Invalid payload length: " << payloadLength
|
||||
<< ", available: " << (recvData.size() - 2) << std::endl;
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
// ת<><D7AA>ΪUTF-8<>ַ<EFBFBD><D6B7><EFBFBD>
|
||||
std::string payload(payloadBytes.begin(), payloadBytes.end());
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>洢װ<E6B4A2>ð汾<C3B0><E6B1BE>Ϣ<EFBFBD>Ľṹ<C4BD><E1B9B9>
|
||||
struct DeviceVersionInfo {
|
||||
std::string BaseModel; // 1: װ<>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ͺ<EFBFBD>
|
||||
std::string CloudProtocolVer; // 2: <20>Ʒ<EFBFBD><C6B7><EFBFBD>Э<EFBFBD><D0AD><EFBFBD>汾
|
||||
std::string AppVersion; // 3: Ӧ<>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>汾<EFBFBD><E6B1BE>
|
||||
std::string AppDate; // 4: Ӧ<>ó<EFBFBD><C3B3><EFBFBD><EFBFBD>汾<EFBFBD><E6B1BE><EFBFBD><EFBFBD>
|
||||
std::string AppChecksum; // 5: Ӧ<>ó<EFBFBD><C3B3><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>
|
||||
std::string VoltageWiring; // 6: <20><>ѹ<EFBFBD><D1B9><EFBFBD>߷<EFBFBD>ʽ
|
||||
std::string CurrentBSynthetic; // 7: <20><><EFBFBD><EFBFBD>B<EFBFBD><42><EFBFBD>Ƿ<EFBFBD><C7B7>ϳ<EFBFBD>
|
||||
int DataStatInterval = 0; // 8: <20><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
|
||||
float RatedVoltage = 0.0f; // 9: <20><EFBFBD><EEB6A8>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>λV<CEBB><56>
|
||||
float PTRatio = 0.0f; // 10: PT<50><54><EFBFBD><EFBFBD>
|
||||
float CTRatio = 0.0f; // 11: CT<43><54><EFBFBD><EFBFBD>
|
||||
std::string SntpIP; // 12: sntp<74><70>ʱIP
|
||||
int SntpPort = 0; // 13: sntp<74><70>ʱ<EFBFBD>˿<EFBFBD>
|
||||
int SntpInterval = 0; // 14: sntp<74><70>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
|
||||
int WebPort = 0; // 15: Web<65>˿<EFBFBD>
|
||||
int FtpPort = 0; // 16: ftp<74>˿<EFBFBD>
|
||||
int PqdifInterval = 0; // 17: Pqdif<69>ļ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сʱ<D0A1><CAB1>
|
||||
int WaveFileTypeCount = 0; // 18: ¼<><C2BC><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::string SpecialVersion; // 19: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>汾<EFBFBD><E6B1BE>Ϣ
|
||||
std::string DeviceModel; // 20: װ<><D7B0><EFBFBD>ͺ<EFBFBD>
|
||||
int HarmonicEnergyFlag = 0; // 21: г<><D0B3><EFBFBD><EFBFBD><EFBFBD>Ȱ汾<C8B0><E6B1BE>־
|
||||
std::string PhysicalName; // 22: <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD>
|
||||
std::string WaveLDName; // 23: ¼<><C2BC>LD<4C><44><EFBFBD><EFBFBD>
|
||||
int HighFreqHarmonicFlag = 0; // 24: <20><>Ƶг<C6B5><D0B3><EFBFBD><EFBFBD><EFBFBD>ܱ<EFBFBD>־
|
||||
unsigned int CommProtocols = 0; // 51: Ͷ<><CDB6><EFBFBD><EFBFBD>ͨѶЭ<D1B6><D0AD>
|
||||
unsigned int TimeSyncMethods = 0;// 52: Ͷ<><CDB6><EFBFBD>Ķ<EFBFBD>ʱ<EFBFBD><CAB1>ʽ
|
||||
unsigned int DeviceFunctions = 0;// 53: װ<>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
} versionInfo;
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8>ֶ<EFBFBD>
|
||||
std::vector<std::string> fields;
|
||||
size_t start = 0;
|
||||
while (start < payload.length()) {
|
||||
size_t end = payload.find(',', start);
|
||||
if (end == std::string::npos) {
|
||||
fields.push_back(payload.substr(start));
|
||||
break;
|
||||
}
|
||||
fields.push_back(payload.substr(start, end - start));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD>ֶ<EFBFBD>
|
||||
for (const auto& field : fields) {
|
||||
if (field.empty()) continue;
|
||||
|
||||
// <20>ָ<EFBFBD><D6B8><EFBFBD>ֵ<EFBFBD><D6B5>
|
||||
size_t colonPos = field.find(':');
|
||||
if (colonPos == std::string::npos || colonPos == 0) continue;
|
||||
|
||||
std::string key = field.substr(0, colonPos);
|
||||
std::string value = field.substr(colonPos + 1);
|
||||
|
||||
// ȥ<><C8A5><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>˵Ŀհ<D5B0><D7BA><EFBFBD><EFBFBD><EFBFBD>
|
||||
auto trim = [](std::string str) -> std::string {
|
||||
size_t start = str.find_first_not_of(" \t\"");
|
||||
size_t end = str.find_last_not_of(" \t\"");
|
||||
return (start == std::string::npos) ? "" : str.substr(start, end - start + 1);
|
||||
};
|
||||
key = trim(key);
|
||||
value = trim(value);
|
||||
|
||||
// ת<><D7AA>Ϊ<EFBFBD><CEAA>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ID
|
||||
try {
|
||||
int fieldId = std::stoi(key);
|
||||
switch (fieldId) {
|
||||
// <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
|
||||
case 1: versionInfo.BaseModel = value; break;
|
||||
case 2: versionInfo.CloudProtocolVer = value; break;
|
||||
case 3: versionInfo.AppVersion = value; break;
|
||||
case 4: versionInfo.AppDate = value; break;
|
||||
case 5: versionInfo.AppChecksum = value; break;
|
||||
case 6: versionInfo.VoltageWiring = value; break;
|
||||
case 7: versionInfo.CurrentBSynthetic = value; break;
|
||||
case 12: versionInfo.SntpIP = value; break;
|
||||
case 19: versionInfo.SpecialVersion = value; break;
|
||||
case 20: versionInfo.DeviceModel = value; break;
|
||||
case 22: versionInfo.PhysicalName = value; break;
|
||||
case 23: versionInfo.WaveLDName = value; break;
|
||||
|
||||
// <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>
|
||||
case 8: versionInfo.DataStatInterval = std::stoi(value); break;
|
||||
case 9: versionInfo.RatedVoltage = std::stof(value); break;
|
||||
case 10: versionInfo.PTRatio = std::stof(value); break;
|
||||
case 11: versionInfo.CTRatio = std::stof(value); break;
|
||||
case 13: versionInfo.SntpPort = std::stoi(value); break;
|
||||
case 14: versionInfo.SntpInterval = std::stoi(value); break;
|
||||
case 15: versionInfo.WebPort = std::stoi(value); break;
|
||||
case 16: versionInfo.FtpPort = std::stoi(value); break;
|
||||
case 17: versionInfo.PqdifInterval = std::stoi(value); break;
|
||||
case 18: versionInfo.WaveFileTypeCount = std::stoi(value); break;
|
||||
case 21: versionInfo.HarmonicEnergyFlag = std::stoi(value); break;
|
||||
case 24: versionInfo.HighFreqHarmonicFlag = std::stoi(value); break;
|
||||
|
||||
// ʮ<><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶΣ<D6B6>51+<2B><>
|
||||
case 51:
|
||||
case 52:
|
||||
case 53: {
|
||||
if (value.size() > 2 && value.substr(0, 2) == "0x") {
|
||||
unsigned int hexValue = std::stoul(value.substr(2), nullptr, 16);
|
||||
switch (fieldId) {
|
||||
case 51: versionInfo.CommProtocols = hexValue; break;
|
||||
case 52: versionInfo.TimeSyncMethods = hexValue; break;
|
||||
case 53: versionInfo.DeviceFunctions = hexValue; break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
std::cerr << "Error parsing field: " << field
|
||||
<< ", error: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
std::cout << "Device Version Info (" << mac << "):\n"
|
||||
<< " Base Model: " << versionInfo.BaseModel << "\n"
|
||||
<< " Cloud Protocol: " << versionInfo.CloudProtocolVer << "\n"
|
||||
<< " App Version: " << versionInfo.AppVersion << "\n"
|
||||
<< " App Date: " << versionInfo.AppDate << "\n"
|
||||
<< " PT Ratio: " << versionInfo.PTRatio << "\n"
|
||||
<< " CT Ratio: " << versionInfo.CTRatio << "\n"
|
||||
<< " Wave File Types: " << versionInfo.WaveFileTypeCount << "\n"
|
||||
<< " Comm Protocols: 0x" << std::hex << versionInfo.CommProtocols << "\n"
|
||||
<< " Time Sync Methods: 0x" << versionInfo.TimeSyncMethods << "\n"
|
||||
<< " Device Functions: 0x" << versionInfo.DeviceFunctions << std::dec << "\n";
|
||||
|
||||
//<2F><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
|
||||
}
|
||||
else {
|
||||
// װ<>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>쳣
|
||||
// <20><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣʧ<CFA2>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><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;
|
||||
|
||||
@@ -154,27 +154,27 @@ void* client_manager_thread(void* arg) {
|
||||
printf("Started client connections\n");
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/*std::vector<PointInfo> points1 = {
|
||||
std::vector<PointInfo> points1 = {
|
||||
{"P001", "Main Voltage", "D001",1 ,1, 1, 1, 1,"0.38k",0},
|
||||
{"P002", "Backup Voltage", "D001",2 ,1, 1, 1, 1,"0.38k",0}
|
||||
};
|
||||
//00B78DA800D6 00-B7-8D-01-79-06
|
||||
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>б<EFBFBD>
|
||||
/*std::vector<DeviceInfo> devices = {
|
||||
std::vector<DeviceInfo> devices = {
|
||||
{
|
||||
"D001", "Primary Device", "Model-X", "00-B7-8D-01-79-06",
|
||||
1, points1
|
||||
1, points1,true
|
||||
}
|
||||
};*/
|
||||
};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>100<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
|
||||
//std::vector<DeviceInfo> test_devices = generate_test_devices(100);
|
||||
|
||||
//lnk<6E><6B>̨<EFBFBD>˶<EFBFBD>ȡ<EFBFBD>豸
|
||||
std::vector<DeviceInfo> devices = GenerateDeviceInfoFromLedger(terminal_devlist);//lnk<6E><6B><EFBFBD><EFBFBD>
|
||||
//std::vector<DeviceInfo> devices = GenerateDeviceInfoFromLedger(terminal_devlist);//lnk<6E><6B><EFBFBD><EFBFBD>
|
||||
|
||||
//̨<>˴<EFBFBD>ӡ
|
||||
PrintDevices(devices);
|
||||
//PrintDevices(devices);
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
start_client_connect(devices);
|
||||
@@ -319,10 +319,10 @@ int main(int argc ,char** argv) {//
|
||||
cleanup_args(args);
|
||||
}
|
||||
|
||||
while(!INITFLAG){
|
||||
/*while(!INITFLAG){
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
std::cout << "waiting cloudfront initialize ..." << std::endl;
|
||||
}
|
||||
}*/
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD>
|
||||
for (int i = 1; i < THREAD_CONNECTIONS; i++) {
|
||||
@@ -396,7 +396,7 @@ int main(int argc ,char** argv) {//
|
||||
std::vector<DeviceInfo> devices = {
|
||||
{
|
||||
"D002", "Backup Device", "Model-Y", "00-B7-8D-A8-00-D6",
|
||||
1, points2
|
||||
1, points2,true
|
||||
}
|
||||
};
|
||||
|
||||
@@ -405,10 +405,10 @@ int main(int argc ,char** argv) {//
|
||||
//static int count = 3;
|
||||
if (++queue_monitor >= 20) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>豸
|
||||
printf("Message queue size: %zu\n", message_queue.size());
|
||||
//queue_monitor = 0;
|
||||
queue_monitor = 0;
|
||||
|
||||
for (const auto& device : devices) {
|
||||
ClientManager::instance().add_device(device);
|
||||
//ClientManager::instance().add_device(device);
|
||||
}
|
||||
|
||||
/*std::vector<DeviceInfo> test_devices = generate_test_devices(count);
|
||||
|
||||
Reference in New Issue
Block a user