Commit Graph
201 Commits
Author SHA1 Message Date
wangfq 70e44e6241 docs(roadmap): 补充脱机日志子系统 + 日志导出管理 + 远程OTA路线细化
- P1.2 脱机日志: W25Qxx 分区规划(参数/事件流/快照流/OTA暂存),
  事件流必录清单, 快照流同频落盘挂 iot_sensor_ingest 同源出口,
  无RTC时间戳方案(boot_seq+mstick+时钟锚点)
- P1.3 导出与管理: MQTT断网补报/命令分页拉取/BLE小程序读取
  三通道, log_stat/log_clear(鉴权+审计自记录)
- P1.4 远程OTA: 先走现网MQTT+复用ISP透传底层(与BLE OTA同构);
  Loop先存后刷+断点续传+回滚, 继电器安全底线;
  DBN自身远程OTA三路线比选(过渡态=仍走BLE最稳妥)
- 风险表新增: 无RTC时间戳、日志写与总线争用
2026-07-17 18:57:13 +08:00
wangfq ea29433633 docs: 新增 ROADMAP — V1.0.0 之后的开发计划 (P0稳固→P1上云→P2算法→P3会车)
- P0 (v1.1.0): BLE透传重构收尾(0xC0三消费方真值表) + TODO清剿
  (loop_ok硬编码/MQTT接收溢出防护) + 工装回归清单
- P1 (v1.2.x): edc_server消费契约(先落库后ACK)、流量API、
  远程OTA方案评审、4G通道预研
- P2 (v2.0.0): 抗变频器干扰(先现场采CAPVD取证)、双线圈测速+
  车型粗分类、半截车双峰识别、方向判别
- P3 (v2.x): 会车控制 — 业务只认event_report、异常分支先行、
  纯平台/纯单机/混合三方案对比
2026-07-17 18:13:29 +08:00
wangfq 579eeecb23 docs: 校准通信接口表述 — DLD960 无 RS485 接口
- 对外通信 = 网口(TCP JSON/MQTT) + 蓝牙(小程序/OTA) + 扩展TTL串口(预留4G上云, RFU)
- 内部双 MCU 经 UART TTL 互联 (0x7F @192000)
- 修正范围: README/CHANGELOG/技术规格书/产品手册/硬件资源文档概述
- acceptance-standard 中 RS-485 为通用验收检查项, 保留
2026-07-16 16:39:02 +08:00
wangfq d61ff830aa fix(vd960DBN): BUFF_STACK_SIZE 512→64 对齐 Loop 侧串口帧缓冲
- 串口帧缓冲装的是 Loop↔DBN 的 0x7F 私有协议帧, 与 Loop 侧发送缓冲(64)同源
- 当前最大帧 0x0C 多线圈上报实测 56B (Len=51), 64 留 8B 余量, 512 严重浪费
- g_pkg_uart_1/2 各省 448B, 合计回收 ~896B SRAM
- 顺带删除零引用死结构体 USART_DMA_UNIT + RX_BUFFER_LEN 宏
2026-07-16 14:52:16 +08:00
wangfq c0bdcd956d docs: 新增产品手册 + 技术规格书 (V1.00, 配套整机 V1.0.0)
- 产品手册: 接口/指示灯/线圈施工要求/快速上手/参数配置/故障排查
- 技术规格书: 双MCU架构/检测规格/灵敏度阈值表(SensTable换算)/算法机制/协议矩阵/配套要求
- README: 文档索引挂接产品文档
2026-07-16 10:31:10 +08:00
wangfq 130054658a docs: 整理发布文档 — 重写根 README + 新增 CHANGELOG (V1.0.0)
- README: 双MCU架构图、子项目/固件版本表、协议版本矩阵、文档索引、发布流程
- CHANGELOG: V1.0.0 首发说明 — Loop/DBN 配套版本矩阵、双侧功能汇总、已知约束
v1.0.0
2026-07-16 10:02:44 +08:00
wangfq 6284bca0cb fix(iot_mqtt): loop_data 陈旧快照 — 事件与缓存统一帧摄取 (同源)
现场: 长车离开后 event_report 正确, 但 loop_data 连续 34s/100+ 条
iscar:true 陈旧快照, 且冻结 diff=517 锁死 fast_mode 300ms 刷屏。

