feat(vd960Air): 方案 C MVP — 0x7F 帧解析 + 标准 JSON 上报(2026-08-31)

协议依据:《DLD960_IoT_MQTT协议》V1.13(4G 通道适配方案 C)

新增模块:
- frame_parser.lua: 0x7F 帧解析状态机(Lua 版 lup_feed_byte, XOR+SUM 校验)
- proto_conv.lua: 0xC0 传感帧 → loop_data + car_state/loop_state 沿检测(4 类线圈事件)
- evt_queue.lua: event_report 队列 + ACK 状态机(16深/5s×3/跨重连同 msg_id,对齐 DBN)
- clock.lua: report_config 时钟校准(协议 §2.3)
- app_iot.lua: initialize(extra_info imei/iccid + link)/ heartbeat / poll 驱动
- tools/sim_frame_test.py: 帧协议参考验证(56B 帧/4 路解析/沿检测/JSON 格式,全过)

改造:
- uart_app.lua: 0x7D 帧 → 0x7F 帧驱动;loop_data/event_report 组包 + link 注入
- mqtt_receiver.lua: 下行分发(ACK 路由 + 时钟校准)
- mqtt_main.lua: 连接成功 → initialize + 未决事件重发
- config.lua/main.lua: 方案 C 配置与入口

MVP 范围: 上行(initialize/loop_data/event_report/heartbeat)+ report_config;
下行命令转换与 0x7D 配置同步列入 P1。
This commit is contained in:
wangfq
2026-08-31 15:47:43 +08:00
parent 6d763f02fe
commit 3ad7ae8f09
11 changed files with 796 additions and 207 deletions
@@ -22,6 +22,8 @@ local mqtt_receiver = require "mqtt_receiver"
local mqtt_sender = require "mqtt_sender"
-- 加载vd960Air配置
local CFG = require "config"
-- 设备业务(initialize/heartbeat)
local app_iot = require "app_iot"
-- mqtt服务器地址和端口(来自config.lua,商用服务器)
local SERVER_ADDR = CFG.CFG_MQTT_HOST
@@ -191,6 +193,10 @@ local function mqtt_client_main_task_func()
log.info("mqtt_client_main_task_func", "connect success")
-- 通知mqtt sender数据发送应用模块的task,MQTT连接成功
sys.sendMsg(mqtt_sender.TASK_NAME, "MQTT_EVENT", "CONNECT_OK", mqtt_client)
-- vd960Air: 上线发 initialize + 未决事件包立即重发
app_iot.on_connected()
local uart_app = require "uart_app"
uart_app.on_mqtt_reconnect()
-- mqtt连接失败
else
log.info("mqtt_client_main_task_func", "connect error")
@@ -1,64 +1,55 @@
--[[
@module mqtt_receiver
@summary mqtt client数据接收处理应用功能模块
@version 1.0
@date 2025.07.29
@author 马梦阳
@summary MQTT 下行命令分发(方案 C)
@version 0.2
@date 2026.08.31
@usage
本文件为mqtt client 数据接收应用功能模块,核心业务逻辑为:
处理接收到的publish数据,同时将数据发送给其他应用功能模块做进一步处理;
本文件的对外接口有2个:
1、mqtt_receiver.proc(topic, payload, metas)publish数据处理入口,在mqtt_main.lua中调用;
2、sys.publish("RECV_DATA_FROM_SERVER", "recv from mqtt server: ", topic, payload)
将接收到的publish中的topic和payload数据通过消息"RECV_DATA_FROM_SERVER"发布出去;
需要处理数据的应用功能模块订阅处理此消息即可,本demo项目中uart_app.lua中订阅处理了本消息;
平台下行(dld960/{sn}/srv)处理:
- event_report ACK(回显 msg_id + code=0)→ evt_queue 出队
- report_config → 时钟校准(信封 ts,协议 §2.3)
- 其他标准 JSON 命令(loop_param_*/log_*/ota_* 等)→ P1: 转 0x7F 帧下发 vd960Loop(待实现)
- frame_cmd(可选兜底)→ P1: hex 解码 → UART1 透传(待实现)
]]
local mqtt_receiver = {}
local function proc(topic, payload, metas)
if not payload or payload:len() == 0 then
return
end
local ok, obj = pcall(json.decode, payload)
if not ok or type(obj) ~= "table" then
log.warn("mqtt_receiver", "bad json")
return
end
--[[
处理接收到的publish数据
local cmd = obj.cmd
local msg_id = obj.msg_id or 0
local code = obj.code
@api mqtt_receiver.proc(topic, payload, metas)
if cmd == "event_report" then
-- 平台 ACK: 回显 msg_id + code;code=0 → 出队
local uart_app = require "uart_app"
uart_app.handle_event_ack(msg_id, code or 0)
log.info("mqtt_receiver", "evt ack", msg_id, code)
@param1 topic string
表示publish主题
elseif cmd == "report_config" then
-- 时钟校准(信封 ts 填当前 Unix 秒)
local clock = require "clock"
clock.sync(obj.ts or 0, mstick())
log.info("mqtt_receiver", "clock sync", obj.ts)
@param2 payload string
表示publish数据负载
else
-- P1: 下行命令转换(loop_param_*/log_*/ota_* 等)暂未实现
log.info("mqtt_receiver", "down cmd", cmd, "msg_id", msg_id)
end
@param2 payload string
表示publish数据负载
-- 喂网络看门狗
sys.publish("FEED_NETWORK_WATCHDOG")
end
@param3 metas table
表示publish报文的一些参数;格式如下:
{
qos: number类型,取值范围0,1,2
retainnumber类型,取值范围0,1
dupnumber类型,取值范围0,1
message_id: number类型
}
@return1 result nil
@usage
mqtt_receiver.proc(topic, payload, metas)
]]
function mqtt_receiver.proc(topic, payload, metas)
log.info("mqtt_receiver.proc", topic, payload:len(), json.encode(metas))
-- 接收到数据,通知网络环境检测看门狗功能模块进行喂狗
sys.publish("FEED_NETWORK_WATCHDOG")
-- 将topic和payload通过"RECV_DATA_FROM_SERVER"消息publish出去,给其他应用模块处理
-- vd960Air: 直接传原始 payload,由 uart_app 组帧后下发 vd960DBN
sys.publish("RECV_DATA_FROM_SERVER", topic, payload)
-- 也可以直接在此处编写代码,处理topic和payload
proc(topic, payload, metas)
end
return mqtt_receiver