feat: V1.03 initialize 上线消息 — 固件+工具同步

vd960DBN:
- dev_initialize_pub() 改为 V1.03 格式 (msg_id/cmd/ts/data/extra_info)
- iot_mqtt_srv: 订阅改双主题 dld960/{sn}/srv, 响应 topic 改 dev
- SUBACK 后自动发 initialize 告知服务器上线
- net_srv.h: 加 dev_initialize_pub 声明

DBNMQTTool:
- protocol.py: 加 CMD_INITIALIZE
- device_manager: DeviceInfo 加 extra_info, 加 mark_online()
- main.py: 接收 initialize 消息, 自动标记设备上线
- docs: 协议 V1.03 + devlog V3.1
This commit is contained in:
wangfq
2026-07-09 21:32:39 +08:00
parent 1ff731c309
commit 652fc5f938
7 changed files with 56 additions and 26 deletions
@@ -22,6 +22,7 @@ class DeviceInfo:
online: bool = False
loop_data: Optional[dict] = None
events: list = field(default_factory=list)
extra_info: dict = field(default_factory=dict) # from initialize 消息
class DeviceManager:
@@ -91,6 +92,17 @@ class DeviceManager:
dev.online = True
self._notify()
def mark_online(self, dev_serial: str, extra_info: Optional[dict] = None):
"""V1.03: 设备上线初始化标记"""
with self._lock:
dev = self.get_or_create(dev_serial)
dev.online = True
dev.last_seen = datetime.now()
if extra_info:
dev.extra_info = extra_info
dev.soft_ver = extra_info.get("version", dev.soft_ver)
self._notify()
def set_offline(self):
"""标记所有设备离线(断开连接时调用)"""
with self._lock:
+1
View File
@@ -65,6 +65,7 @@ CMD_REPORT_CONFIG = "report_config"
CMD_LOOP_DATA = "loop_data"
CMD_EVENT_REPORT = "event_report"
CMD_HEARTBEAT = "heartbeat"
CMD_INITIALIZE = "initialize" # V1.03: 设备上电初始化
# 配置类命令 → topic
CONFIG_SET_COMMANDS = {CMD_DEV_SERIAL_SET, CMD_SSC_NET_SET, CMD_IOT_NET_SET, CMD_IOT_TOPIC_SET, CMD_LOOP_PARAM_SET}
+10 -1
View File
@@ -30,7 +30,7 @@ from dbn_mqtt_tool.protocol import (
CMD_IOT_TOPIC_QUERY, CMD_LOOP_PARAM_QUERY, CMD_REPORT_CONFIG,
CMD_SSC_NET_SET, CMD_IOT_NET_SET, CMD_IOT_TOPIC_SET,
CMD_PWD_VERIFY, CMD_PWD_SET, CMD_FACTORY_RESET, CMD_DEVICE_RESET,
CMD_LOOP_DATA, CMD_EVENT_REPORT, CMD_HEARTBEAT,
CMD_LOOP_DATA, CMD_EVENT_REPORT, CMD_HEARTBEAT, CMD_INITIALIZE,
ERROR_MSGS, FREQ_LEVELS, OUTPUT_MODES, EVENT_TYPES,
data_ssc_net_set, data_iot_net_set, data_iot_topic_set,
data_pwd_verify, data_pwd_set, data_report_config,
@@ -857,6 +857,15 @@ class MainWindow(QMainWindow):
self._devmgr.update_heartbeat(dev_serial, data)
self._log_recv(topic, payload, f"heartbeat uptime={data.get('uptime', 0)}s")
elif cmd == CMD_INITIALIZE:
# V1.03: 设备上线初始化
data = payload.get("data", {})
dev_sn = data.get("dev_serial", dev_serial)
extra = data.get("extra_info", {})
self._devmgr.mark_online(dev_sn, extra)
self._log_recv(topic, payload, f"initialize sn={dev_sn} ver={extra.get('version','?')}")
self._show_json({"online": dev_sn, "info": extra})
# 旧协议 / 无 cmd 字段 的消息(如 Initialize
elif "Method" in payload:
self._log_recv(topic, payload, f"Method={payload.get('Method', '?')}")
@@ -279,6 +279,7 @@ void manage_tcp_message(uint8_t socket, uint8_t *buf, uint32_t len);
void manage_mqtt_recv_message(char * msg, int length);
void poll_mqtt(void);
void mqtt_publish(char *topic, char *message, int req_qos);
void dev_initialize_pub(void); // 发布上线 initialize 消息 (V1.03)
void GetMacAddr(unsigned char *pMAC);
@@ -110,23 +110,17 @@ static int iot_mqtt_send_connect(void) {
return iot_mqtt_send(buf, (uint16_t)len);
}
/* 发送 MQTT SUBSCRIBE */
/* 发送 MQTT SUBSCRIBE — V1.01 双主题协议 */
static int iot_mqtt_send_subscribe(void) {
static uint8_t buf[256]; // static: 避免栈溢出
int len;
char topic[IOT_MQTT_TOPIC_MAX_LEN];
MQTTString topics[3];
int qos[3] = {1, 1, 1};
MQTTString topics[1];
int qos[1] = {1};
int count = 0;
// 订阅服务器下发消息
iot_make_topic(topic, sizeof(topic), "srv", "config", "set");
topics[count].cstring = topic; topics[count].lenstring.len = 0; count++;
iot_make_topic(topic, sizeof(topic), "srv", "config", "query");
topics[count].cstring = topic; topics[count].lenstring.len = 0; count++;
iot_make_topic(topic, sizeof(topic), "srv", "ctrl", NULL);
// V1.01: 仅订阅 dld960/{sn}/srv 双主题
snprintf(topic, sizeof(topic), "dld960/%s/srv", g_iot_dev_serial);
topics[count].cstring = topic; topics[count].lenstring.len = 0; count++;
len = MQTTSerialize_subscribe(buf, sizeof(buf), 0,
@@ -192,9 +186,9 @@ static void iot_handle_publish(const char *topic, uint8_t *payload, int payload_
return;
}
/* 构建响应 topic */
/* 构建响应 topic — V1.01 双主题 */
char resp_topic[IOT_MQTT_TOPIC_MAX_LEN];
iot_make_topic(resp_topic, sizeof(resp_topic), "dev", "config", "resp");
snprintf(resp_topic, sizeof(resp_topic), "dld960/%s/dev", g_iot_dev_serial);
/* 处理命令 — 复用 TCP JSON 的命令逻辑 */
/* 目前仅实现基本响应框架, 后续逐步对接 Loop MCU 命令 */
@@ -268,6 +262,9 @@ static void iot_handle_suback(void) {
PRINT("IOT: ← SUBACK, topics subscribed\n");
g_iot_state = IOT_STATE_READY;
_iot_reconnect_backoff = 0; // 连接成功, 重置退避
// V1.03: 订阅成功后发布 initialize 告知服务器上线
dev_initialize_pub();
}
/* 处理收到的 MQTT 数据 */
@@ -386,10 +383,9 @@ void iot_mqtt_publish_sensor(void) {
return;
}
/* 全通道一次性上报,字段按 DLD960_TCP_JSON协议.md §5.1:
ch, freq_level, has_car, loop_ok, freq_current, freq_diff,
sensitivity, condition, misc.type, misc.value
: mqttBuf 1024 4 (~846 ) */
/* 全通道一次性上报,字段按 DLD960_IoT_MQTT协议.md §5.2 V1.02:
ch, level, iscar, loop_ok, freq, diff, sens, cndtn, misc.{type,value}
: mqttBuf 1024 4 (~800 ) */
static char data_json[1024];
static char payload[1400];
char *p = data_json;
@@ -183,15 +183,25 @@ void dev_initialize_pub(void)
return;
}
memset(mBuff, 0, 256);
sprintf((char *)mBuff, "{\"Method\":\"Initialize\", \"Device_id\": \"%s\","
"\"Extra_Info\":{\"Code\":\"%s\",\"CSQ\":%d, \"Version\":\"%s\"}}", g_dev_number_str, "0", 0, FIRMWARE_VER);
//mqtt_publish((char *)"gtpc/display/Initialize", gbufSend, 0);
PRINT("\r\nWill publish initialize_topic:\n%s\r\n", mBuff);
// V1.03: 上线后发布 initialize,告知服务器设备信息
// 格式: {msg_id, cmd:"initialize", ts, data:{dev_serial, extra_info:{code,csq,location,version}}}
uint32_t now = (mstick() > 0) ? (uint32_t)(mstick() / 1000) : 0;
sprintf((char *)mBuff,
"{\"msg_id\":%lu,\"cmd\":\"initialize\",\"ts\":%lu,"
"\"data\":{\"dev_serial\":\"%s\","
"\"extra_info\":{\"code\":\"%s\",\"csq\":\"%d\","
"\"location\":\"%s\",\"version\":\"%s\"}}}",
(unsigned long)++g_msg_id, (unsigned long)now,
g_dev_number_str,
"0", 0, "", FIRMWARE_VER);
PRINT("
\nWill publish initialize_topic:\n%s
\n", mBuff);
mqtt_publish((char *)(g_iot_topic.topic_pub), (char *)mBuff, 0);
free(mBuff);
}
+1
View File
@@ -210,6 +210,7 @@ topic 修正为 V1.01 双主题协议 `dld960/{sn}/dev`(此前遗留旧 topic
| 版本 | 时间 | 说明 |
|------|------|------|
| V3.1 | 2026-07-09 | V1.03: 订阅后发 initialize 上线消息; iot_mqtt_srv 订阅改双主题 |
| V3.0 | 2026-07-08 | MQTT 稳定性修复: socket初始化/buffer溢出/分批发送/hex dump/PINGREQ |
| V2.9 | 2026-07-07 | MQTT V1.01 双主题协议 + 命令分发 + report_config 7参数 |
| V2.8 | 2026-07-07 | MQTT 网络配置: ssc_net_set / iot_net_set / iot_topic_set |