根因: 0xC0 帧两条竞争消费路径数据源分裂 —
  uart_srv→lup回调只喂事件不更新 _cached_sr;
  Step1 直读才更新缓存, 但赢得竞争概率实测 ~2%
→ 事件每帧必达而快照冻结, 出现'事件说车走了、快照说车还在'。

修复:
- 新增 iot_sensor_ingest(): 事件沿 + _cached_sr 刷新单一入口,
  回调与 Step1 两路汇入, 帧竞争不再影响数据新鲜度
- Step1 直读路径补 lup_verify_checksum (此前裸解析未校验)
2026-07-15 17:48:30 +08:00
wangfq a457b81916 feat(iot_mqtt): loop_data 上报调度升级三档 — car_state 沿立即上报
原双速率下进/出车沿最坏等 300ms 门控。改为三档:
- 立即档: 任一通道 car_state 翻转沿 → 直通间隔门控立即发布
- 快速档: |variation|>阈值 → 300ms (不变)
- 空闲档: 配置 interval, 默认 60s (不变)

要点:
- car_edge 优先级最高; 快照仍在门控后刷新, 同沿只触发一次立即档
- 防洪泛天然有界: Loop 事件帧最快 150ms/帧 且 car_state 为防抖后状态
- 协议 §5.2 补上报节奏说明; tests/test_report_cadence.c 8 组全过
2026-07-15 16:56:21 +08:00
wangfq 3e28174b40 feat(mqtt): 设备时钟同步方案B — 平台经 report_config 下发 Unix ts (协议V1.05)
设备无RTC/SNTP, 原上行 ts=mstick()/1000(上电秒数)。方案B:
- net_srv.c 新增 dev_time_sync()/dev_time_now(): 门槛≥1600000000挡上电秒数,
  已校准返回真Unix, 未校准退回上电秒数; 无符号相减处理mstick 49.7天回绕
- manage_mqtt_recv_message 从下行命令信封 ts 校准 (report_config主同步点)
- 全部上行 ts (14处命令响应+initialize+loop_data+event_report) 改 dev_time_now()
  heartbeat uptime 字段保留 mstick()/1000 (运行时长非时间戳)
- 协议 V1.05 §2.3 时间同步 + report_config 兼任同步点职责
- tests/test_dev_time_sync.c 6组全过

平台侧配合: 收到 initialize 后下发 report_config 时 ts 填当前 Unix 时间
2026-07-15 15:25:44 +08:00
wangfq e3eaa111fe fix(mqtt): 修复 loop_data>512B 溢出发垃圾包致 broker RST 重连风暴 (现场P0)
根因(非平台推测的环形缓冲/event_report队列):
  mqtt_publish 的 mqttBuf=512B < loop_data(4通道)604B
  → MQTTSerialize_publish 返回 -2 不写 buf
  → len 为 uint32_t, -2 变 42.9亿
  → WCHNET 把清零缓冲+越界相邻全局(temp_guide=report_config→report_c)
    当 520B 垃圾包发出 → broker 见非法类型0x00 RST → 重连风暴

修复(net_srv.c):
  - MAX_MQTTBUF_LEN 512→1024 (容纳 604B loop_data)
  - mqtt_publish: len uint32→int + 守卫 if(len<=0)return (序列化失败绝不发残缓冲)
  - keepalive 9→60 (报告建议, 9s过激)

event_report 协议违规修复(iot_mqtt_srv.c):
  - 重连重发保持原 msg_id/ts (V1.04 §5.3-2), 不再作废换号致平台去重失效

验证: tests/test_mqtt_publish_overflow.c 复现旧垃圾包+验证守卫/大缓冲;
      tests/test_event_report.c T8 断言重连同 msg_id. 均全过.
