添加了实时数据的报文组装
This commit is contained in:
@@ -203,5 +203,37 @@ std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_
|
|||||||
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Stat));
|
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Stat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//ѯ<><D1AF>ʵʱ<CAB5><CAB1><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD> <20><><EFBFBD><EFBFBD>1-6 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1-11 г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0-2
|
||||||
|
std::vector<unsigned char> generate_realstat_message(unsigned char nCpuNo,
|
||||||
|
unsigned char StaTtype,
|
||||||
|
unsigned char flag)
|
||||||
|
{
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD>С<EFBFBD><D0A1>3(<28><><EFBFBD><EFBFBD>) + 1(nCpuNo) + 1(StaTtype) + 1(<28>̶<EFBFBD>ֵ) + 1(flag)
|
||||||
|
const size_t totalSize = 7;
|
||||||
|
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>nCpuNo<4E><6F>1<EFBFBD>ֽڣ<D6BD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-6
|
||||||
|
memcpy(DataBuf.data() + offset, &nCpuNo, sizeof(unsigned char));
|
||||||
|
offset += sizeof(unsigned char);
|
||||||
|
|
||||||
|
// 3. д<><D0B4>StaTtype<70><65>1<EFBFBD>ֽڣ<D6BD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-11 һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-6
|
||||||
|
memcpy(DataBuf.data() + offset, &StaTtype, sizeof(unsigned char));
|
||||||
|
offset += sizeof(unsigned char);
|
||||||
|
|
||||||
|
// 4. д<><D0B4><EFBFBD>̶<EFBFBD>ֵ1<D6B5><31>1<EFBFBD>ֽڣ<D6BD> 3<><33>ʵʱ<CAB5><CAB1><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD>1 <20><>ʾƽ<CABE><C6BD>ֵ
|
||||||
|
const unsigned char fixedValue = 1;
|
||||||
|
memcpy(DataBuf.data() + offset, &fixedValue, sizeof(unsigned char));
|
||||||
|
offset += sizeof(unsigned char);
|
||||||
|
|
||||||
|
// 5. д<><D0B4>flag<61><67>1<EFBFBD>ֽڣ<D6BD> <20><>־λ 0-2 г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 25 50 100<30><30>
|
||||||
|
memcpy(DataBuf.data() + offset, &flag, sizeof(unsigned char));
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_New_3S));
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,14 +21,18 @@ enum class MsgRequestType : unsigned char {
|
|||||||
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
Request_StatTime = 0x8b,
|
Request_StatTime = 0x8b,
|
||||||
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
Request_Stat = 0x8a
|
Request_Stat = 0x8a,
|
||||||
|
//ѯ<><D1AF>ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>
|
||||||
|
Request_New_3S = 0x04
|
||||||
};
|
};
|
||||||
// <20><><EFBFBD>ձ<EFBFBD><D5B1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
|
// <20><><EFBFBD>ձ<EFBFBD><D5B1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
|
||||||
enum class MsgResponseType : unsigned char {
|
enum class MsgResponseType : unsigned char {
|
||||||
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
|
||||||
Response_StatTime = 0x27,
|
Response_StatTime = 0x27,
|
||||||
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
Response_Stat = 0x26
|
Response_Stat = 0x26,
|
||||||
|
//ѯ<><D1AF>ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>
|
||||||
|
Response_New_3S = 0x84
|
||||||
};
|
};
|
||||||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>ṹ
|
||||||
class MessageParser {
|
class MessageParser {
|
||||||
@@ -803,3 +807,5 @@ std::vector<unsigned char> generate_frontlogin_message(const std::string& strMac
|
|||||||
std::vector<unsigned char> generate_statequerytime_message();
|
std::vector<unsigned char> generate_statequerytime_message();
|
||||||
//<2F><><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
|
//<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);
|
std::vector<unsigned char> generate_statequerystat_message(tagTime time, uint16_t nDeviceNo, uint16_t nDataType);
|
||||||
|
//<2F><><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF>ʵʱ<CAB5><CAB1><EFBFBD>ݱ<EFBFBD><DDB1><EFBFBD>
|
||||||
|
std::vector<unsigned char> generate_realstat_message(unsigned char nCpuNo, unsigned char StaTtype, unsigned char flag);
|
||||||
@@ -53,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, 5000,5000);
|
uv_timer_start(&timer, on_timer, 1000,1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,29 +355,36 @@ void on_write(uv_write_t* req, int status) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 定时发送回调 */
|
/* 定时发送回调 */
|
||||||
//5秒执行一次定时器
|
//1秒执行一次定时器
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int statequerytime = 0;//询问统计数据时间标志 20秒执行一次
|
|
||||||
|
|
||||||
// 检查状态超时 30秒状态未更新则重置为空闲状态
|
// 检查状态超时 30秒状态未更新则重置为空闲状态
|
||||||
ctx->check_state_timeout();
|
ctx->check_state_timeout();
|
||||||
|
|
||||||
// 装置登录成功后,只在空闲状态处理后续动作
|
// 装置登录成功后,只在空闲状态处理后续动作
|
||||||
if (ctx->cloudstatus == 1) {
|
if (ctx->cloudstatus == 1) {
|
||||||
|
uint64_t now = uv_now(ctx->loop);//当前时间戳
|
||||||
//20秒一次 执行统计数据时间询问
|
//20秒一次 执行统计数据时间询问
|
||||||
if (++statequerytime >= 4 && ctx->current_state_ == DeviceState::IDLE) {
|
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->last_state_query_time_ >= 20000) {
|
||||||
statequerytime = 0;//重置计时
|
// 更新统计数据最后查询时间
|
||||||
|
ctx->last_state_query_time_ = now;
|
||||||
|
|
||||||
auto sendbuff = generate_statequerytime_message();//组装询问统计数据时间报文
|
auto sendbuff = generate_statequerytime_message();//组装询问统计数据时间报文
|
||||||
ctx->add_action(DeviceState::READING_STATS_TIME, sendbuff);//将该状态以及待发送报文存入队列
|
ctx->add_action(DeviceState::READING_STATS_TIME, sendbuff);//将该状态以及待发送报文存入队列
|
||||||
}
|
}
|
||||||
|
//一秒一次 执行实时数据询问 仅执行指定次数
|
||||||
|
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->real_state_query_time_ >= 1000 && ctx->real_state_count > 0) {
|
||||||
|
// 更新实时数据执行时间和实时收发计数
|
||||||
|
ctx->real_state_query_time_ = now;
|
||||||
|
ctx->real_state_count--;
|
||||||
|
|
||||||
|
//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);//将该状态以及待发送报文存入队列
|
||||||
|
}
|
||||||
//处理后续工作队列的工作 取出一个并执行
|
//处理后续工作队列的工作 取出一个并执行
|
||||||
if (ctx->current_state_ == DeviceState::IDLE) {
|
if (ctx->current_state_ == DeviceState::IDLE) {
|
||||||
ctx->process_next_action();
|
ctx->process_next_action();
|
||||||
@@ -489,7 +496,10 @@ 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;
|
||||||
|
// 新增:初始化各个计时时间戳
|
||||||
|
ctx->last_state_query_time_ = uv_now(ctx->loop);//初始化统计数据时间戳
|
||||||
|
ctx->real_state_query_time_ = uv_now(ctx->loop);//初始化实时数据时间戳
|
||||||
|
ctx->real_state_count = 0;//实时数据收发计数
|
||||||
//客户端连接完毕后,发送装置登陆消息
|
//客户端连接完毕后,发送装置登陆消息
|
||||||
std::cout << "connected: " << ctx->device_info.mac << " send login msg!" << std::endl;
|
std::cout << "connected: " << ctx->device_info.mac << " send login msg!" << std::endl;
|
||||||
auto binary_data = generate_frontlogin_message(ctx->device_info.mac);
|
auto binary_data = generate_frontlogin_message(ctx->device_info.mac);
|
||||||
@@ -974,3 +984,31 @@ bool ClientManager::clear_float_cache(const std::string& identifier) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ClientManager::set_real_state_count(const std::string& identifier, int count, ushort point_id = 1) {
|
||||||
|
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->real_state_count = count;
|
||||||
|
|
||||||
|
// 设置测点序号(如果提供了有效值)
|
||||||
|
if (point_id != 0) {
|
||||||
|
ctx->real_point_id_ = point_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "[Device " << identifier
|
||||||
|
<< "] Real state params set - count: " << count
|
||||||
|
<< ", point_id: " << ctx->real_point_id_.load()
|
||||||
|
<< std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "[set_real_state_count] Device not found: " << identifier << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@@ -43,6 +43,7 @@ enum class DeviceState {
|
|||||||
IDLE, // <20><><EFBFBD><EFBFBD>״̬
|
IDLE, // <20><><EFBFBD><EFBFBD>״̬
|
||||||
READING_STATS, // <20><>ȡͳ<C8A1><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
READING_STATS, // <20><>ȡͳ<C8A1><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
READING_STATS_TIME, // <20><>ȡͳ<C8A1><CDB3>ʱ<EFBFBD><CAB1>
|
READING_STATS_TIME, // <20><>ȡͳ<C8A1><CDB3>ʱ<EFBFBD><CAB1>
|
||||||
|
READING_REALSTAT, // <20><>ȡʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>
|
||||||
// <20>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>״̬
|
// <20>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>״̬
|
||||||
CUSTOM_ACTION // <20>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF>
|
CUSTOM_ACTION // <20>Զ<EFBFBD><D4B6>嶯<EFBFBD><E5B6AF>
|
||||||
};
|
};
|
||||||
@@ -62,6 +63,10 @@ public:
|
|||||||
ConnectionState state;
|
ConnectionState state;
|
||||||
int reconnect_attempts;
|
int reconnect_attempts;
|
||||||
volatile bool shutdown;
|
volatile bool shutdown;
|
||||||
|
uint64_t last_state_query_time_ = 0; // ͳ<><CDB3><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD>
|
||||||
|
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>
|
||||||
|
|
||||||
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>
|
int cloudstatus; // <20><>ǰ<EFBFBD>õ<EFBFBD>¼״̬<D7B4><CCAC>0<EFBFBD><30>δ<EFBFBD><CEB4>¼ 1<><31><EFBFBD>ѵ<EFBFBD>¼<EFBFBD><C2BC>
|
||||||
@@ -207,6 +212,8 @@ public:
|
|||||||
// <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8>㻺<EFBFBD><E3BBBA>
|
// <20><><EFBFBD><EFBFBD><EFBFBD>豸<EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD>и<EFBFBD><D0B8>㻺<EFBFBD><E3BBBA>
|
||||||
bool clear_float_cache(const std::string& identifier);
|
bool clear_float_cache(const std::string& identifier);
|
||||||
|
|
||||||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
bool set_real_state_count(const std::string& identifier, int count, ushort point_id = 1);
|
||||||
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_;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ void process_received_message(string mac, string id,const char* data, size_t len
|
|||||||
std::cout << "cloud login: " << mac << " state: success!" << std::endl;
|
std::cout << "cloud login: " << mac << " state: success!" << std::endl;
|
||||||
//װ<>õ<EFBFBD>¼<EFBFBD>ɹ<EFBFBD>
|
//װ<>õ<EFBFBD>¼<EFBFBD>ɹ<EFBFBD>
|
||||||
ClientManager::instance().set_cloud_status(id, 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>õ<EFBFBD>¼״̬Ϊ<CCAC>ѵ<EFBFBD>¼
|
ClientManager::instance().set_cloud_status(id, 1); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD>õ<EFBFBD>¼״̬Ϊ<CCAC>ѵ<EFBFBD>¼
|
||||||
|
//ClientManager::instance().set_real_state_count("D002", 10);//<2F><>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵʱ
|
||||||
}
|
}
|
||||||
if (udata[19] == 0x00) {
|
if (udata[19] == 0x00) {
|
||||||
std::cout << "cloud login: " << mac << " state: fail!" << std::endl;
|
std::cout << "cloud login: " << mac << " state: fail!" << std::endl;
|
||||||
|
|||||||
Reference in New Issue
Block a user