设备接入说明
本文档面向需要将自有硬件设备接入 YunStack-IoT 的开发者,以硬件模拟器为参考实现,说明物模型规范、MQTT 通信格式和最佳实践。
1. 物模型
物模型是设备的数字化描述,用 JSON 定义设备有哪些属性、事件、服务。平台通过物模型理解设备能力,实现异构设备统一管理。
1.1 基本结构
json
{
"version": "1.0",
"deviceType": "relay_controller",
"meta": {
"name": "四路智能继电器",
"description": "ESP32-C3 四路继电器控制模块"
},
"properties": [...]
}| 字段 | 必填 | 说明 |
|---|---|---|
version | 是 | 物模型版本号 |
deviceType | 是 | 设备类型标识 |
meta.name | 是 | 设备名称(产品级) |
properties | 是 | 属性列表 |
1.2 属性定义
json
{
"id": "relay_1",
"name": "继电器1",
"type": "bool",
"access": "rw",
"ui": { "component": "switch" }
}| 字段 | 必填 | 说明 |
|---|---|---|
id | 是 | 属性唯一标识,snake_case |
name | 是 | 显示名称 |
type | 是 | 数据类型:bool / int / float / string / enum |
access | 是 | 读写权限:r 只读,rw 读写 |
unit | 否 | 单位,如 °C、%、hPa |
min / max | 否 | 数值范围(仅 int/float) |
default | 否 | 默认值 |
ui.component | 否 | Web 端渲染组件:switch(开关)、chart(图表) |
1.3 推荐标准属性
为保持设备一致性,建议每个设备物模型包含:
| 属性 ID | 类型 | 说明 |
|---|---|---|
firmware_version | string (r) | 固件版本号,示例 "v2.0" |
2. MQTT 通信
2.1 连接参数
| 参数 | 说明 | 示例 |
|---|---|---|
| Broker URL | MQTT 服务器地址 | mqtt://duruofu.cn:1883 |
| ClientId | 设备物理 ID(MAC 去除冒号,全大写) | AABBCCDDEE01 |
| Username | 产品标识 ProductKey | p_relay_4ch |
| Password | 设备密钥 DeviceSecret | test-relay-secret |
| Keep Alive | 心跳间隔(秒) | 60 |
物理 ID 格式:MAC 地址去除冒号,全大写,如
AA:BB:CC:DD:EE:01→AABBCCDDEE01。
2.2 Topic 规范
所有 Topic 遵循 sys/{pid}/{did}/thing/... 格式:
| 方向 | Topic | QoS | 说明 |
|---|---|---|---|
| 设备→平台 | sys/{pid}/{did}/thing/event/property/post | 1 | 属性上报 |
| 平台→设备 | sys/{pid}/{did}/thing/service/property/set | 1 | 控制指令(需订阅) |
| 设备→平台 | sys/{pid}/{did}/thing/service/property/set_reply | 1 | 控制回复 |
| 平台→设备 | sys/{pid}/{did}/thing/config/set | 1 | 配置下发(需订阅) |
| 设备→平台 | sys/{pid}/{did}/thing/config/set_reply | 1 | 配置回复 |
| 平台→设备 | sys/{pid}/{did}/thing/ota/notify | 1 | OTA 通知(需订阅) |
| 设备→平台 | sys/{pid}/{did}/thing/ota/progress | 1 | OTA 进度上报 |
{pid}= ProductKey,{did}= 设备物理 ID
2.3 订阅
设备连接后需订阅以下 Topic 以接收平台指令:
sys/{pid}/{did}/thing/service/property/set
sys/{pid}/{did}/thing/config/set
sys/{pid}/{did}/thing/ota/notify3. 通信流程
3.1 属性上报
设备定期或变化时上报属性值。
Payload 格式:
json
{
"msgId": "a1b2c3d4",
"params": {
"relay_1": true,
"chip_temp": 45.2,
"firmware_version": "v2.0"
}
}最佳实践:
- 首次连接后立即全量上报一次(所有属性)
- 后续周期仅上报变化的属性(delta),不动的不传
- 收到控制指令后立即全量上报一次
- 上报间隔建议 ≥ 5 秒
3.2 接收控制指令
平台通过 MQTT 下发控制指令,设备需订阅相应 Topic。
收到指令 Payload:
json
{
"msgId": "3d3aff36-784",
"params": {
"relay_1": true
}
}设备响应:
- 执行指令(如切换继电器)
- 回复
set_reply:
json
{
"msgId": "3d3aff36-784",
"code": 200,
"msg": "success"
}- 立即上报完整属性状态
3.3 OTA 固件升级
收到 OTA 通知:
json
{
"taskId": "uuid",
"version": "2.0",
"url": "https://.../firmware.bin",
"size": 1048576,
"md5": "abc123..."
}设备行为:
- 下载固件,上报下载进度
- 校验 MD5
- 写入固件,上报安装进度
- 完成后上报
status: "success"
OTA 进度上报 Payload:
json
{
"taskId": "uuid",
"progress": 75,
"status": "downloading"
}状态流转:downloading → installing → success / failed
3.4 完整接入流程
1. 设备上电 → WiFi 连接
2. MQTT CONNECT(ClientId=物理ID, Username=ProductKey, Password=DeviceSecret)
3. 订阅 3 个 Topic(指令/配置/OTA)
4. 全量上报属性(首次同步)
5. 进入循环:定时 delta 上报 → 接收指令 → 回复 + 全量上报4. 硬件模拟器参考
硬件模拟器(yunstack-mock-hardware)是完全符合上述规范的参考实现:
| 文件 | 说明 |
|---|---|
lib/mqtt-client.js | MQTT 连接/订阅/上报/OTA 模拟 |
lib/data-generator.js | 物模型驱动的数据生成,delta 上报 |
thing-models/ | 内置物模型示例 |
bash
# Web 可视化模式
node server.js
# CLI 模式
node cli.js --type relay --broker mqtt://duruofu.cn:18835. 注意事项
- ClientId 唯一性:同一 ProductKey 下物理 ID 必须唯一,EMQX 会踢掉重复 ClientId
- QoS 使用:属性上报建议 QoS 1(至少一次),指令使用 QoS 1
- 增量上报:减少消息负载,不动的不传。首次连接和指令后全量
- 超时处理:指令下发有 30 秒超时,设备需及时回复
- 重连策略:断线后 5 秒重连,重连后需重新订阅 Topic 并全量上报
- 安全:生产环境务必修改默认密钥,启用 TLS 加密