遗留: ts=上电秒数非Unix时间戳, 待定方案(设备无RTC/SNTP)

Refs: docs/incidents/2026-07-15-DC045A49718F-protocol-error.md
2026-07-15 14:58:03 +08:00
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
wangfq 4112b7cbbf feat(iot_mqtt): 实现 event_report 平台必答+设备重发 (协议 V1.04); 时间单位统一 50ms
时间单位:
- 串口协议 V1.06 / TCP JSON 协议: 杂项时间量、事件 value 由 5ms 修正为
  50ms, 对齐 Loop 固件 50ms tick 实现 (TMR15 5ms×10)

event_report (iot_mqtt_srv.c + net_srv.c):
- 沿检测双路汇聚: Step1 消费路径 + lup 回调覆盖 uart_srv 路径, 不漏帧
- 16 深环形队列, 事件仅 ACK(code=0) 后出队; 溢出丢最旧
- 5s 超时重发同 msg_id/原始 ts ×3 次, 耗尽挂起, 新事件/重连沿合并补报
- 帧消费提前至 READY/enable 之前: 断网期间事件入队, 重连补报
- 线圈断开期间屏蔽 car 沿; loop_restore value=本地计时/50
- msg_id 独立 uint32 计数 (g_iot_msg_id 为 uint8 混用会破坏去重窗口)
- net_srv.c ACK 路由: cmd=event_report 回显帧确认出队, 不回 unsupported
- gcc 隔离单测 8 组全过 (tests/test_event_report.c), 单包 6 条实测 317B
2026-07-15 12:27:22 +08:00
wangfq 0861a1c1f8 proto: event_report 增加平台/客户端必答确认机制 (MQTT V1.04 / TCP V1.01)
事件为不可再生关键数据, QoS/TCP送达不代表业务层落库, 引入应用层闭环:
- 应答格式: 回显 msg_id + code/msg, 不带 data
- 设备重发: 5s 超时, 同 msg_id/原始 ts, 最多 3 次, 失败留队列
  待重连或下一事件合并上报 (MQTT ≤500B / TCP ≤4096B 拆包)
- 平台/客户端: 先落库后应答; msg_id 十分钟窗口去重, 重复包答 code=0 不重复入库
- 附正常/应答丢失重发时序图; 命令详表与交互示例同步
2026-07-15 11:55:21 +08:00
wangfq dc7dd1cb26 feat(iot_mqtt): 快速上报增加 car_state 翻转沿触发
- Step2: 任一通道 |variation|>=阈值 或 car_state 翻转沿, 均进入 300ms 快速档
  (高灵敏度档小车 variation 可能不过阈值, 但 Loop 已判翻转, 事件不应慢发)
- 修复首版两坑: if(fast_mode=0) 单等号致沿检测死代码;
  快照刷新移到间隔门控之后, 防止沿被门控吞掉后退化为空闲慢发
- gcc 隔离单测: buggy 沿后延迟 950ms vs fixed 250ms, 出车沿/负向variation回归通过
- devlog 补 2026-07-15 条目
2026-07-15 09:34:04 +08:00
wangfq 964d619f10 docs(vd960Loop): variation 分析报告标记 DBN 解析端升级已核实
代码核对确认: 步长12B/bit23符号扩展/misc偏移/fast_mode双向绝对值均已落地
2026-07-15 08:46:20 +08:00
wangfq 7c5920805d docs(vd960Loop): variation-analysis.md 对齐协议 V1.05 (变化量 2B无符号→3B有符号)
- 全文口径切换: variation = Origin - CAPVD, 3B LE 补码, ±2^23 饱和
- 新增 §5 变更分析: 回绕污染/方向丢失缺陷、符号语义、bit23 符号扩展、
  步长 11→12 死绑定的静默错位风险及 Len 字节兼容方案
