diff --git a/DBNMQTTool/dbn_mqtt_tool/protocol.py b/DBNMQTTool/dbn_mqtt_tool/protocol.py index 33d1e51..ad183a9 100644 --- a/DBNMQTTool/dbn_mqtt_tool/protocol.py +++ b/DBNMQTTool/dbn_mqtt_tool/protocol.py @@ -1,7 +1,7 @@ """ DLD960 IoT MQTT 协议定义 -基于《DLD960_IoT_MQTT协议.md》V1.01 +基于《DLD960_IoT_MQTT协议.md》V1.03 双主题结构:{sn}/srv(服务器下发)、{sn}/dev(设备上报) 消息类型由 JSON `cmd` 字段区分。 """ diff --git a/DBNMQTTool/main.py b/DBNMQTTool/main.py index 7d05f1c..583b246 100644 --- a/DBNMQTTool/main.py +++ b/DBNMQTTool/main.py @@ -419,6 +419,21 @@ class MainWindow(QMainWindow): g2l.addLayout(g2l2) layout.addWidget(g2) + # -- initialize -- + g_init = QGroupBox("上电初始化 (initialize) — V1.03") + g_init_l = QVBoxLayout(g_init) + self._sim_init = QPlainTextEdit() + self._sim_init.setFont(QFont("Consolas", 10)) + self._sim_init.setPlainText(self._sample_initialize_data()) + g_init_l.addWidget(self._sim_init) + g_init_l2 = QHBoxLayout() + b_init = QPushButton("发送") + b_init.clicked.connect(self._sim_send_initialize) + g_init_l2.addWidget(b_init) + g_init_l2.addStretch() + g_init_l.addLayout(g_init_l2) + layout.addWidget(g_init) + # -- heartbeat -- g3 = QGroupBox("心跳上报 (heartbeat)") g3l = QVBoxLayout(g3) @@ -479,6 +494,24 @@ class MainWindow(QMainWindow): ]} }, indent=2) + def _sample_initialize_data(self) -> str: + return json.dumps({ + "msg_id": 1, + "cmd": "initialize", + "ts": 1719000000, + "data": { + "dev_serial": "DC045A49718F", + "model": "DLD960", + "hard_ver": "1.0", + "soft_ver": "1.0", + "extra_info": { + "code": "869756049404948", + "csq": "21", + "location": "113.9237976,022.6400375" + } + } + }, indent=2) + def _sample_heartbeat_data(self) -> str: return json.dumps({ "msg_id": 200, @@ -509,6 +542,10 @@ class MainWindow(QMainWindow): sn = self._sim_sn.text() self._sim_publish(topic_up(sn), self._sim_event.toPlainText()) + def _sim_send_initialize(self): + sn = self._sim_sn.text() + self._sim_publish(topic_up(sn), self._sim_init.toPlainText()) + def _sim_send_hb(self): sn = self._sim_sn.text() self._sim_publish(topic_up(sn), self._sim_hb.toPlainText()) @@ -602,6 +639,7 @@ class MainWindow(QMainWindow): item = QTreeWidgetItem(dev, [topic_up(sn), "设备发布:loop_data / event_report / heartbeat / 命令响应"]) # 子条目列出 cmd 类型 for cmd_name, desc in [ + ("initialize", "设备上电初始化 (V1.03)"), ("loop_data", "线圈传感数据上报"), ("event_report", "事件上报(有车/无车/故障)"), ("heartbeat", "设备心跳"), diff --git a/docs/DLD960_IoT_MQTT协议.md b/docs/DLD960_IoT_MQTT协议.md index ab4f2ea..5c1d314 100644 --- a/docs/DLD960_IoT_MQTT协议.md +++ b/docs/DLD960_IoT_MQTT协议.md @@ -637,11 +637,13 @@ dld960/{dev_serial}/{direction} "ts": 1719000000, "data": { "dev_serial":"A1B2C3D4E5F6", + "model": "DLD960", + "hard_ver": "1.0", + "soft_ver": "1.0", "extra_info": { "code": "869756049404948", "csq": "21", "location": "113.9237976,022.6400375", - "version": "1.0.1" } } } @@ -650,10 +652,12 @@ dld960/{dev_serial}/{direction} | 字段 | 类型 | 说明 | |------|------|------| | `data.dev_serial` | string | 设备序列码 | +| `data.model` | string | 产品型号 | +| `data.hard_ver` | string | 硬件版本 | +| `data.soft_ver` | string | 固件版本 | | `data.extra_info.code` | string | 可选,设备代码如IMSI/ICCID | | `data.extra_info.csq` | string | 可选,当前信号强度 | | `data.extra_info.location` | string | 可选,经纬度(经度,纬度) | -| `data.extra_info.version` | string | 版本号 | ## 5.2 线圈传感数据 `loop_data` diff --git a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/iot_mqtt_srv.c b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/iot_mqtt_srv.c index 6b1b760..dc18169 100644 --- a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/iot_mqtt_srv.c +++ b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/iot_mqtt_srv.c @@ -427,12 +427,16 @@ void iot_mqtt_publish_sensor(void) { snprintf(p, remaining, "]}"); - /* Wrap and publish */ + /* Wrap and publish — V1.01 双主题模型: dld960/{sn}/dev */ snprintf(payload, sizeof(payload), "{\"msg_id\":%d,\"cmd\":\"loop_data\",\"ts\":%lu,\"data\":%s}", ++g_iot_msg_id, mstick() / 1000, data_json); - mqtt_publish((char *)g_iot_topic.topic_pub, payload, 0); + { + char topic[IOT_MQTT_TOPIC_MAX_LEN]; + snprintf(topic, sizeof(topic), "dld960/%s/dev", g_iot_dev_serial); + mqtt_publish(topic, payload, 0); + } done: InitPkgUart(&g_pkg_uart_2); @@ -463,7 +467,7 @@ static void iot_send_heartbeat(void) { loop_ok[2] ? "true" : "false", loop_ok[3] ? "true" : "false"); char topic[IOT_MQTT_TOPIC_MAX_LEN]; - iot_make_topic(topic, sizeof(topic), "dev", "status", NULL); + snprintf(topic, sizeof(topic), "dld960/%s/dev", g_iot_dev_serial); iot_mqtt_publish(topic, payload, strlen(payload), 0); } diff --git a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/net_srv.c b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/net_srv.c index 5e05601..c8ac243 100644 --- a/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/net_srv.c +++ b/vd960DBN/BLE/OnlyUpdateApp_Peripheral/APP/net_srv.c @@ -177,30 +177,32 @@ void mqtt_publish(char *topic, char *message, int req_qos) void dev_initialize_pub(void) { - char *mBuff = (char *)malloc(256); + char *mBuff = (char *)malloc(512); if(mBuff == NULL) { return; } - memset(mBuff, 0, 256); + memset(mBuff, 0, 512); // V1.03: 上线后发布 initialize,告知服务器设备信息 - // 格式: {msg_id, cmd:"initialize", ts, data:{dev_serial, extra_info:{code,csq,location,version}}} + // 格式: {msg_id, cmd:"initialize", ts, data:{dev_serial, model, hard_ver, soft_ver, extra_info:{code,csq,location}}} uint32_t now = (mstick() > 0) ? (uint32_t)(mstick() / 1000) : 0; + char topic[64]; + snprintf(topic, sizeof(topic), "dld960/%s/dev", g_dev_number_str); sprintf((char *)mBuff, "{\"msg_id\":%lu,\"cmd\":\"initialize\",\"ts\":%lu," - "\"data\":{\"dev_serial\":\"%s\"," + "\"data\":{\"dev_serial\":\"%s\",\"model\":\"%s\"," + "\"hard_ver\":\"%s\",\"soft_ver\":\"%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); + "\"location\":\"%s\"}}}", + (unsigned long)++g_iot_msg_id, (unsigned long)now, + g_dev_number_str, PRODUCT_MODEL, + HARDWARE_VER, FIRMWARE_VER, + "0", 0, ""); - PRINT(" -\nWill publish initialize_topic:\n%s -\n", mBuff); + PRINT("\nWill publish initialize topic=%s:\n%s\n", topic, mBuff); - mqtt_publish((char *)(g_iot_topic.topic_pub), (char *)mBuff, 0); + mqtt_publish(topic, (char *)mBuff, 0); free(mBuff); }