Files
vd_960/DBNMQTTool/docs/devlog.md
T
wangfq f2141976f0 feat(vd960DBN)+fix(DBNMQTTool): MQTT 查询命令补齐 + 工具命令集对齐 (2026-08-18)
固件 (V4.2):
- iot_mqtt_srv.c 补齐 ssc_net_query / iot_net_query / iot_topic_query (只读全局组包, 与 TCP JSON §4.5/4.7/4.9 对齐)
- 修复实测: MQTT 通道 ssc_net_query/iot_net_query 返回 code=4 unsupported

工具:
- 禁用固件未实现的 6 个按钮 (ssc/iot_net/iot_topic_set + pwd_set/factory_reset/device_reset) + tooltip 引导 TCP/BLE
- 设备刷新列表移除 loop_param_query (固件未实现)
- offscreen 验证按钮状态正确
2026-08-18 11:44:52 +08:00

8.9 KiB
Raw Blame History

DBNMQTTool 开发日志

DLD960 IoT MQTT 桌面工具 | Python 3.11+ | PySide6 | paho-mqtt v2 | 跨平台 (Windows/Linux/macOS)

定位: DLD960 车检器 MQTT 调试工具 — 设备管理、实时数据监控、模拟上报、主题订阅/发布


2026-08-18 — 命令集对齐:禁用固件未实现的 MQTT 命令按钮

背景

实测发现 MQTT 通道 ssc_net_query / iot_net_query 返回 code=4 unsupported command——固件 MQTT 分发只实现 6 条命令,工具按协议文档命令表做了全按钮。

变更

  • 固件同步补齐vd960DBN V4.2):ssc_net_query / iot_net_query / iot_topic_query 三条查询命令已实现,工具对应查询按钮保持可用
  • 工具禁用固件仍未实现的命令按钮:ssc_net_set / iot_net_set / iot_topic_set / pwd_set / factory_reset / device_resetsetEnabled(False) + tooltip 引导走 TCP JSON/BLE 通道)
  • 设备刷新列表移除 CMD_LOOP_PARAM_QUERY(固件未实现,刷新时不再报 error)

验证

  • offscreen 实例化:6 个按钮禁用 + tooltip 正确,查询类/验证密码/report_config/log_* 可用

2026-08-18 — 脱机日志支持快照流 (stream=snapshot, 协议 V1.07)