- 波形场景补充方向语义: 锯齿极性=漂移方向, 持续负值=基线污染诊断
- 旧问题清单更新: 2B 截断标记已解决; 待验证新增新旧固件混跑错位复现
2026-07-15 08:38:22 +08:00
wangfq 82e01cd337 docs(devlog): 记录 variation 2B->3B有符号升级 (V1.05)
- vd960Loop/docs/devlog.md: 组包端改动(uint32->int32,方案B,饱和防回绕),
  背景/影响范围/验证
- vd960DBN/docs/devlog.md: 接收端4处联动(结构体/解析步长/符号扩展/
  fast_mode abs阈值), 缓冲核查
两端均标注必须同版本发布
2026-07-14 16:48:25 +08:00
wangfq bfc9646e48 proto(V1.05): variation 由 2B无符号 扩展为 3B有符号
背景: variation 是遥测量, 用于离线跟踪分析车检器算法。原 2B 无符号
存在两个缺陷: (1)CAPVD域量级~131072, 大车全覆盖时偏差可超65535而回绕,
污染数据; (2)绝对值丢失方向, 分不清'车进入'与'反向漂移'。

改动 (三端联动, 同版本发布):
- 协议 DLD960Loop_串口通信协议.md: 变化量 2B->3B有符号补码, 定义
  variation=Origin-CAPVD (正=车/裕量, 负=反向漂移); 每单元11->12B,
  Len 47->51; 补符号扩展说明; 示例报文重算(XOR=FE SUM=38); 修订记录V1.05
- vd960Loop main.c: 组包 uint32->int32, Origin-CAPVD, 3B LE, +-2^23饱和防回绕
- vd960DBN loop_uart_proto.h: variation uint16->int32
- vd960DBN loop_uart_proto.c: 步长11->12, data_len/11->/12, misc偏移右移1B,
  variation 3B解码+bit23符号扩展
- vd960DBN iot_mqtt_srv.c: fast_mode 阈值判断改 abs(variation)>=10, 正负变化都加速

验证: 本地 gcc 隔离单测 编解码往返/符号扩展/饱和/方向语义/fast_mode 全通过;
大车 diff=100000 旧版回绕34464 新版正确保留。字节账: 帧56B < Loop缓冲64B
< DBN缓冲512B < MSS576, 均不溢出。整体固件编译需在 Keil/MounRiver 侧完成。
2026-07-14 14:47:39 +08:00
wangfq db52f92348 docs: 新增 variation 上报量分析报告
分析 uart_report_packet_loop_acs 中 variation=|Origin-CAPVD| 的更新机制:
- 三操作数节奏: CAPVD~10ms / Origin 5s阶跃 / 上报窗150/600ms采样
- Origin 基线状态机: 稳定期(win100~1s)/正常(win500~5s)/冻结/冻结超时(~10s)/有车冻结
- 波形特征: 无车漂移锯齿波、车辆驻留干净跟随、大干扰防污染冻结
- 风险: 采样混叠、2B截断回绕、锯齿谷误判空闲、稳定期切换拐点
2026-07-14 11:47:19 +08:00
wangfq 403770e1c8 feat(iot_mqtt): 传感器MQTT主动上报改为双速率间隔上报
- 新增传感器数据缓存(_cached_sr), 0xC0帧到达时更新缓存, 不上报
- 根据各通道 variation 决定上报间隔:
  空闲态(diff < 10): 使用 g_report_cfg.interval 秒
  变化态(diff >= 10): 固定 300ms 快速上报
- interval=0 时自动退化为最小 1s 空闲间隔
- 断线时清缓存+复位计时, 重连后等新帧首发
- 消除对 g_pkg_uart_2.flag 的硬依赖, 从缓存自主定时上报

新增常量:
  IOT_MQTT_FAST_INTERVAL_MS     300
  IOT_MQTT_VARIATION_THRESHOLD  10
  IOT_MQTT_IDLE_INTERVAL_MIN_MS 1000
