--[[ @module app_iot @summary vd960Air 设备业务: initialize 上线 / heartbeat 心跳 / 主循环驱动 @version 0.1 @date 2026.08.31 @usage - on_connected(): MQTT 连接成功后调用 → 发 initialize(extra_info imei/iccid + link) - heartbeat 定时任务: 60s 发 heartbeat(协议 §5.4,带 link) - poll(): 主循环驱动 uart_app 事件重发检查(可挂 sys.timerLoopStart) ]] local CFG = require "config" local link_info = require "link_info" local clock = require "clock" local app_iot = {} local HEARTBEAT_INTERVAL = CFG.CFG_HEARTBEAT_INTERVAL or 60 -- 上行 JSON 注入 link local function inject_link(payload) if CFG.CFG_LINK_ENABLE then local ok, obj = pcall(json.decode, payload) if ok and type(obj) == "table" then obj.link = link_info.get() return json.encode(obj) end end return payload end -- 组 initialize(协议 §5.1,extra_info 含 imei/iccid V1.13) local function build_initialize() local info = link_info.get() local payload = string.format( '{"msg_id":1,"cmd":"initialize","ts":%d,' .. '"data":{"dev_serial":"%s","model":"%s","hard_ver":"%s","soft_ver":"%s",' .. '"loop_ver":"%s","loop_hw_ver":"%s",' .. '"extra_info":{"code":"%s","imei":"%s","iccid":"%s","csq":"%s","location":""}}}', clock.now(), CFG.CFG_DEV_SERIAL, CFG.CFG_MODEL or "DLD960", CFG.CFG_HW_VER or "1.0", CFG.CFG_SW_VER or "1.0", CFG.CFG_LOOP_VER or "", CFG.CFG_LOOP_HW_VER or "", info.imsi, info.imei, info.iccid, tostring(info.csq)) return inject_link(payload) end -- 组 heartbeat(协议 §5.4) local function build_heartbeat() local uart_app = require "uart_app" local loop_ok = uart_app.get_loop_status() local ls = string.format('[%s,%s,%s,%s]', tostring(loop_ok[1]), tostring(loop_ok[2]), tostring(loop_ok[3]), tostring(loop_ok[4])) local payload = string.format( '{"msg_id":%d,"cmd":"heartbeat","ts":%d,' .. '"data":{"uptime":%d,"loop_status":%s,"net_status":true,"iot_status":true}}', math.floor(mstick() / 1000) % 100000 + 1000, clock.now(), math.floor(mstick() / 1000), ls) return inject_link(payload) end -- MQTT 连接成功后调用 function app_iot.on_connected() -- 发 initialize(上线) local payload = build_initialize() sys.publish("SEND_DATA_REQ", "vd960DBN", CFG.CFG_TOPIC_UP, payload, 1) log.info("app_iot", "initialize sent") end -- 心跳定时任务 local function heartbeat_task() while true do sys.wait(HEARTBEAT_INTERVAL * 1000) local payload = build_heartbeat() sys.publish("SEND_DATA_REQ", "vd960DBN", CFG.CFG_TOPIC_UP, payload, 0) log.info("app_iot", "heartbeat sent") end end -- 主循环驱动: 事件重发检查(500ms 粒度) local function poll_task() local uart_app = require "uart_app" while true do sys.wait(500) uart_app.poll() end end -- 初始化(evt_queue 复位 + 启动定时任务) function app_iot.init() local evt_queue = require "evt_queue" evt_queue.init() sys.taskInit(heartbeat_task) sys.taskInit(poll_task) log.info("app_iot", "init ok") end return app_iot