变更

  • protocol.py:新增 STREAM_EVENT / STREAM_SNAPSHOT 常量;data_log_querystream 参数(快照流显式传 stream 字段 + count≤2);新增 data_log_clear(stream)(事件流省略 data 兼容老固件);新增 SNAP_MISC_TYPE_DESCtime/cut_count/flow_count/relay_count 中文描述)
  • main.py:脱机日志区加"日志流"选择器(事件日志/传感快照);统计/拉取/清除三按钮按当前流发请求(log_clear 确认框提示阻塞时长 2.8s/45ms);log_stat/log_query 响应展示区分流——快照记录解析 channels[] 逐字段(freq_level/direction/freq_type/sens/cond/loop/car/freq/variation/misc

验证

  • protocol 数据构建器断言 6 例全过(事件流不带 stream / 快照流 count≤2 / log_clear 流参数)
  • QT_QPA_PLATFORM=offscreen 实例化 MainWindow 实测:log_stat(snapshot) capacity=48064 展示、log_query(snapshot) 2 条快照记录逐字段展示(含负 variation、misc_type 中文)、事件流展示回归无损、空记录边界
  • 依赖:venv + PySide6 + paho-mqttvenv/ 已加 .gitignore

配套

  • 固件 vd960DBN log_* stream=snapshot 分支(同日实现,devlog V4.1
  • 协议文档:TCP JSON V1.03 / IoT MQTT V1.07

2026-07-06 (晚) — 模拟上报 + 协议Topic + 自定义Topic c19e465

1. 模拟上报 Tab

  • loop_data / event_report / heartbeat 三类上报携带独立可编辑 JSON 编辑区
  • 范例填充:首次切换类型时自动填入协议定义的标准载荷
  • 单次发送 + 周期上报QSpinBox 可调间隔)
  • 周期开关由 QPushButton toggle 控制

2. 协议Topic Tab

  • 预加载双主题:dld960/{sn}/srv(下发)、dld960/{sn}/dev(上报)
  • QListWidget 展示,双击自动填充到发布区
  • 发布区可编辑 JSON 载荷,一键发布
  • 主题列表受 SN 输入框驱动,实时更新

3. 自定义Topic Tab

  • 自由输入 topic + JSON 载荷,QoS (0/1/2) 可调
  • 订阅 / 取消订阅,接收消息实时展示在 QPlainTextEdit
  • # / + 通配符支持,paho.mqtt.topic_matches_sub 路由匹配
  • 自定义订阅的消息自动分发到接收区,附带 topic 前缀

4. 新增依赖

  • paho.mqtt.client 导入新增 topic_matches_sub
  • UI 控件: QComboBox, QSpinBox, QPlainTextEdit

2026-07-06 — paho-mqtt v2 回调修复 213c0dd

问题

断开连接时报错:

TypeError: MqttClient._on_disconnect() missing 1 required positional argument: 'reason_code'

根因

paho-mqtt v2 默认 callback_api_version=VERSION2on_disconnect 回调签名为 5 参数 (client, userdata, flags, reason_code, properties),而 v1 为 3 参数 (client, userdata, rc)

修复

  • _on_disconnect 改用 *args 兼容 v1/v2
  • Client 构造显式指定 callback_api_version=CallbackAPIVersion.VERSION2
  • _on_connect 保持 v2 签名不变

2026-07-06 — tkinter → PySide6 迁移 e1bf3dc

决策

放弃 tkinter,改用 PySide6 (Qt for Python),理由:

  • 跨平台原生外观 (Fusion 风格)
  • Qt 信号/槽机制替代 tkinter 回调,更易维护
  • 组件丰富 (QGroupBox, QSplitter, QTabWidget 等)

改动

  • main.py 全量重写为 PySide6 主窗口
  • 布局: QGroupBox 分组 → QSplitter 分栏 → QTabWidget 功能分区
  • requirements.txt 新增 PySide6>=6.6.0
  • tkinter → Qt 映射: StringVar→信号/槽, ListboxQListWidget, TextQTextEdit

2026-07-06 — 项目初始化 a2cfe46

功能 (初始版本, tkinter)

  • MQTT Broker 连接管理
  • 设备自动发现 (dld960/+/dev 通配符订阅)
  • 设备信息查询 + 主题配置
  • 实时线圈数据 / 事件上报 / 心跳 监控
  • 控制命令: 密码验证/设置、出厂初始化、设备复位

项目结构

DBNMQTTool/
├── main.py                  # 主窗口 (tkinter → 后迁移至 PySide6)
├── dbn_mqtt_tool/
│   ├── protocol.py          # DLD960 IoT MQTT 协议定义 (主题/命令/载荷模板)
│   ├── mqtt_client.py       # MQTT 客户端封装 (paho-mqtt v2)
│   └── device_manager.py    # 设备发现与状态管理
└── requirements.txt         # paho-mqtt>=2.0.0 + PySide6>=6.6.0

协议依据

DLD960_IoT_MQTT协议.md V1.00


当前状态

组件 状态
MQTT 连接/断开 已实现,v1/v2 兼容
设备发现 通配符订阅
实时数据监控 loop_data/event_report/heartbeat
控制命令 15 条命令
模拟上报 c19e465
协议Topic订阅/发布 c19e465
自定义Topic订阅/发布 c19e465
固件联调 vd960DBN IoT 模式稳定上报

2026-07-07 — MQTT V1.01 适配 + 稳定性修复

1. MQTT 协议 V1.01 适配

  • Topic 从多主题(/loop_data, /event_report, /heartbeat, /cmd…)压缩为双主题 dld960/{sn}/dev(上报)、dld960/{sn}/srv(下发)
  • manage_mqtt_recv_message() 实现 V1.01 协议命令分发,支持 cmd/Method 双格式
  • MQTT PUBLISH 接收修复:topic 过滤 + 通配符路由修正

2. MqttClient 重构:tkinter 回调 → QObject 信号/槽

问题: paho.mqtt C 层回调直接操作 Qt UI 控件 → RuntimeError: wrapped C/C++ object has been deleted 崩溃。

修复:

  • MqttClient 继承 QObject,使用 Qt 信号/槽机制
  • on_messagemessage_received 信号 → 主线程 slot 安全更新 UI
  • 所有 publish 路径增加通用异常捕获,防止未捕获异常导致静默崩溃
  • 回退 Qt 信号排队方案,改用 QMetaObject.invokeMethod + 日志追踪定位阻塞点

3. DeviceManager 死锁修复

threading.Lock 在单线程 Qt 事件循环中自锁 → RLockadd_device()remove_device() 同线程互调时 Lock 阻塞自身。

4. UI/UX 改进

  • 日志增强: 收发打印 topic + payload 详情,调试信息更直观
  • 查询响应自动回填: 设备信息查询后自动填充 SN 等输入框
  • 主动上报配置: report_config 面板支持完整 7 参数独立开关
  • right 局部变量 → self._notebook,修复 tab 引用丢失

2026-08-05 — 脱机事件日志命令支持 (MQTT V1.06)

配合 vd960DBN 固件 P1.3commit 1a01316+ 协议 V1.06,工具新增脱机事件日志面板(参数配置 Tab 底部):

新增命令

命令 按钮 说明
log_stat 统计 日志统计/分页定位: enabled/boot_seq/count/capacity/seq_first/seq_last
log_query 拉取日志 按全局序号分页拉取, 起始序号 + 条数(1~4) 可调
log_clear 清除日志 二次确认弹窗, 审计留痕不可撤销

实现要点

  • protocol.py: 新增 CMD_LOG_* 常量、LOG_COMMANDS 集合、data_log_query() 构建器(start_seq≥1 / count 1~4 边界钳制)、LOG_EVENT_TYPE_DESC 事件类型中文描述(10 类 + unknown
  • main.py: 参数配置 Tab 新增 g6 组(起始序号/条数 spinbox + 三按钮 + 只读显示区 QPlainTextEdit
  • _on_message code==0 分支新增 log_stat/log_query/log_clear 响应处理
  • 显示优化: log_query 记录带事件类型中文描述; unix_ts 已同步显示真实时间, 未同步显示 boot+ts_ms(未同步)
  • 清除日志前 QMessageBox 二次确认(防误触, 与出厂初始化/设备复位同模式)

验证

  • py_compile 四个模块通过
  • protocol 逻辑单测: data_log_query 边界钳制 (0→1, 99→4, 0→1)、命令枚举一致性、build_request 带 data