2026-07-13 10:57:40 +08:00
wangfq c2fb459a80 vd960DBN docs: 开发日志更新 V3.2 — 双主题统一 + initialize 对齐 + packet_id 断连修复 2026-07-10 15:02:04 +08:00
wangfq 01ab739d05 vd960DBN: 修复 mqtt_publish QoS>0 时 packet_id=0 导致 broker 断连
MQTT 规范要求 QoS≥1 的 PUBLISH 必须带非零 packet_id。
net_srv.c 的 mqtt_publish 硬编码 packet_id=0,broker 检测到协议违规后主动断开连接。
修复:QoS>0 时使用递增的 packet_id。
2026-07-10 09:20:14 +08:00
wangfq 01db1e6a1c DBNMQTTool: 增加 dld960/+/dev/# 订阅兼容旧固件多级 topic
旧固件响应发布到 dld960/{sn}/dev/config/resp 等多级路径,
单级通配 dld960/+/dev 无法匹配,# 通配确保向后兼容。
2026-07-10 09:12:31 +08:00
wangfq 9d9e4fa4bc DBNMQTTool: initialize 消息解析后同步显示设备型号到列表
- device_manager.mark_online 增加 model/hard_ver/soft_ver 参数
- 修复旧格式 extra_info.version 取 soft_ver 的问题
- main.py 的 initialize 处理传入完整设备信息
2026-07-10 09:04:39 +08:00
wangfq 11d1a96d24 同步协议 V1.03:双主题发布对齐 + initialize 数据格式修正
vd960DBN:
- heartbeat/sensor/initialize 发布统一走 dld960/{sn}/dev
- dev_initialize_pub 补 model/hard_ver/soft_ver,删 extra_info.version

DBNMQTTool:
- 协议版本号更新至 V1.03
- 协议 Topic 树和模拟页增加 initialize 支持
2026-07-10 08:49:28 +08:00
wangfq 652fc5f938 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
2026-07-09 21:32:39 +08:00
wangfq 1ff731c309 fix(docs): initialize 消息结构修正 — snake_case + data包装
- extra_Info → extra_info(命名风格统一)
- 字段表加 data.extra_info.* 路径前缀
- JSON 结构统一为 data: {...} 包装,加 ts
2026-07-09 19:00:43 +08:00
wangfq c515638032 fix: MQTT协议 V1.02 同步 — 字段名缩短 + 时间单位修正
- docs/DLD960_IoT_MQTT协议.md: 字段缩写 + 时间单位 5ms→50ms
- vd960DBN/iot_mqtt_srv.c: 6字段缩短对齐协议 (level/iscar/freq/diff/sens/cndtn)
- vd960DBN/tcp_json_srv.c: gap_ms5/passtime_ms → gap/passtime
- vd960DBN/loop_uart_proto.h: 注释 5ms→50ms
- DBNMQTTool/main.py: 模拟样本数据字段同步
2026-07-09 10:18:03 +08:00
wangfq 466ce00680 feat(iot_mqtt): 恢复 loop_data 完整字段 + 分批发送(2通道/包)
按 DLD960_TCP_JSON协议.md §5.1 恢复完整字段:
- ch, freq_level, has_car, loop_ok, freq_current, freq_diff,
  sensitivity, condition, misc.type, misc.value

每包发 2 个通道,确保 JSON < 450 字节 (mqttBuf 512 安全范围内)。
4 通道设备每次 SensorReport 发 2 条 loop_data 消息。
2026-07-08 17:21:06 +08:00
wangfq 4c6d23a951 fix(iot_mqtt): 传感数据 topic 改为 V1.01 双主题协议 dld960/{sn}/dev
原 iot_make_topic("dev","data","loop") → dld960/{sn}/dev/data/loop (V1.00)
改为直接用 g_iot_topic.topic_pub → dld960/{sn}/dev (V1.01)
与 report_config 等命令响应共用同一 topic,DBNMQTTool 订阅 dld960/+/dev 可接收到
2026-07-08 16:54:23 +08:00
wangfq 8425b473d3 fix: net_srv.h 添加 mqtt_publish() 声明供 iot_mqtt_srv.c 调用 2026-07-08 16:12:20 +08:00
wangfq 8232ec2c55 fix(iot_mqtt): 改用 net_srv.c mqtt_publish() 发送传感数据
iot_mqtt_publish_sensor() 原先调用 iot_mqtt_publish() →
iot_mqtt_send() → WCHNET_SocketSend() 从主循环发送导致重启。
改为调用 net_srv.c 的 mqtt_publish()(与 report_config 响应
共用同一路径,已验证在中断上下文中稳定工作)。

