Skip to content

核心业务流程

1. 设备上行:数据上报 (Telemetry)

这是设备主动向平台汇报状态的流程。

时序图

详细步骤

  1. 采集:设备(如四路继电器)检测到开关状态变化或周期性读取传感器数据。
  2. 发布:设备将数据封装为 JSON 格式,发布到 Topic sys/{product_id}/{device_id}/thing/event/property/post
  3. 接收后端服务作为 MQTT 客户端,通过 TCP 长连接实时收到订阅的消息。
  4. 处理
    • 后端服务校验数据格式与设备身份。
    • 更新 Redis 影子缓存(热缓存,用于 WebSocket 实时推送)。
    • 更新 Redis 在线状态SET device:online:{id} = 1 EX 120)。
    • 写入 PostgreSQL 设备影子(权威源,用于 API 查询和审计)。
    • 将时序数据写入 InfluxDB 存档。
  5. 推送:如果用户正在查看小程序,后端通过 WebSocket/SSE 将最新状态实时推送给前端。

2. 设备在线状态(属性上报驱动)

平台维护设备在线状态,由属性上报消息驱动 + Redis TTL 自动过期实现,不使用 EMQX Webhook。

原理

每次设备属性上报 → 后端 SET device:online:{id} = 1, EX 120s
120 秒内无新上报 → Redis key 过期 → 判定离线

设计理由

  1. 解耦:不依赖 EMQX Webhook 配置,EMQX 和后端各自独立运行
  2. 语义准确:"在线" = "设备在主动上报数据",比"TCP 连接存在"更有业务意义
  3. 部署零配置:切换测试/生产环境不需要改 EMQX 配置

在线状态查询

API 查询设备列表时,后端优先从 Redis 读取在线状态。key 存在 = 在线,key 不存在 = 离线。同时将在线状态同步回 PostgreSQL(isOnline 字段)以保持持久化层一致。

对于设备刚连接但尚未发第一条属性上报的窗口(通常 2-5 秒),设备显示为离线。这在业务场景中不构成问题——设备上报第一条数据后立即变更为在线。

3. 应用下行:指令控制 (Command)

这是用户通过手机控制设备的流程。

时序图

详细步骤

  1. 操作:用户在小程序点击"开启继电器 1"。
  2. 请求:小程序发送 HTTPS 请求 POST /device/control 携带目标设备 ID 和指令参数。
  3. 鉴权:后端服务验证用户是否有权限控制该设备。
  4. 下发
    • 后端生成控制指令 Payload。
    • 后端通过 MQTT 发布到 Topic sys/{product_id}/{device_id}/thing/service/property/set
  5. 执行:设备收到 MQTT 消息,解析指令,驱动继电器动作。
  6. 反馈
    • 设备动作完成后,发布响应消息到 sys/.../set_reply 确认执行结果。
    • 后端收到确认后,更新数据库状态,并返回操作成功给小程序(或通过异步通知)。

4. 设备首次注册与激活 (Device Registration)

设备配网时,后端提前在数据库创建设备记录。设备上电后使用预置凭证连接,EMQX 直连 PostgreSQL 进行认证。

时序图

详细步骤

第一阶段:配网时预先注册

  1. 配网:用户通过小程序 BLE 配网,扫描设备并写入 WiFi 信息(详见第 6 节)。
  2. 创建设备:配网成功后,小程序调用后端 API 创建设备记录。后端在 PostgreSQL 中写入设备物理 ID(MAC)、ProductKey、DeviceSecret(随机生成)。
  3. 返回凭证:后端将 DeviceSecret 返回给小程序,小程序通过 BLE 写入设备或提示用户。

第二阶段:设备上电连接

  1. 连接:设备上电后,以 MAC 作为 ClientId,ProductKey 为 Username,DeviceSecret 为 Password,向 EMQX 发起 MQTT CONNECT。
  2. 认证:EMQX 直接查询 PostgreSQL devices 表,比对凭证。查询到匹配记录则允许连接。

