feat: DBNetClient Loop命令完善 + vd960DBN 发送调试打印

vd960DBN:
- loop_uart_proto.c: 所有发送函数添加 LUP Tx 调试打印
- tcp_json_srv.c: 新增 loop_version_query/loop_reset/loop_factory_init/
  loop_sens_read/loop_sens_write 命令处理器 + 延迟响应解析
- 修复 loop_sens_write 未设置命令状态机和错误使用解析函数的问题

DBNetClient:
- tcp_json_client.py: 新增 full Loop MCU API (6 条命令)
- main.py: 线圈参数标签页增加版本/复位/出厂/灵敏度操作按钮
This commit is contained in:
wangfq
2026-07-02 10:33:11 +08:00
parent e9b58a660e
commit e9c24ae736
4 changed files with 296 additions and 27 deletions

View File

@@ -483,18 +483,30 @@ void lup_cmd_on_response(const uint8_t *pkg, uint16_t len)
* High-level Send Commands
*===========================================================================*/
static void lup_debug_tx(const uint8_t *buf, uint16_t len)
{
uint8_t i;
PRINT("LUP Tx:");
for (i = 0; i < len; i++) {
PRINT(" %02X", buf[i]);
}
PRINT("\n");
}
void lup_send_get_version(void)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_get_version(buf);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
lup_cmd_begin(LUP_CMD_GET_VERSION, 200); // 200ms timeout
lup_cmd_begin(LUP_CMD_GET_VERSION, 200);
}
void lup_send_reset(void)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_reset(buf);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
// No response expected
}
@@ -503,6 +515,7 @@ void lup_send_factory_init(void)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_factory_init(buf);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
lup_cmd_begin(LUP_CMD_FACTORY_INIT, 500);
}
@@ -511,6 +524,7 @@ void lup_send_sensitivity_read(void)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_sensitivity_read(buf);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
lup_cmd_begin(LUP_CMD_SENSITIVITY, 200);
}
@@ -519,6 +533,7 @@ void lup_send_set_param(const LUP_ParamSet *ps)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_set_param(buf, ps);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
lup_cmd_begin(LUP_CMD_SET_PARAM, 500);
}
@@ -527,6 +542,7 @@ void lup_send_get_param(void)
{
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_get_param(buf);
lup_debug_tx(buf, len);
UART2_SendString(buf, len);
lup_cmd_begin(LUP_CMD_GET_PARAM, 500);
}

View File