同时在 net_srv.h 中声明 mqtt_publish() 供跨文件调用。
2026-07-08 16:11:50 +08:00
wangfq 2175fee742 fix(iot_mqtt): 移除 iot_mqtt_send() hex dump 循环避免栈溢出重启
hex dump 连续 65 次 PRINT 调用消耗大量栈空间,
在 CH32V208 2KB 栈限制下导致溢出重启.
改为仅打印 len 和 ret/status.
2026-07-08 15:52:43 +08:00
wangfq a71adaafdc fix(iot_mqtt): 精简 loop_data JSON 避免 WCHNET_SocketSend 超大包崩溃
问题: 4通道传感器数据 JSON ~700字节 → MQTT Publish 733字节
      超过 WCHNET TCP MSS(576) 和原始 MAX_MQTTBUF_LEN(512) 设计上限
      WCHNET_SocketSend(733) 导致设备重启

修复:
- 移除非必要字段: freq_current, freq_diff, condition
- 展平 misc 嵌套对象 → mt(类型) + mv(数值)
- 缩短 key 名: freq_level→fl, has_car→car, loop_ok→ok, sensitivity→sens
- 每通道 ~70字, 4通道 ~280, 全包 ~400字节
- 加安全检查: payload >450 时跳过并打印警告
2026-07-08 15:09:50 +08:00
wangfq 555cdb741d fix(iot_mqtt): g_iot_socket 未初始化导致 WCHNET_SocketSend(0xFF) 硬故障重启
根因: iot_mqtt_srv.c 中 g_iot_socket 初始化为 0xFF,
仅 iot_connect_broker() 中设为 SocketId_TCP.
但内联 MQTT 模式(iot_mqtt_poll 从未调用)下该赋值永不执行.
iot_mqtt_publish_sensor() 调用 iot_mqtt_send() →
WCHNET_SocketSend(0xFF, ...) → HardFault → 设备重启.

修复: iot_mqtt_init() 中设置 g_iot_socket = SocketId_TCP,
该函数在 net_srv_init() flag==1 时被调用(含首次启动和每次重连).
2026-07-08 09:11:23 +08:00
wangfq 0e116c2d31 fix(net_srv): MQTT 主动上报无数据 + PINGREQ 缺失导致断连
问题1: iot_mqtt_publish_sensor() 检查 g_iot_state != IOT_STATE_READY 直接 return,
但 g_iot_state 从未被 net_srv.c 内联 MQTT 处理器设置为 READY → 无传感数据上报

问题2: poll_mqtt() 依赖 flag_mqtt_ping_send 触发 PINGREQ,
但该标志从未被设为 1 → broker keepalive 超时断连 (~12s)

