feat(iot_mqtt): 恢复 loop_data 完整字段 + 分批发送(2通道/包)
按 DLD960_TCP_JSON协议.md §5.1 恢复完整字段: - ch, freq_level, has_car, loop_ok, freq_current, freq_diff, sensitivity, condition, misc.type, misc.value 每包发 2 个通道,确保 JSON < 450 字节 (mqttBuf 512 安全范围内)。 4 通道设备每次 SensorReport 发 2 条 loop_data 消息。
This commit is contained in:
@@ -372,7 +372,7 @@ void iot_mqtt_publish_sensor(void) {
|
|||||||
if (g_iot_state != IOT_STATE_READY) return;
|
if (g_iot_state != IOT_STATE_READY) return;
|
||||||
if (!g_report_cfg.enable) return;
|
if (!g_report_cfg.enable) return;
|
||||||
|
|
||||||
/* 复用 g_pkg_uart_2 中的传感器帧 */
|
/* Reuse g_pkg_uart_2 sensor frame from Loop MCU */
|
||||||
if (g_pkg_uart_2.flag == 0) return;
|
if (g_pkg_uart_2.flag == 0) return;
|
||||||
if (g_pkg_uart_2.pkg[0] != 0x7F) return;
|
if (g_pkg_uart_2.pkg[0] != 0x7F) return;
|
||||||
if (g_pkg_uart_2.pkg[3] != 0xC0) return;
|
if (g_pkg_uart_2.pkg[3] != 0xC0) return;
|
||||||
@@ -386,67 +386,75 @@ void iot_mqtt_publish_sensor(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 构建 loop_data JSON */
|
/* Batch-publish: 2 channels per message to keep each under 512 bytes.
|
||||||
static char data_json[IOT_MQTT_SEND_BUF_LEN]; // static: 避免栈溢出
|
Full-field JSON (freq_current, freq_diff, condition, misc) per the protocol doc. */
|
||||||
char *p = data_json;
|
static char data_json[1024]; // single buffer for 2-channel JSON
|
||||||
int remaining = sizeof(data_json);
|
static char payload[1024];
|
||||||
int written;
|
char *pub_topic = (char *)g_iot_topic.topic_pub;
|
||||||
|
uint8_t batch_start = 0;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
written = snprintf(p, remaining,
|
while (batch_start < sr.coil_count) {
|
||||||
"{\"channels\":[");
|
char *p = data_json;
|
||||||
if (written < 0 || written >= remaining) goto done;
|
int remaining = sizeof(data_json);
|
||||||
p += written; remaining -= written;
|
int written;
|
||||||
|
uint8_t batch_end = batch_start + 2;
|
||||||
for (i = 0; i < sr.coil_count; i++) {
|
if (batch_end > sr.coil_count) batch_end = sr.coil_count;
|
||||||
const LUP_CoilSensor *cs = &sr.coils[i];
|
|
||||||
const char *misc_type_str = "time";
|
|
||||||
uint32_t misc_val = 0;
|
|
||||||
|
|
||||||
if (cs->misc_type == 0) { misc_type_str = "time"; misc_val = cs->misc.passtime_ms; }
|
|
||||||
else if (cs->misc_type == 1) { misc_type_str = "cut_count"; misc_val = cs->misc.cut_amount; }
|
|
||||||
else if (cs->misc_type == 2) { misc_type_str = "flow_count"; misc_val = cs->misc.flow_amount; }
|
|
||||||
else if (cs->misc_type == 3) { misc_type_str = "relay_count"; misc_val = cs->misc.relay_count; }
|
|
||||||
|
|
||||||
const char *freq_level_names[] = {"high", "mid_high", "mid_low", "low"};
|
|
||||||
|
|
||||||
written = snprintf(p, remaining,
|
written = snprintf(p, remaining,
|
||||||
"%s{\"ch\":%d,\"fl\":\"%s\",\"car\":%s,"
|
"{\"channels\":[");
|
||||||
"\"ok\":%s,\"sens\":%d,\"mt\":\"%s\",\"mv\":%lu}",
|
|
||||||
(i > 0) ? "," : "",
|
|
||||||
i + 1,
|
|
||||||
freq_level_names[cs->freq_level],
|
|
||||||
cs->car_state ? "true" : "false",
|
|
||||||
cs->loop_state ? "false" : "true",
|
|
||||||
cs->sensitivity,
|
|
||||||
misc_type_str, misc_val);
|
|
||||||
if (written < 0 || written >= remaining) goto done;
|
if (written < 0 || written >= remaining) goto done;
|
||||||
p += written; remaining -= written;
|
p += written; remaining -= written;
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(p, remaining, "]}");
|
for (i = batch_start; i < batch_end; i++) {
|
||||||
|
const LUP_CoilSensor *cs = &sr.coils[i];
|
||||||
|
const char *misc_type_str = "time";
|
||||||
|
uint32_t misc_val = 0;
|
||||||
|
|
||||||
/* 包装为通用消息格式 */
|
if (cs->misc_type == 0) { misc_type_str = "time"; misc_val = cs->misc.passtime_ms; }
|
||||||
static char payload[IOT_MQTT_SEND_BUF_LEN]; // static: 避免 2KB 栈溢出
|
else if (cs->misc_type == 1) { misc_type_str = "cut_count"; misc_val = cs->misc.cut_amount; }
|
||||||
snprintf(payload, sizeof(payload),
|
else if (cs->misc_type == 2) { misc_type_str = "flow_count"; misc_val = cs->misc.flow_amount; }
|
||||||
"{\"msg_id\":%d,\"cmd\":\"loop_data\",\"ts\":%lu,\"data\":%s}",
|
else if (cs->misc_type == 3) { misc_type_str = "relay_count"; misc_val = cs->misc.relay_count; }
|
||||||
++g_iot_msg_id, mstick() / 1000, data_json);
|
|
||||||
|
|
||||||
{
|
const char *freq_level_names[] = {"high", "mid_high", "mid_low", "low"};
|
||||||
uint16_t plen = (uint16_t)strlen(payload);
|
|
||||||
if (plen > 450) {
|
written = snprintf(p, remaining,
|
||||||
PRINT("IOT: payload too large (%u bytes), skipping\n", plen);
|
"%s{\"ch\":%d,\"freq_level\":\"%s\",\"has_car\":%s,"
|
||||||
} else {
|
"\"loop_ok\":%s,\"freq_current\":%lu,\"freq_diff\":%d,"
|
||||||
/* V1.01: publish to g_iot_topic.topic_pub = dld960/{sn}/dev */
|
"\"sensitivity\":%d,\"condition\":%d,"
|
||||||
char *pub_topic = (char *)g_iot_topic.topic_pub;
|
"\"misc\":{\"type\":\"%s\",\"value\":%lu}}",
|
||||||
mqtt_publish(pub_topic, payload, 0);
|
(i > batch_start) ? "," : "",
|
||||||
|
i + 1,
|
||||||
|
freq_level_names[cs->freq_level],
|
||||||
|
cs->car_state ? "true" : "false",
|
||||||
|
cs->loop_state ? "false" : "true",
|
||||||
|
cs->freq, cs->variation,
|
||||||
|
cs->sensitivity, cs->condition,
|
||||||
|
misc_type_str, misc_val);
|
||||||
|
if (written < 0 || written >= remaining) goto done;
|
||||||
|
p += written; remaining -= written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snprintf(p, remaining, "]}");
|
||||||
|
|
||||||
|
/* Wrap in outer message and publish */
|
||||||
|
snprintf(payload, sizeof(payload),
|
||||||
|
"{\"msg_id\":%d,\"cmd\":\"loop_data\",\"ts\":%lu,\"data\":%s}",
|
||||||
|
++g_iot_msg_id, mstick() / 1000, data_json);
|
||||||
|
|
||||||
|
uint16_t plen = (uint16_t)strlen(payload);
|
||||||
|
mqtt_publish(pub_topic, payload, 0);
|
||||||
|
|
||||||
|
batch_start = batch_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
InitPkgUart(&g_pkg_uart_2);
|
InitPkgUart(&g_pkg_uart_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitPkgUart(&g_pkg_uart_2);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================
|
/*===========================================================================
|
||||||
* 心跳上报
|
* 心跳上报
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
|
|||||||
Reference in New Issue
Block a user