@@ -562,6 +562,93 @@ static void handle_report_config(uint8_t socket, uint32_t msg_id, const char *js
PRINT("JSON: report_config (push not yet implemented)\n");
}
/* 4.16 loop_version_query — 获取地感MCU版本号 (CMD 0x4A) */
static void handle_loop_version_query(uint8_t socket, uint32_t msg_id, const char *json) {
lup_send_get_version();
g_json_pending.active = 1;
g_json_pending.socket = socket;
g_json_pending.msg_id = msg_id;
strncpy(g_json_pending.cmd, "loop_version_query", sizeof(g_json_pending.cmd) - 1);
g_json_pending.deadline = mstick() + 300;
PRINT("JSON: loop_version_query sent\n");
}
/* 4.17 loop_reset — 复位地感MCU (CMD 0x6D, 无回复) */
static void handle_loop_reset(uint8_t socket, uint32_t msg_id, const char *json) {
lup_send_reset();
json_send_ok(socket, msg_id, "loop_reset", NULL);
PRINT("JSON: loop_reset sent (no response expected)\n");
}
/* 4.18 loop_factory_init — 地感MCU出厂初始化 (CMD 0x92) */
static void handle_loop_factory_init(uint8_t socket, uint32_t msg_id, const char *json) {
lup_send_factory_init();
g_json_pending.active = 1;
g_json_pending.socket = socket;
g_json_pending.msg_id = msg_id;
strncpy(g_json_pending.cmd, "loop_factory_init", sizeof(g_json_pending.cmd) - 1);
g_json_pending.deadline = mstick() + 600;
PRINT("JSON: loop_factory_init sent\n");
}
/* 4.19 loop_sens_read — 读取线圈灵敏度列表 (CMD 0x8A Read) */
static void handle_loop_sens_read(uint8_t socket, uint32_t msg_id, const char *json) {
lup_send_sensitivity_read();
g_json_pending.active = 1;
g_json_pending.socket = socket;
g_json_pending.msg_id = msg_id;
strncpy(g_json_pending.cmd, "loop_sens_read", sizeof(g_json_pending.cmd) - 1);
g_json_pending.deadline = mstick() + 300;
PRINT("JSON: loop_sens_read sent\n");
}
/* 4.20 loop_sens_write — 写入线圈灵敏度列表 (CMD 0x8A Write) */
static void handle_loop_sens_write(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, "loop_sens_write", JSON_CODE_PARAM_ERR, "missing data");
return;
}
LUP_Sensitivity sens;
memset(&sens, 0, sizeof(sens));
sens.rw = LUP_SENS_RW_WRITE;
uint32_t amount = json_get_uint_field(data, "\"amount\"");
if (amount == 0 || amount > LUP_COIL_COUNT) amount = LUP_COIL_COUNT;
sens.amount = (uint8_t)amount;
char key[16];
uint8_t i;
for (i = 0; i < sens.amount; i++) {
snprintf(key, sizeof(key), "\"ch%d\"", i + 1);
char ch_data[256] = {0};
reset_tmp();
simple_parse_json(data, key, g_tmp_value);
if (strlen(g_tmp_value) == 0) continue;
strncpy(ch_data, g_tmp_value, sizeof(ch_data) - 1);
sens.sens_in[i] = (uint16_t)json_get_uint_field(ch_data, "\"sens_in\"");
sens.sens_out[i] = (uint16_t)json_get_uint_field(ch_data, "\"sens_out\"");
}
free(data);
uint8_t buf[LUP_MAX_PKG_LEN];
uint16_t len = lup_build_sensitivity_write(buf, &sens);
UART2_SendString(buf, len);
PRINT("LUP Tx:");
for (i = 0; i < len; i++) PRINT(" %02X", buf[i]);
PRINT("\n");
lup_cmd_begin(LUP_CMD_SENSITIVITY, 300);
g_json_pending.active = 1;
g_json_pending.socket = socket;
g_json_pending.msg_id = msg_id;
strncpy(g_json_pending.cmd, "loop_sens_write", sizeof(g_json_pending.cmd) - 1);
g_json_pending.deadline = mstick() + 300;
PRINT("JSON: loop_sens_write sent (ch=%d)\n", sens.amount);
}
/*===========================================================================
* Command Dispatch Table
@@ -573,21 +660,26 @@ typedef struct {
} JsonCmdEntry;
static const JsonCmdEntry g_cmd_table[] = {
{"pwd_verify", handle_pwd_verify, 0},
{"dev_serial_set", handle_dev_serial_set, 1},
{"dev_info_query", handle_dev_info_query, 1},
{"ssc_net_set", handle_ssc_net_set, 1},
{"ssc_net_query", handle_ssc_net_query, 1},
{"iot_net_set", handle_iot_net_set, 1},
{"iot_net_query", handle_iot_net_query, 1},
{"iot_topic_set", handle_iot_topic_set, 1},
{"iot_topic_query", handle_iot_topic_query, 1},
{"pwd_set", handle_pwd_set, 1},
{"factory_reset", handle_factory_reset, 1},
{"device_reset", handle_device_reset, 1},
{"loop_param_set", handle_loop_param_set, 1},
{"loop_param_query", handle_loop_param_query, 1},
{"report_config", handle_report_config, 1},
{"pwd_verify", handle_pwd_verify, 0},
{"dev_serial_set", handle_dev_serial_set, 1},
{"dev_info_query", handle_dev_info_query, 1},
{"ssc_net_set", handle_ssc_net_set, 1},
{"ssc_net_query", handle_ssc_net_query, 1},
{"iot_net_set", handle_iot_net_set, 1},
{"iot_net_query", handle_iot_net_query, 1},
{"iot_topic_set", handle_iot_topic_set, 1},
{"iot_topic_query", handle_iot_topic_query, 1},
{"pwd_set", handle_pwd_set, 1},
{"factory_reset", handle_factory_reset, 1},
{"device_reset", handle_device_reset, 1},
{"loop_param_set", handle_loop_param_set, 1},
{"loop_param_query", handle_loop_param_query, 1},
{"loop_version_query", handle_loop_version_query, 1},
{"loop_reset", handle_loop_reset, 1},
{"loop_factory_init", handle_loop_factory_init, 1},
{"loop_sens_read", handle_loop_sens_read, 1},
{"loop_sens_write", handle_loop_sens_write, 1},
{"report_config", handle_report_config, 1},
};
#define JSON_CMD_COUNT (sizeof(g_cmd_table) / sizeof(g_cmd_table[0]))
@@ -830,10 +922,7 @@ static int format_sensor_json(char *buf, uint16_t buf_size, const LUP_SensorRepo
static void json_check_pending(void) {
if (!g_json_pending.active) return;
uint8_t cmd = g_lup_cmd.pending_cmd;
if (g_lup_cmd.state == LUP_STATE_RESPONSE_READY) {
// Response received!
if (strcmp(g_json_pending.cmd, "loop_param_set") == 0) {
uint8_t success = 0;
int ret = lup_parse_set_param_resp(g_lup_cmd.resp_buf, g_lup_cmd.resp_len, &success);
@@ -864,6 +953,91 @@ static void json_check_pending(void) {
g_json_pending.cmd, JSON_CODE_INTERNAL_ERR,
"Failed to parse Loop MCU response");
}
} else if (strcmp(g_json_pending.cmd, "loop_version_query") == 0) {
LUP_VersionInfo info;
memset(&info, 0, sizeof(info));
int ret = lup_parse_version(g_lup_cmd.resp_buf, g_lup_cmd.resp_len, &info);
if (ret == 0) {
snprintf(info.version_str, sizeof(info.version_str),
"V%d.%d.%d (HW:%d.%d.%d)",
info.soft_main, info.soft_sub, info.soft_ssub,
info.hard_main, info.hard_sub, info.hard_ssub);
char data_json[256];
snprintf(data_json, sizeof(data_json),
"{\"soft_ver\":\"%d.%d.%d\",\"hard_ver\":\"%d.%d.%d\","
"\"version_str\":\"%s\"}",
info.soft_main, info.soft_sub, info.soft_ssub,
info.hard_main, info.hard_sub, info.hard_ssub,
info.version_str);
json_send_ok(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, data_json);
} else {
json_send_error(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, JSON_CODE_INTERNAL_ERR,
"Failed to parse version");
}
} else if (strcmp(g_json_pending.cmd, "loop_factory_init") == 0) {
uint8_t success = 0;
int ret = lup_parse_factory_init_resp(g_lup_cmd.resp_buf, g_lup_cmd.resp_len, &success);
if (ret == 0 && success) {
json_send_ok(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, NULL);
} else {
json_send_error(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, JSON_CODE_INTERNAL_ERR,
ret == 0 ? "Factory init failed" : "Parse error");
}
} else if (strcmp(g_json_pending.cmd, "loop_sens_read") == 0) {
LUP_Sensitivity sens;
memset(&sens, 0, sizeof(sens));
int ret = lup_parse_sensitivity_resp(g_lup_cmd.resp_buf, g_lup_cmd.resp_len, &sens);
if (ret == 0) {
char data_json[512];
char *p = data_json;
int rem = sizeof(data_json);
int w = snprintf(p, rem, "{\"amount\":%d,\"channels\":[", sens.amount);
p += w; rem -= w;
uint8_t i;
for (i = 0; i < sens.amount; i++) {
w = snprintf(p, rem,
"%s{\"ch\":%d,\"sens_value\":%d}",
(i > 0) ? "," : "", i + 1, sens.sens_in[i]);
p += w; rem -= w;
}
snprintf(p, rem, "]}");
json_send_ok(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, data_json);
} else {
json_send_error(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, JSON_CODE_INTERNAL_ERR,
"Failed to parse sensitivity");
}
} else if (strcmp(g_json_pending.cmd, "loop_sens_write") == 0) {
// 0x8A Write response returns sensitivity list
LUP_Sensitivity sens;
memset(&sens, 0, sizeof(sens));
int ret = lup_parse_sensitivity_resp(g_lup_cmd.resp_buf, g_lup_cmd.resp_len, &sens);
if (ret == 0) {
char data_json[512];
char *p = data_json;
int rem = sizeof(data_json);
int w = snprintf(p, rem, "{\"amount\":%d,\"channels\":[", sens.amount);
p += w; rem -= w;
uint8_t i;
for (i = 0; i < sens.amount; i++) {
w = snprintf(p, rem,
"%s{\"ch\":%d,\"sens_value\":%d}",
(i > 0) ? "," : "", i + 1, sens.sens_in[i]);
p += w; rem -= w;
}
snprintf(p, rem, "]}");
json_send_ok(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, data_json);
} else {
json_send_error(g_json_pending.socket, g_json_pending.msg_id,
g_json_pending.cmd, JSON_CODE_INTERNAL_ERR,
"Failed to parse sensitivity response");
}
}
lup_cmd_done();