修复:
- mqtt_data_manage() CONNACK: 设 g_iot_state=IOT_STATE_READY
- WCHNET_HandleSockInt DISCONNECT: 设 g_iot_state=IOT_STATE_DISCONNECTED
- mqtt_data_manage() PINGRESP: 重置 flag_mqtt_ping_err
- poll_mqtt(): g_activ_counter > 9000 自动触发 PINGREQ
2026-07-08 08:55:10 +08:00
wangfq de2e70fd89 feat(vd960DBN): MQTT ssc_net_set / iot_net_set / iot_topic_set 实现
- ssc_net_set: 解析 dev_ip/subnet_mask/route_ip/lssc_ip/dns/port,调用 write_net_config
- iot_net_set: 解析 host/port/client_id/username/password,调用 write_net_config
- iot_topic_set: 解析 client_id_enable/topic_pub/topic_sub,调用 write_net_config
- 三个 SET 命令均写入 flash 并在完成后返回 code=0 success
2026-07-07 21:15:55 +08:00
wangfq 2bbe388738 fix: iot_mqtt_srv.c 添加缺失的 tcp_json_srv.h include 2026-07-07 18:47:05 +08:00
wangfq a7de4dfcde feat(vd960DBN): MQTT/TCP report_config 支持完整7参数配置
- 新增 ReportConfig 结构体 (sensor_type/enable/once/env_eval/interval/ack_required/timeout)
- net_srv.c: MQTT report_config handler — 查询/设置均返回完整配置JSON
- tcp_json_srv.c: TCP JSON handle_report_config 同步升级,兼容旧 active_report
- iot_mqtt_srv.c: g_report_active → g_report_cfg.enable
- g_report_active 全局变量替换为 g_report_cfg 结构体
2026-07-07 18:39:45 +08:00
wangfq cd92f3e0c3 feat(DBNMQTTool): 查询响应自动回填输入框 + 主动上报配置
- _on_message 中 ssc_net/iot_net/iot_topic/report_config 查询结果
  不再仅显示 JSON,改为调用 _apply_* 方法回填到对应输入框
- 新增「主动上报配置」GroupBox(sensor_type / interval / timeout
  + 4 开关),支持查询/设置 CMD_REPORT_CONFIG
- import 增加 CMD_REPORT_CONFIG / data_report_config
2026-07-07 18:22:39 +08:00
wangfq b932dd7c6f feat: DBNMQTTool 日志增强 — 收发打印 topic + payload 详情
新增 _log_send() / _log_recv() 两个统一日志方法:
- 发送: 标签 + → topic + PASTE:{精简payload}
- 接收: ← topic + summary + RECV:{精简payload}
- payload >200/300 字符自动截断

覆盖所有收发路径:
- [模拟]/[协议]/[自定义]/[命令] 发送
- 响应/loop_data/event_report/heartbeat/Initialize 接收
- mqtt_client.py 自动订阅事件日志
2026-07-07 17:47:58 +08:00
wangfq 5e4e1b1ec7 fix: DeviceManager 死锁 — threading.Lock 改为 RLock
根因: update_from_dev_info/update_loop_data/update_event/update_heartbeat
      在 with self._lock 块内调用 get_or_create(), 后者再次 with self._lock.
      Python threading.Lock 不可重入 → 永久阻塞 → GUI 无响应.

修复: self._lock = threading.RLock() (可重入锁)

清理: mqtt_client.py 移除 debug print 和未使用的 sys import
2026-07-07 17:36:35 +08:00
wangfq c98aa5b0bb fix: MqttClient 回退信号方案,添加 publish debug 日志追踪阻塞点
- 移除 QObject 基类和 QueuedConnection 信号方案
- publish() 直接调用 self._client.publish() 并打印前后日志
- 添加 print(flush=True) 确保 Windows 终端实时输出

目的是确认阻塞发生在:
  [MqttClient] publish topic=... qos=1  ← 打印后消失?
  [MqttClient] publish done mid=...      ← 这行能否出现?
2026-07-07 17:27:15 +08:00
wangfq baa82c895d fix: MqttClient 重构为 QObject — publish 通过 Qt 信号排队避免 C 层崩溃
问题: paho-mqtt publish() C 扩展在 Windows 上从 GUI 线程调用时静默崩溃。

修复:
- MqttClient 改为 QObject 子类
- publish() 通过 Qt Signal(Qt.QueuedConnection) 排队,_do_publish()
  始终在主线程事件循环中执行 paho 调用
- 状态/消息通知改用 Qt Signal 跨线程传递
- 新增 subscribe()/unsubscribe() 公开 API,消除 main.py 直接
  访问 _client 的脆弱代码