第三阶段:配置下发

  1. 下发配置:后端通过 sys/{pid}/{did}/thing/config/set Topic 下发逻辑 ID 和 MQTT Topic 列表。
  2. 保存:设备收到配置后,将逻辑 ID 写入 NVS(非易失存储),回复 set_reply 确认。

第四阶段:开始上报

  1. 首次上报:设备通过 sys/{pid}/{did}/thing/event/property/post 上报属性。
  2. 标记在线:后端收到首次属性上报后,在 Redis 设置在线标记(TTL 120s),更新 PostgreSQL 最后上线时间。
  3. 后续通信:设备所有通信均使用逻辑 ID,不再暴露物理 MAC 地址。

5. OTA 固件升级 (Firmware OTA)

设备固件远程升级的端到端流程,涵盖固件上传、升级通知、下载校验、安装重启和状态上报。

时序图

详细步骤

  1. 上传固件:运维人员在 Web 后台上传新固件,后端存储到 OSS/MinIO,并在 PostgreSQL 记录版本号、下载 URL、文件大小和 MD5 校验值。
  2. 触发升级:运维人员选择目标设备(单设备或批量),触发升级任务。
  3. 通知设备:后端通过 sys/{pid}/{did}/thing/ota/upgrade Topic 向设备推送升级通知。
  4. 下载固件:设备收到通知后,通过 HTTP/HTTPS 从 OSS 下载固件文件。
  5. 进度上报:设备每下载 10%,通过 thing/ota/progress Topic 上报进度。后端通过 WebSocket 推送到 Web 后台实时展示。
  6. 校验:下载完成后,设备计算文件 MD5 并与通知中的 MD5 比对。
  7. 安装:校验通过后,设备将固件写入 OTA 分区,设置启动标记,上报 progress=100, desc="flashing"。
  8. 重启:设备自动重启,运行新固件,重新连接 MQTT 后上报新版本号。
  9. 记录:后端更新设备的固件版本记录,标记升级任务完成。
  10. 异常处理:若 MD5 校验失败,设备上报 desc="verify_failed",后端记录失败日志并通知运维人员。

离线设备处理:若设备在 OTA 通知下发时未在线(Redis 在线标记已过期),后端将 OTA 任务标记为 pending。设备下次上线后首次属性上报触发后端检查 pending 任务,重新生成 OTA 通知并下发。


6. 设备配网与绑定流程 (Device Provisioning)

用户通过微信小程序 BLE 配网,将新设备连接 WiFi 并注册到平台。

时序图

详细步骤

  1. 设备广播:设备上电后开启 BLE 广播,广播名称包含产品标识(如 YunStack-4CH-),等待配网。
  2. 发起配网:用户在小程序点击"添加设备",选择"BLE 配网"。
  3. 扫描设备:小程序调用 wx.startBluetoothDevicesDiscovery 扫描附近的 BLE 设备,按广播名称过滤出目标设备。
  4. 建立连接:用户选择设备后,小程序通过 BLE GATT 建立连接。
  5. 输入 WiFi:用户在小程序输入当前环境的 WiFi SSID 和密码。
  6. 写入配网信息:小程序通过 BLE 将 WiFi SSID 和密码写入设备的配网特征值(UUID: 0xFF01)。
  7. 连接结果:设备通过 BLE 回复连接结果。
  8. 预注册设备:WiFi 连接成功后,小程序调用后端 API 创建设备记录。后端生成 DeviceSecret 并返回。
  9. 写入凭证:小程序通过 BLE 将 DeviceSecret 写入设备。
  10. MQTT 认证:设备用凭证连接 EMQX,EMQX 直连 PostgreSQL 认证通过。
  11. 配置下发:后端通过 MQTT 下发逻辑 ID,设备保存到 NVS。
  12. 上线通知:设备首次属性上报后,后端通过 WebSocket 推送上线通知到小程序。
  13. 命名设备:小程序显示配网成功,引导用户为设备命名。
  14. 超时处理:若 30 秒内未收到设备上线通知,小程序提示配网失败,引导重试。