Files
vd_960/docs/DLD960_IoT_MQTT协议.md
T
wangfq e54334e761 docs: event_report 不受 report_config.enable 门控 (王工拍板)
- devlog 决策落定, 移除待确认标记
- MQTT/TCP 两协议 §5.x 补充: enable/interval 仅管 loop_data, 事件上报解耦
2026-07-15 13:45:51 +08:00

20 KiB
Raw Blame History

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 结构

协议仅使用两个主题,所有消息类型通过 JSON 内 cmd 字段区分。

dld960/{dev_serial}/{direction}
字段 说明
dev_serial 设备序列码(6字节十六进制字符串,如 A1B2C3D4E5F6
direction srv = 服务器下发(设备订阅),dev = 设备上报(服务器订阅)

1.2.1 服务器下发 Topic — dld960/{sn}/srv

设备订阅此主题,接收服务器下发的所有命令(配置设置、查询、控制等)。 服务器发布到此主题。

对应串口 CMD0x09 ~ 0x1F, 0x63, 0x64, 0xC5 等。

1.2.2 设备上报 Topic — dld960/{sn}/dev

设备发布到此主题,上报线圈数据、事件、心跳及命令响应。 服务器订阅此主题接收所有设备上行消息。

服务器端可订阅通配符 dld960/+/dev 监听所有设备。


2 JSON 消息格式

2.1 通用结构

{
  "msg_id": 12345,
  "cmd": "dev_info_query",
  "ts": 1719000000,
  "data": { ... }
}
字段 类型 说明
msg_id uint32 消息序列号,递增,用于请求-响应匹配(由发起方生成)
cmd string 命令标识符
ts uint32 Unix 时间戳(秒),发起方填充
data object 命令参数,结构依 cmd 而定

2.2 响应通用结构

{
  "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
initialize 设备上电初始化登陆 dev→srv
loop_data 线圈传感数据上报 dev→srv 0xC0
event_report 事件上报(平台须应答,见 §5.3 dev→srv
heartbeat 设备心跳 dev→srv

4 命令详情

4.1 更改设备序列码 dev_serial_set

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 1,
  "cmd": "dev_serial_set",
  "ts": 1719000000,
  "data": {
    "dev_serial": "A1B2C3D4E5F6"
  }
}

响应: Topic: dld960/{sn}/dev

{
  "msg_id": 1,
  "cmd": "dev_serial_set",
  "ts": 1719000001,
  "code": 0,
  "msg": "success"
}

4.2 查询设备信息 dev_info_query

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 2,
  "cmd": "dev_info_query",
  "ts": 1719000000
}

响应:

{
  "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

请求:

{
  "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 端口号

响应:

{
  "msg_id": 3,
  "cmd": "ssc_net_set",
  "ts": 1719000001,
  "code": 0,
  "msg": "success"
}

4.4 查询 SSC 网络配置 ssc_net_query

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 4,
  "cmd": "ssc_net_query",
  "ts": 1719000000
}

响应: 返回字段同 4.3 的 data

4.5 设置 IoT 网络配置 iot_net_set

Topic: dld960/{sn}/srv

请求:

{
  "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

请求:

{
  "msg_id": 6,
  "cmd": "iot_net_query",
  "ts": 1719000000
}

响应: 返回字段同 4.5 的 data

4.7 设置设备 Topic iot_topic_set

Topic: dld960/{sn}/srv

请求:

{
  "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

请求:

{
  "msg_id": 8,
  "cmd": "iot_topic_query",
  "ts": 1719000000
}

响应: 返回字段同 4.7 的 data

4.9 验证设备密码 pwd_verify

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 9,
  "cmd": "pwd_verify",
  "ts": 1719000000,
  "data": {
    "password": "123456"
  }
}
data 字段 类型 说明
password string 6 位数字密码

响应:

{
  "msg_id": 9,
  "cmd": "pwd_verify",
  "ts": 1719000001,
  "code": 0,
  "msg": "success"
}

4.10 设置设备密码 pwd_set

Topic: dld960/{sn}/srv

请求:

{
  "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

请求:

{
  "msg_id": 11,
  "cmd": "factory_reset",
  "ts": 1719000000
}

响应:

{
  "msg_id": 11,
  "cmd": "factory_reset",
  "ts": 1719000001,
  "code": 0,
  "msg": "success"
}

4.12 设备复位 device_reset

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 12,
  "cmd": "device_reset",
  "ts": 1719000000
}

无响应(设备复位后断开连接)。

4.13 设置车检器多路参数 loop_param_set

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 13,
  "cmd": "loop_param_set",
  "ts": 1719000000,
  "data": {
    "auto_mode": false,
    "channels": [
      {
        "ch": 1,
        "sens": 7,
        "level": "high",
        "delay": 0,
        "output": "exist",
        "exist": 0,
        "dir": 0,
        "safe": 0,
        "fun_mode": 0
      },
      {
        "ch": 2,
        "sens": 7,
        "level": "mid_high",
        "delay": 5,
        "output": "enter_pulse",
        "exist": 10,
        "dir": 0,
        "safe": 0,
        "fun_mode": 0
      },
      {
        "ch": 3,
        "sens": 5,
        "level": "mid_low",
        "delay": 0,
        "output": "exist",
        "exist": 0,
        "dir": 1,
        "safe": 5,
        "fun_mode": 0
      },
      {
        "ch": 4,
        "sens": 8,
        "level": "low",
        "delay": 10,
        "output": "leave_pulse",
        "exist": 15,
        "dir": 0,
        "safe": 0,
        "fun_mode": 0
      }
    ]
  }
}
data 字段 类型 说明
auto_mode bool 自动调频模式,默认 false
channels array 各路通道参数,1~4 路
channels[].ch uint8 通道号 1~4
channels[].sens uint8 sensitivity, 灵敏度 0~9,默认 7
channels[].level string freq_level, "high"(33nF) / "mid_high"(43nF) / "mid_low"(66nF) / "low"(76nF)
channels[].delay uint8 loop_delay, 延时时间,0~200(×0.1s),最大 20s
channels[].output string exist_mode, "exist" / "enter_pulse" / "leave_pulse" / "direction"
channels[].exist uint8 output_mode, 存在方式,0=永久,非0=分钟数
channels[].dir uint8 direction_mode, 方向判别模式,0=触发,1~6=方向输出
channels[].safe uint8 safe_mode, 安全模式,0=关闭,非0=分钟数
channels[].fun_mode uint8 function_mode, 功能模式

响应:

{
  "msg_id": 13,
  "cmd": "loop_param_set",
  "ts": 1719000001,
  "code": 0,
  "msg": "success"
}

4.14 读取车检器多路参数 loop_param_query

Topic: dld960/{sn}/srv

请求:

{
  "msg_id": 14,
  "cmd": "loop_param_query",
  "ts": 1719000000
}

响应:

{
  "msg_id": 14,
  "cmd": "loop_param_query",
  "ts": 1719000001,
  "code": 0,
  "msg": "success",
  "data": {
    "auto_mode": false,
    "channels": [
      {
        "ch": 1,
        "sens": 7,
        "level": "high",
        "delay": 0,
        "output": "exist",
        "exist": 0,
        "dir": 0,
        "safe": 0,
        "fun_mode": 0,
        "f_initial": 105300,
        "f_current": 105280,
        "diff": 20
      }
    ]
  }
}
额外字段 类型 单位 说明
f_initial uint32 Hz freq_initial, 初始频率
f_current uint32 Hz freq_current, 当前实时频率
diff uint32 Hz 变化量(绝对值)

4.15 设置主动上报 report_config

Topic: dld960/{sn}/srv

请求:

{
  "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 设备上电登陆信息 initialize

Topic: dld960/{sn}/dev QoS: 0/1

{
  "msg_id": 1,
  "cmd": "initialize",
  "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",
    }
  }
}
字段 类型 说明
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 可选,经纬度(经度,纬度)

5.2 线圈传感数据 loop_data

Topic: dld960/{sn}/dev QoS: 0/1

{
  "msg_id": 100,
  "cmd": "loop_data",
  "ts": 1719000100,
  "data": {
    "channels": [
      {
        "ch": 1,
        "level": "high",
        "iscar": false,
        "loop_ok": true,
        "freq": 105280,
        "diff": 20,
        "sens": 7,
        "cndtn": 0,
        "misc": {
          "type": "time",
          "value": 0
        }
      },
      {
        "ch": 2,
        "level": "mid_high",
        "iscar": true,
        "loop_ok": true,
        "freq": 98700,
        "diff": 1500,
        "sens": 7,
        "cndtn": 2,
        "misc": {
          "type": "time",
          "value": 350
        }
      },
      {
        "ch": 3,
        "level": "mid_low",
        "iscar": false,
        "loop_ok": false,
        "freq": 0,
        "diff": 0,
        "sens": 5,
        "cndtn": 0,
        "misc": {
          "type": "cut_count",
          "value": 3
        }
      },
      {
        "ch": 4,
        "level": "low",
        "iscar": false,
        "loop_ok": true,
        "freq": 62100,
        "diff": 5,
        "sens": 8,
        "cndtn": 0,
        "misc": {
          "type": "flow_count",
          "value": 128
        }
      }
    ]
  }
}
通道字段 类型 说明
ch uint8 通道号 1~4
level string freq_level 线圈高低频档位
iscar bool 是否有车
loop_ok bool 线圈是否正常(false=断开)
freq uint32 当前频率 (Hz)
diff uint32 变化量
sens uint8 sensitivity, 当前灵敏度等级
cndtn uint8 condition, 环境状态评估值(越大干扰越大)
misc.type string "time"(时间量) / "cut_count"(断开次数) / "flow_count"(车流量)
misc.value uint32 杂项数值(时间量单位 50ms

5.3 事件上报 event_report

上报 Topic: dld960/{sn}/dev 应答 Topic: dld960/{sn}/srv QoS: 1(建议) ⚠️ 本指令要求平台必须应答(区别于 loop_data / heartbeat 的单向上报)

设备检测到事件时主动上报,非周期性。事件(进车/出车/线圈断开等)是不可再生的关键数据MQTT QoS 仅保证 broker 收到,不代表平台业务层已处理入库,因此引入应用层应答 + 设备重发机制闭环确认。

event_report 不受 report_config.enable 门控——设备上电即检测并上报事件。report_configenable/interval 仅控制 loop_data 周期上报,与事件上报解耦。

设备上报(dev topic):

{
  "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 车辆离开 通过时间 (×50ms)
loop_cut 线圈断开 0
loop_restore 线圈恢复 断开持续时长 (×50ms)

平台应答(srv topic,收到后必须立即回复):

{
  "msg_id": 101,
  "cmd": "event_report",
  "ts": 1719000201,
  "code": 0,
  "msg": "success"
}
字段 说明
msg_id 必须回显设备上报的 msg_id,设备以此匹配确认
cmd 固定 "event_report"
code 0 = 已接收并处理;非 0 = 处理失败(设备视同未确认,进入重发)

设备端确认与重发机制:

  1. 发出 event_report 后启动确认定时器,5s 内未收到 msg_id 匹配且 code=0 的应答 → 重发;
  2. 重发使用相同的 msg_id 与原始 ts(首次事件发生时间,不随重发刷新),平台以此去重;
  3. 最多重发 3 次(含首发共 4 次)。仍未确认 → 事件保留在待发队列,待 MQTT 重连成功或下一次事件触发时合并上报;
  4. 等待确认期间新产生的事件,合并进下一包的 events 数组(使用新 msg_id)。单包长度受发布缓冲限制(≤500B),超出时拆包分批;
  5. 待发队列建议深度 ≥16 条事件,溢出时丢弃最旧事件(先保新鲜数据)。

平台端要求:

  1. 收到 event_report 先落库、后应答,应答即承诺数据已持久化;
  2. (dev_serial, msg_id) 在近期窗口(建议 10 分钟)内去重——重复包为设备未收到应答所致,直接应答 code=0,不重复入库(设备重启后 msg_id 从头递增,去重必须限定时间窗口);
  3. 应答报文应控制在最小集(不带 data),减轻设备下行解析负担。

时序(正常 / 应答丢失重发):

设备                        平台
 │── event_report(id=101) ──▶│  落库
 │◀─ ack(id=101, code=0) ────│  确认, 事件出队
 │
 │── event_report(id=102) ──▶│  落库
 │      ✗ 应答丢失            │
 │  [5s 超时]                 │
 │── event_report(id=102) ──▶│  (dev_serial,102) 命中去重 → 不入库
 │◀─ ack(id=102, code=0) ────│  确认, 事件出队

5.4 设备心跳 heartbeat

Topic: dld960/{sn}/dev 周期:默认 60 秒

{
  "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
V1.01 2026-07-07 Topic 压缩为双主题({sn}/srv + {sn}/dev),消息类型由 cmd 字段区分 wangfq
V1.02 2026-07-09 缩写相关字段 wangfq
V1.03 2026-07-09 增加设备上电初始化指令 wangfq
V1.04 2026-07-15 event_report 增加平台必答机制:应答格式(回显 msg_id)、设备 5s 超时重发(同 msg_id/ts,最多 3 次)、待发队列合并上报、平台去重与先落库后应答要求 wangfq