- 移除 MainWindow 中已不再需要的中间信号 _mqtt_status/_mqtt_msg
2026-07-07 14:25:49 +08:00
wangfq 6eb93637c7 fix: DBNMQTTool — 所有 publish 路径增加通用异常捕获
问题: _custom_publish / _proto_publish / _sim_publish 只 catch
json.JSONDecodeError, MqttClient.publish() 抛出的 ConnectionError
等异常未被捕获, 在 Qt 信号槽中导致静默崩溃(Windows 无 traceback).

修复:
- _custom_publish: +except Exception, 避免 toPlainText() 重复调用
- _proto_publish: +except Exception, 避免 toPlainText() 重复调用
- _sim_publish: +except Exception
- _custom_subscribe/_custom_unsubscribe: +except Exception, +_client 空检查
2026-07-07 14:15:36 +08:00
wangfq 5a2ef0be5d fix: DBNMQTTool — right 局部变量改为 self._notebook
_build_ui() 中 right = QTabWidget() 是局部变量,导致
_proto_publish_item() 中 self._notebook.setCurrentWidget() 报
AttributeError: 'MainWindow' object has no attribute '_notebook'
2026-07-07 14:07:52 +08:00
wangfq 90d723517e feat: manage_mqtt_recv_message 实现 V1.01 协议命令分发
net_srv.c: manage_mqtt_recv_message() 从占位打印升级为完整命令分发器:

已实现(8条):
- dev_info_query: 返回设备信息(序列码/版本/子码)
- ssc_net_query: 返回 SSC 网络配置
- iot_net_query: 返回 IoT 网络配置(MQTT broker)
- iot_topic_query: 返回 topic 配置
- pwd_verify: 验证设备密码
- factory_reset: 出厂初始化+重启
- device_reset: 设备复位

未实现(返回 code=4):
- dev_serial_set, pwd_set, ssc_net_set 等 SET 类命令

所有响应通过 g_iot_topic.topic_pub (dld960/{sn}/dev) 发布
2026-07-07 13:58:27 +08:00
wangfq 3cdc5b6286 fix: MQTT PUBLISH 接收修复 — topic 过滤 + cmd/Method 双格式支持
问题: mqtt_data_manage() 的 PUBLISH 分支直接调用 manage_mqtt_recv_message(),
      跳过了 mqtt_deserialize_publish() 的 topic 过滤, 且只支持旧 Method 格式.

修复:
- mqtt_data_manage: PUBLISH 改为走 mqtt_deserialize_publish 做 topic 匹配
- mqtt_deserialize_publish: topic 过滤已改用 g_iot_topic.topic_sub
- manage_mqtt_recv_message: 优先解析 cmd, 兼容旧 Method 字段
2026-07-07 12:09:07 +08:00
wangfq ab3a4cea0a fix: 出厂默认 topic 使用真实设备序列号 + PRINT 修正
- cfig_flash.c: factory_dev_info() 用 gMacAddr 生成真实主题 dld960/{SN}/srv + dld960/{SN}/dev
- net_srv.h: TOPIC_DEFAULT 加注释标明为格式模板
- net_srv.c: 修复上次提交的 PRINT 宏转义异常
2026-07-07 10:57:20 +08:00
wangfq b707241429 feat: MQTT 双主题同步到 vd960DBN 固件 + DBNMQTTool devlog
vd960DBN 固件改动:
- net_srv.h: 默认 topic 改为 dld960/{sn}/srv + dld960/{sn}/dev
- net_srv.c: dg_subscribe_display_topic() 直接用 topic_sub 订阅(不再追加 client_id/sn 后缀)
- net_srv.c: mqtt_deserialize_publish() topic 过滤改用 g_iot_topic.topic_sub(不再硬编码 TOPIC_DEFAULT_SUBSCRIBE)

DBNMQTTool 文档:
- devlog.md: 清理过期 topic 引用语义
2026-07-07 09:46:54 +08:00