feat(vd960DBN): MQTT/TCP report_config 支持完整7参数配置
- 新增 ReportConfig 结构体 (sensor_type/enable/once/env_eval/interval/ack_required/timeout) - net_srv.c: MQTT report_config handler — 查询/设置均返回完整配置JSON - tcp_json_srv.c: TCP JSON handle_report_config 同步升级,兼容旧 active_report - iot_mqtt_srv.c: g_report_active → g_report_cfg.enable - g_report_active 全局变量替换为 g_report_cfg 结构体
This commit is contained in:
@@ -58,6 +58,19 @@ typedef struct {
|
||||
uint32_t deadline; // ms deadline for timeout
|
||||
} TcpJsonPending;
|
||||
|
||||
/*===========================================================================
|
||||
* Report Config
|
||||
*===========================================================================*/
|
||||
typedef struct {
|
||||
uint8_t enable; // 0=off, 1=on
|
||||
uint8_t sensor_type; // Sensor type, default 12
|
||||
uint8_t once; // 0=periodic, 1=single report
|
||||
uint8_t env_eval; // 0=skip, 1=environment evaluation
|
||||
uint16_t interval; // Report interval in seconds
|
||||
uint8_t ack_required; // 0=fire-and-forget, 1=ACK required
|
||||
uint16_t timeout; // Timeout in ms
|
||||
} ReportConfig;
|
||||
|
||||
/*===========================================================================
|
||||
* Externs
|
||||
*===========================================================================*/
|
||||
@@ -70,7 +83,7 @@ extern uint32_t g_json_last_comm_ts; // Last communication timestamp (ms)
|
||||
extern uint32_t g_json_last_connect_ts; // Last client connect timestamp (ms)
|
||||
extern uint8_t g_json_restart_count; // Auto-restart counter
|
||||
extern uint32_t g_json_restart_cooldown; // Cooldown deadline (ms)
|
||||
extern uint8_t g_report_active; // 0=inactive 1=active report
|
||||
extern ReportConfig g_report_cfg; // Active report configuration
|
||||
|
||||
/*===========================================================================
|
||||
* API
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
*===========================================================================*/
|
||||
|
||||
|
||||
extern uint8_t g_report_active; // from tcp_json_srv.c, 0=inactive 1=active
|
||||
extern ReportConfig g_report_cfg; // from tcp_json_srv.c
|
||||
extern uint8_t SocketId_TCP; // from net_srv.c, MQTT socket created by WCHNET_CreateTcpMqttSocket
|
||||
uint8_t g_iot_socket = 0xFF; // MQTT TCP socket ID
|
||||
IotMqttState g_iot_state = IOT_STATE_DISCONNECTED;
|
||||
@@ -372,7 +372,7 @@ static void iot_process_recv(void) {
|
||||
*===========================================================================*/
|
||||
void iot_mqtt_publish_sensor(void) {
|
||||
if (g_iot_state != IOT_STATE_READY) return;
|
||||
if (!g_report_active) return;
|
||||
if (!g_report_cfg.enable) return;
|
||||
|
||||
/* 复用 g_pkg_uart_2 中的传感器帧 */
|
||||
if (g_pkg_uart_2.flag == 0) return;
|
||||
|
||||
@@ -1252,6 +1252,73 @@ void manage_mqtt_recv_message(char * msg, int length)
|
||||
return;
|
||||
}
|
||||
|
||||
// --- report_config ---
|
||||
if(strcmp(cmd_str, "report_config") == 0) {
|
||||
char *data_buf = (char *)malloc(512);
|
||||
if(data_buf) {
|
||||
memset(data_buf, 0, 512);
|
||||
simple_parse_json(msg, "\"data\"", data_buf);
|
||||
|
||||
if(strlen(data_buf) > 0) {
|
||||
// sensor_type (int)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"sensor_type\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.sensor_type = (uint8_t)strtoul(tmp, NULL, 10);
|
||||
|
||||
// enable (bool)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"enable\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.enable = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||||
|
||||
// once (bool)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"once\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.once = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||||
|
||||
// env_eval (bool)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"env_eval\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.env_eval = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||||
|
||||
// interval (int)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"interval\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.interval = (uint16_t)strtoul(tmp, NULL, 10);
|
||||
|
||||
// ack_required (bool)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"ack_required\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.ack_required = (uint8_t)(strstr(tmp, "true") ? 1 : 0);
|
||||
|
||||
// timeout (int)
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
simple_parse_json(data_buf, "\"timeout\"", tmp);
|
||||
if(strlen(tmp) > 0) g_report_cfg.timeout = (uint16_t)strtoul(tmp, NULL, 10);
|
||||
}
|
||||
free(data_buf);
|
||||
}
|
||||
|
||||
char resp[400];
|
||||
snprintf(resp, sizeof(resp),
|
||||
"{\"msg_id\":%lu,\"cmd\":\"report_config\","
|
||||
"\"ts\":%lu,\"code\":0,\"msg\":\"success\","
|
||||
"\"data\":{"
|
||||
"\"sensor_type\":%d,\"enable\":%s,\"once\":%s,\"env_eval\":%s,"
|
||||
"\"interval\":%u,\"ack_required\":%s,\"timeout\":%u}}",
|
||||
msg_id, mstick() / 1000,
|
||||
g_report_cfg.sensor_type,
|
||||
g_report_cfg.enable ? "true" : "false",
|
||||
g_report_cfg.once ? "true" : "false",
|
||||
g_report_cfg.env_eval ? "true" : "false",
|
||||
g_report_cfg.interval,
|
||||
g_report_cfg.ack_required ? "true" : "false",
|
||||
g_report_cfg.timeout);
|
||||
mqtt_publish(resp_topic, resp, 1);
|
||||
PRINT("IOT: report_config enable=%d interval=%u sensor=%d\n",
|
||||
g_report_cfg.enable, g_report_cfg.interval, g_report_cfg.sensor_type);
|
||||
return;
|
||||
}
|
||||
|
||||
// --- 未支持的命令 ---
|
||||
{
|
||||
char resp[256];
|
||||
|
||||
@@ -31,7 +31,7 @@ uint32_t g_json_auth_timer = 0;
|
||||
uint8_t g_json_pwd_retry = 0;
|
||||
uint32_t g_json_lockout_timer = 0;
|
||||
TcpJsonPending g_json_pending = {0, 0, 0, "", 0};
|
||||
uint8_t g_report_active = 0; // 0=不主动上报, 1=主动上报传感器数据
|
||||
ReportConfig g_report_cfg = {0}; // 上电默认关闭上报
|
||||
uint32_t g_json_last_comm_ts = 0; // 最后通信时间戳
|
||||
uint32_t g_json_last_connect_ts = 0; // 最后连接时间戳
|
||||
uint8_t g_json_restart_count = 0; // 自动重启计数
|
||||
@@ -555,29 +555,85 @@ static void handle_loop_param_query(uint8_t socket, uint32_t msg_id, const char
|
||||
PRINT("JSON: loop_param_query sent\n");
|
||||
}
|
||||
|
||||
/* 4.15 report_config — 配置主动上报开关 */
|
||||
/* 4.15 report_config — 配置主动上报参数 */
|
||||
static void handle_report_config(uint8_t socket, uint32_t msg_id, const char *json) {
|
||||
char *data = json_get_data_str(json);
|
||||
if (!data) {
|
||||
json_send_error(socket, msg_id, "report_config", JSON_CODE_PARAM_ERR, "missing data");
|
||||
return;
|
||||
}
|
||||
if (data) {
|
||||
reset_tmp();
|
||||
|
||||
// Parse active_report flag
|
||||
reset_tmp();
|
||||
simple_parse_json(data, "\"active_report\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
if (strstr(g_tmp_value, "true")) {
|
||||
g_report_active = 1;
|
||||
} else {
|
||||
g_report_active = 0;
|
||||
// sensor_type (int)
|
||||
simple_parse_json(data, "\"sensor_type\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.sensor_type = (uint8_t)strtoul(g_tmp_value, NULL, 10);
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
|
||||
json_send_ok(socket, msg_id, "report_config",
|
||||
g_report_active ? "{\"active_report\":true}" : "{\"active_report\":false}");
|
||||
PRINT("JSON: report_config active_report=%d\n", g_report_active);
|
||||
// enable (bool)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"enable\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.enable = (uint8_t)(strstr(g_tmp_value, "true") ? 1 : 0);
|
||||
}
|
||||
|
||||
// once (bool)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"once\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.once = (uint8_t)(strstr(g_tmp_value, "true") ? 1 : 0);
|
||||
}
|
||||
|
||||
// env_eval (bool)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"env_eval\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.env_eval = (uint8_t)(strstr(g_tmp_value, "true") ? 1 : 0);
|
||||
}
|
||||
|
||||
// interval (int)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"interval\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.interval = (uint16_t)strtoul(g_tmp_value, NULL, 10);
|
||||
}
|
||||
|
||||
// ack_required (bool)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"ack_required\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.ack_required = (uint8_t)(strstr(g_tmp_value, "true") ? 1 : 0);
|
||||
}
|
||||
|
||||
// timeout (int)
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"timeout\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.timeout = (uint16_t)strtoul(g_tmp_value, NULL, 10);
|
||||
}
|
||||
|
||||
// 兼容旧协议 active_report
|
||||
memset(g_tmp_value, 0, sizeof(g_tmp_value));
|
||||
simple_parse_json(data, "\"active_report\"", g_tmp_value);
|
||||
if (strlen(g_tmp_value) > 0) {
|
||||
g_report_cfg.enable = (uint8_t)(strstr(g_tmp_value, "true") ? 1 : 0);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
char data_json[256];
|
||||
snprintf(data_json, sizeof(data_json),
|
||||
"{\"sensor_type\":%d,\"enable\":%s,\"once\":%s,\"env_eval\":%s,"
|
||||
"\"interval\":%u,\"ack_required\":%s,\"timeout\":%u}",
|
||||
g_report_cfg.sensor_type,
|
||||
g_report_cfg.enable ? "true" : "false",
|
||||
g_report_cfg.once ? "true" : "false",
|
||||
g_report_cfg.env_eval ? "true" : "false",
|
||||
g_report_cfg.interval,
|
||||
g_report_cfg.ack_required ? "true" : "false",
|
||||
g_report_cfg.timeout);
|
||||
|
||||
json_send_ok(socket, msg_id, "report_config", data_json);
|
||||
PRINT("JSON: report_config enable=%d interval=%u sensor=%d\\n",
|
||||
g_report_cfg.enable, g_report_cfg.interval, g_report_cfg.sensor_type);
|
||||
}
|
||||
|
||||
/* 4.16 loop_version_query — 获取地感MCU版本号 (CMD 0x4A) */
|
||||
@@ -758,12 +814,12 @@ static int format_loop_param_json(char *buf, uint16_t buf_size, const LUP_ParamG
|
||||
static void json_sensor_callback(const uint8_t *pkg, uint16_t len)
|
||||
{
|
||||
PRINT("JSON: sensor_cb enter socket=%d auth=%d report=%d\n",
|
||||
g_json_socket_listen, g_json_auth_state, g_report_active);
|
||||
g_json_socket_listen, g_json_auth_state, g_report_cfg.enable);
|
||||
|
||||
// Check: socket active, authed, report enabled
|
||||
if (g_json_socket_listen == 0xFF) { PRINT("JSON: sensor_cb skip: no socket\n"); return; }
|
||||
if (g_json_auth_state != JSON_STATE_AUTHED) { PRINT("JSON: sensor_cb skip: not authed\n"); return; }
|
||||
if (!g_report_active) { PRINT("JSON: sensor_cb skip: report disabled\n"); return; }
|
||||
if (!g_report_cfg.enable) { PRINT("JSON: sensor_cb skip: report disabled\\n"); return; }
|
||||
|
||||
LUP_SensorReport sr;
|
||||
memset(&sr, 0, sizeof(sr));
|
||||
@@ -1247,7 +1303,7 @@ void tcp_json_push_sensor(void) {
|
||||
// Check: socket active, authed, report enabled
|
||||
if (g_json_socket_listen == 0xFF) return;
|
||||
if (g_json_auth_state != JSON_STATE_AUTHED) return;
|
||||
if (!g_report_active) return; // 主动上报未开启
|
||||
if (!g_report_cfg.enable) return; // 主动上报未开启
|
||||
|
||||
// Only proceed if g_pkg_uart_2 has data and it's a 0xC0 sensor report
|
||||
if (g_pkg_uart_2.flag == 0) return;
|
||||
|
||||
Reference in New Issue
Block a user