Files
vd_960/docs/DLD960_IoT_MQTT协议.md
wangfq ef806b6013 init: vd_960 项目初始化
- 双 MCU 架构:AT32F421(线圈) + CH32V208(通信)
- DLD960 串口通信协议 V1.01
- IoT MQTT 接口协议 V1.00 (JSON)
- TCP 接口协议 V1.00 (JSON)
2026-06-22 17:02:23 +08:00

790 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DLD960 IoT 接口协议MQTT + JSON
> 基于《DLD960 串口通信协议》V1.01,将设备管理、参数配置、数据上报映射到 MQTT 协议。
> 交互格式JSON。
---
# 1 通信说明
## 1.1 连接参数
| 项目 | 说明 |
|------|------|
| 协议 | MQTT 3.1.1 / 5.0 |
| 传输层 | TCP (TLS 可选) |
| QoS | 配置类 QoS 1数据上报类 QoS 0/1 |
| 编码 | UTF-8 |
| 序列化 | JSON |
## 1.2 Topic 结构
```
dld960/{dev_serial}/{direction}/{category}[/{sub}]
```
| 字段 | 说明 |
|------|------|
| `dev_serial` | 设备序列码6字节十六进制字符串`A1B2C3D4E5F6` |
| `direction` | `srv` = 服务器下发,`dev` = 设备上报 |
| `category` | 消息类别 |
| `sub` | 子类别(可选) |
### 1.2.1 服务器下发 Topic设备订阅
| Topic | 说明 | 对应串口 CMD |
|-------|------|-------------|
| `dld960/{sn}/srv/config/set` | 设置配置参数 | 0x11, 0x13, 0x15, 0x63 |
| `dld960/{sn}/srv/config/query` | 查询配置参数 | 0x10, 0x12, 0x14, 0x16, 0x64 |
| `dld960/{sn}/srv/ctrl` | 控制命令 | 0x09, 0x1C, 0x1D, 0x1E, 0x1F, 0xC5 |
### 1.2.2 设备上报 Topic服务器订阅
| Topic | 说明 | 对应串口 CMD |
|-------|------|-------------|
| `dld960/{sn}/dev/config/resp` | 配置查询/设置响应 | 各命令返回 |
| `dld960/{sn}/dev/data/loop` | 线圈传感数据上报 | 0xC0 (SensType=0x0C) |
| `dld960/{sn}/dev/data/event` | 事件上报(有车/无车、故障等) | — |
| `dld960/{sn}/dev/status` | 设备状态(在线心跳、自检) | — |
---
# 2 JSON 消息格式
## 2.1 通用结构
```json
{
"msg_id": 12345,
"cmd": "dev_info_query",
"ts": 1719000000,
"data": { ... }
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `msg_id` | uint32 | 消息序列号,递增,用于请求-响应匹配(由发起方生成) |
| `cmd` | string | 命令标识符 |
| `ts` | uint32 | Unix 时间戳(秒),发起方填充 |
| `data` | object | 命令参数,结构依 cmd 而定 |
## 2.2 响应通用结构
```json
{
"msg_id": 12345,
"cmd": "dev_info_query",
"ts": 1719000001,
"code": 0,
"msg": "success",
"data": { ... }
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `code` | int | 0 = 成功,非 0 = 失败码 |
| `msg` | string | 错误描述(成功时为 `"success"` |
### 错误码定义
| code | 说明 |
|------|------|
| 0 | 成功 |
| 1 | 参数错误(格式/范围不正确) |
| 2 | 密码验证失败 |
| 3 | 设备忙(操作执行中) |
| 4 | 不支持的命令 |
| 5 | 内部错误 |
| 6 | 数据超长 |
---
# 3 命令详表
| cmd | 说明 | 方向 | 对应串口 |
|-----|------|------|----------|
| `dev_serial_set` | 更改设备序列码 | srv→dev | 0x09 |
| `dev_info_query` | 查询设备信息 | srv→dev | 0x10 |
| `ssc_net_set` | 设置 SSC 网络配置 | srv→dev | 0x11 |
| `ssc_net_query` | 查询 SSC 网络配置 | srv→dev | 0x12 |
| `iot_net_set` | 设置 IoT 网络配置 | srv→dev | 0x13 |
| `iot_net_query` | 查询 IoT 网络配置 | srv→dev | 0x14 |
| `iot_topic_set` | 设置设备 Topic | srv→dev | 0x15 |
| `iot_topic_query` | 查询设备 Topic | srv→dev | 0x16 |
| `pwd_verify` | 验证设备密码 | srv→dev | 0x1C |
| `pwd_set` | 设置设备密码 | srv→dev | 0x1D |
| `factory_reset` | 设备出厂初始化 | srv→dev | 0x1E |
| `device_reset` | 设备复位 | srv→dev | 0x1F |
| `loop_param_set` | 设置车检器多路参数 | srv→dev | 0x63 |
| `loop_param_query` | 读取车检器多路参数 | srv→dev | 0x64 |
| `report_config` | 设置主动上报 | srv→dev | 0xC5 |
| `loop_data` | 线圈传感数据上报 | dev→srv | 0xC0 |
| `event_report` | 事件上报 | dev→srv | — |
| `heartbeat` | 设备心跳 | dev→srv | — |
---
# 4 命令详情
## 4.1 更改设备序列码 `dev_serial_set`
> Topic: `dld960/{sn}/srv/config/set`
**请求:**
```json
{
"msg_id": 1,
"cmd": "dev_serial_set",
"ts": 1719000000,
"data": {
"dev_serial": "A1B2C3D4E5F6"
}
}
```
**响应:** Topic: `dld960/{sn}/dev/config/resp`
```json
{
"msg_id": 1,
"cmd": "dev_serial_set",
"ts": 1719000001,
"code": 0,
"msg": "success"
}
```
## 4.2 查询设备信息 `dev_info_query`
> Topic: `dld960/{sn}/srv/config/query`
**请求:**
```json
{
"msg_id": 2,
"cmd": "dev_info_query",
"ts": 1719000000
}
```
**响应:**
```json
{
"msg_id": 2,
"cmd": "dev_info_query",
"ts": 1719000001,
"code": 0,
"msg": "success",
"data": {
"dev_serial": "A1B2C3D4E5F6",
"hard_ver": "1.1",
"soft_ver": "1.1",
"model": "DLD960",
"product_code": "960001",
"sub_code": {
"net": true,
"iot": true
},
"bus": {
"bus1": 0,
"bus2": 0,
"bus3": 0,
"bus4": 0
}
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `dev_serial` | string | 12 位十六进制序列码 |
| `hard_ver` | string | 硬件版本,格式 `"主.次"` |
| `soft_ver` | string | 软件版本,格式 `"主.次"` |
| `model` | string | 产品型号1~10 字符 |
| `product_code` | string | 产品编码6 位数字字符串 |
| `sub_code.net` | bool | 网络功能是否启用 |
| `sub_code.iot` | bool | IoT/MQTT 功能是否启用 |
| `bus.bus1~4` | uint8 | 各总线探头数 |
## 4.3 设置 SSC 网络配置 `ssc_net_set`
> Topic: `dld960/{sn}/srv/config/set`
**请求:**
```json
{
"msg_id": 3,
"cmd": "ssc_net_set",
"ts": 1719000000,
"data": {
"dev_ip": "192.168.1.100",
"subnet_mask": "255.255.255.0",
"route_ip": "192.168.1.1",
"lssc_ip": "192.168.1.200",
"dns": "8.8.8.8",
"port": 502
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `dev_ip` | string | 设备 IP 地址 |
| `subnet_mask` | string | 子网掩码 |
| `route_ip` | string | 网关地址 |
| `lssc_ip` | string | LSSC 服务器 IP |
| `dns` | string | DNS 服务器 IP |
| `port` | uint16 | 端口号 |
**响应:**
```json
{
"msg_id": 3,
"cmd": "ssc_net_set",
"ts": 1719000001,
"code": 0,
"msg": "success"
}
```
## 4.4 查询 SSC 网络配置 `ssc_net_query`
> Topic: `dld960/{sn}/srv/config/query`
**请求:**
```json
{
"msg_id": 4,
"cmd": "ssc_net_query",
"ts": 1719000000
}
```
**响应:** 返回字段同 4.3 的 `data`
## 4.5 设置 IoT 网络配置 `iot_net_set`
> Topic: `dld960/{sn}/srv/config/set`
**请求:**
```json
{
"msg_id": 5,
"cmd": "iot_net_set",
"ts": 1719000000,
"data": {
"host": "mqtt.example.com",
"port": 1883,
"client_id": "dld960_A1B2C3D4E5F6",
"username": "admin",
"password": "secret"
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `host` | string | MQTT Broker 域名或 IP |
| `port` | uint16 | MQTT 端口,默认 1883 |
| `client_id` | string | MQTT Client ID空时用空格 |
| `username` | string | MQTT 用户名 |
| `password` | string | MQTT 密码 |
**响应:** 标准成功/失败。
## 4.6 查询 IoT 网络配置 `iot_net_query`
> Topic: `dld960/{sn}/srv/config/query`
**请求:**
```json
{
"msg_id": 6,
"cmd": "iot_net_query",
"ts": 1719000000
}
```
**响应:** 返回字段同 4.5 的 `data`
## 4.7 设置设备 Topic `iot_topic_set`
> Topic: `dld960/{sn}/srv/config/set`
**请求:**
```json
{
"msg_id": 7,
"cmd": "iot_topic_set",
"ts": 1719000000,
"data": {
"client_id_enable": true,
"topic_pub": "dld960/data/A1B2C3D4E5F6",
"topic_sub": "dld960/cmd/A1B2C3D4E5F6"
}
}
```
**响应:** 标准成功/失败。
## 4.8 查询设备 Topic `iot_topic_query`
> Topic: `dld960/{sn}/srv/config/query`
**请求:**
```json
{
"msg_id": 8,
"cmd": "iot_topic_query",
"ts": 1719000000
}
```
**响应:** 返回字段同 4.7 的 `data`
## 4.9 验证设备密码 `pwd_verify`
> Topic: `dld960/{sn}/srv/ctrl`
**请求:**
```json
{
"msg_id": 9,
"cmd": "pwd_verify",
"ts": 1719000000,
"data": {
"password": "123456"
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `password` | string | 6 位数字密码 |
**响应:**
```json
{
"msg_id": 9,
"cmd": "pwd_verify",
"ts": 1719000001,
"code": 0,
"msg": "success"
}
```
## 4.10 设置设备密码 `pwd_set`
> Topic: `dld960/{sn}/srv/ctrl`
**请求:**
```json
{
"msg_id": 10,
"cmd": "pwd_set",
"ts": 1719000000,
"data": {
"old_password": "123456",
"new_password": "654321"
}
}
```
**响应:** 标准成功/失败。旧密码错误时 `code=2`
## 4.11 设备出厂初始化 `factory_reset`
> Topic: `dld960/{sn}/srv/ctrl`
**请求:**
```json
{
"msg_id": 11,
"cmd": "factory_reset",
"ts": 1719000000
}
```
**响应:**
```json
{
"msg_id": 11,
"cmd": "factory_reset",
"ts": 1719000001,
"code": 0,
"msg": "success"
}
```
## 4.12 设备复位 `device_reset`
> Topic: `dld960/{sn}/srv/ctrl`
**请求:**
```json
{
"msg_id": 12,
"cmd": "device_reset",
"ts": 1719000000
}
```
无响应(设备复位后断开连接)。
## 4.13 设置车检器多路参数 `loop_param_set`
> Topic: `dld960/{sn}/srv/config/set`
**请求:**
```json
{
"msg_id": 13,
"cmd": "loop_param_set",
"ts": 1719000000,
"data": {
"auto_mode": false,
"channels": [
{
"ch": 1,
"sensitivity": 7,
"freq_level": "high",
"loop_delay": 0,
"output_mode": "exist",
"exist_mode": 0,
"direction_mode": 0,
"safe_mode": 0,
"function_mode": 0
},
{
"ch": 2,
"sensitivity": 7,
"freq_level": "mid_high",
"loop_delay": 5,
"output_mode": "enter_pulse",
"exist_mode": 10,
"direction_mode": 0,
"safe_mode": 0,
"function_mode": 0
},
{
"ch": 3,
"sensitivity": 5,
"freq_level": "mid_low",
"loop_delay": 0,
"output_mode": "exist",
"exist_mode": 0,
"direction_mode": 1,
"safe_mode": 5,
"function_mode": 0
},
{
"ch": 4,
"sensitivity": 8,
"freq_level": "low",
"loop_delay": 10,
"output_mode": "leave_pulse",
"exist_mode": 15,
"direction_mode": 0,
"safe_mode": 0,
"function_mode": 0
}
]
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `auto_mode` | bool | 自动调频模式,默认 false |
| `channels` | array | 各路通道参数1~4 路 |
| `channels[].ch` | uint8 | 通道号 1~4 |
| `channels[].sensitivity` | uint8 | 灵敏度 0~9默认 7 |
| `channels[].freq_level` | string | `"high"`(33nF) / `"mid_high"`(43nF) / `"mid_low"`(66nF) / `"low"`(76nF) |
| `channels[].loop_delay` | uint8 | 延时时间0~200×0.1s),最大 20s |
| `channels[].output_mode` | string | `"exist"` / `"enter_pulse"` / `"leave_pulse"` / `"direction"` |
| `channels[].exist_mode` | uint8 | 存在方式0=永久非0=分钟数 |
| `channels[].direction_mode` | uint8 | 方向判别模式0=触发1~6=方向输出 |
| `channels[].safe_mode` | uint8 | 安全模式0=关闭非0=分钟数 |
| `channels[].function_mode` | uint8 | 功能模式 |
**响应:**
```json
{
"msg_id": 13,
"cmd": "loop_param_set",
"ts": 1719000001,
"code": 0,
"msg": "success"
}
```
## 4.14 读取车检器多路参数 `loop_param_query`
> Topic: `dld960/{sn}/srv/config/query`
**请求:**
```json
{
"msg_id": 14,
"cmd": "loop_param_query",
"ts": 1719000000
}
```
**响应:**
```json
{
"msg_id": 14,
"cmd": "loop_param_query",
"ts": 1719000001,
"code": 0,
"msg": "success",
"data": {
"auto_mode": false,
"channels": [
{
"ch": 1,
"sensitivity": 7,
"freq_level": "high",
"loop_delay": 0,
"output_mode": "exist",
"exist_mode": 0,
"direction_mode": 0,
"safe_mode": 0,
"function_mode": 0,
"freq_initial": 105300,
"freq_current": 105280,
"freq_diff": 20
}
]
}
}
```
| 额外字段 | 类型 | 单位 | 说明 |
|----------|------|------|------|
| `freq_initial` | uint32 | Hz | 初始频率 |
| `freq_current` | uint32 | Hz | 当前实时频率 |
| `freq_diff` | uint32 | Hz | 频率变化量(绝对值) |
## 4.15 设置主动上报 `report_config`
> Topic: `dld960/{sn}/srv/ctrl`
**请求:**
```json
{
"msg_id": 15,
"cmd": "report_config",
"ts": 1719000000,
"data": {
"sensor_type": 12,
"enable": true,
"once": false,
"env_eval": false,
"interval": 5,
"ack_required": false,
"timeout": 0
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `sensor_type` | uint8 | 传感器类型,线圈=0x0C(12) |
| `enable` | bool | 是否使能主动上报 |
| `once` | bool | 仅上报一次(查询模式) |
| `env_eval` | bool | 环境评估使能 |
| `interval` | uint8 | 上报间隔0=实时 |
| `ack_required` | bool | 上报是否需要确认 |
| `timeout` | uint8 | 超时时间分钟0=无限制 |
**响应:** 标准成功/失败。
---
# 5 设备主动上报
## 5.1 线圈传感数据 `loop_data`
> Topic: `dld960/{sn}/dev/data/loop`
> QoS: 0/1
```json
{
"msg_id": 100,
"cmd": "loop_data",
"ts": 1719000100,
"data": {
"channels": [
{
"ch": 1,
"freq_level": "high",
"has_car": false,
"loop_ok": true,
"freq_current": 105280,
"freq_diff": 20,
"sensitivity": 7,
"condition": 0,
"misc": {
"type": "time",
"value": 0
}
},
{
"ch": 2,
"freq_level": "mid_high",
"has_car": true,
"loop_ok": true,
"freq_current": 98700,
"freq_diff": 1500,
"sensitivity": 7,
"condition": 2,
"misc": {
"type": "time",
"value": 350
}
},
{
"ch": 3,
"freq_level": "mid_low",
"has_car": false,
"loop_ok": false,
"freq_current": 0,
"freq_diff": 0,
"sensitivity": 5,
"condition": 0,
"misc": {
"type": "cut_count",
"value": 3
}
},
{
"ch": 4,
"freq_level": "low",
"has_car": false,
"loop_ok": true,
"freq_current": 62100,
"freq_diff": 5,
"sensitivity": 8,
"condition": 0,
"misc": {
"type": "flow_count",
"value": 128
}
}
]
}
}
```
| 通道字段 | 类型 | 说明 |
|----------|------|------|
| `ch` | uint8 | 通道号 1~4 |
| `freq_level` | string | 线圈高低频档位 |
| `has_car` | bool | 是否有车 |
| `loop_ok` | bool | 线圈是否正常false=断开) |
| `freq_current` | uint32 | 当前频率 (Hz) |
| `freq_diff` | uint32 | 频率变化量 (Hz) |
| `sensitivity` | uint8 | 当前灵敏度等级 |
| `condition` | uint8 | 环境状态评估值(越大干扰越大) |
| `misc.type` | string | `"time"`(时间量) / `"cut_count"`(断开次数) / `"flow_count"`(车流量) |
| `misc.value` | uint32 | 杂项数值(时间量单位 5ms |
## 5.2 事件上报 `event_report`
> Topic: `dld960/{sn}/dev/data/event`
设备检测到事件时主动上报,非周期性。
```json
{
"msg_id": 101,
"cmd": "event_report",
"ts": 1719000200,
"data": {
"events": [
{
"type": "car_enter",
"ch": 2,
"value": 0
},
{
"type": "car_leave",
"ch": 2,
"value": 350
},
{
"type": "loop_cut",
"ch": 3,
"value": 0
}
]
}
}
```
| 事件类型 `type` | 说明 | `value` 含义 |
|----------------|------|-------------|
| `car_enter` | 车辆进入 | 0 |
| `car_leave` | 车辆离开 | 通过时间 (×5ms) |
| `loop_cut` | 线圈断开 | 0 |
| `loop_restore` | 线圈恢复 | 断开持续时长 (×5ms) |
## 5.3 设备心跳 `heartbeat`
> Topic: `dld960/{sn}/dev/status`
> 周期:默认 60 秒
```json
{
"msg_id": 200,
"cmd": "heartbeat",
"ts": 1719000060,
"data": {
"uptime": 3600,
"loop_status": [true, true, false, true],
"net_status": true,
"iot_status": true
}
}
```
| data 字段 | 类型 | 说明 |
|-----------|------|------|
| `uptime` | uint32 | 设备运行时长(秒) |
| `loop_status` | bool[4] | 各路线圈是否正常 |
| `net_status` | bool | 以太网连接状态 |
| `iot_status` | bool | MQTT 连接状态 |
---
# 修订记录
| 版本 | 修订时间 | 修订说明 | 修订人 |
|------|----------|----------|--------|
| V1.00 | 2026-06-22 | 初始版本,基于串口协议 V1.01 | wangfq |