通信协议
大约 5 分钟deviceshadowprotocol
通信概述
设备影子系统通过标准 MQTT 协议实现设备、平台、应用之间的双向通信。本节详细说明 Topic 体系、消息格式和四个核心交互流程。
一、MQTT Topic 体系
| Topic | 方向 | 说明 |
|---|---|---|
/blade/shadow/update/${productKey}/${deviceName} | 设备→平台 | 设备上报 reported |
/blade/shadow/update/${productKey}/${deviceName} | 应用→平台 | 应用设置 desired |
/blade/shadow/update/${productKey}/${deviceName}_reply | 平台→设备 | 更新结果回复 |
/blade/shadow/get/${productKey}/${deviceName} | 设备→平台 | 设备请求获取完整影子 |
/blade/shadow/get/${productKey}/${deviceName}_reply | 平台→设备 | 返回完整影子文档 |
/blade/shadow/delta/${productKey}/${deviceName} | 平台→设备 | 推送 Delta 差量 |
/blade/shadow/delta/${productKey}/${deviceName}_reply | 设备→平台 | 设备确认已处理 Delta |
/blade/shadow/delete/${productKey}/${deviceName} | 设备→平台 | 请求清除影子 |
/blade/shadow/delete/${productKey}/${deviceName}_reply | 平台→设备 | 清除结果回复 |
二、消息格式规范
1. 请求报文
所有请求采用统一的 JSON 格式(与 Alink 协议一致):
{
"id": "a1b2c3d4e5f6...",
"version": "1.0",
"sys": { "ack": 1 },
"method": "thing.shadow.update",
"params": { ... }
}| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | String | 是 | 消息 ID(UUID,32 位) |
| version | String | 是 | 协议版本号,固定 1.0 |
| sys | Object | 否 | 扩展功能,ack=0 不回复,ack=1 回复 |
| method | String | 是 | 请求方法标识 |
| params | Object | 是 | 请求参数 |
2. 响应报文
{
"id": "a1b2c3d4e5f6...",
"version": "1.0",
"code": 200,
"message": "success",
"method": "thing.shadow.update",
"data": { "version": 13 }
}| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码,200 = 成功 |
| message | String | 结果信息 |
| data | Object | 响应数据 |
3. 方法标识
| method | 说明 |
|---|---|
thing.shadow.update | 设备上报 reported |
thing.shadow.desired | 应用设置 desired |
thing.shadow.get | 设备获取完整影子 |
thing.shadow.delta | 平台推送 Delta |
thing.shadow.delta.reply | 设备确认 Delta |
thing.shadow.delete | 清除影子 |
三、设备上报属性更新影子
设备主动将当前状态上报到影子的 reported 字段。
请求示例:
{
"id": "a1b2c3d4...",
"version": "1.0",
"method": "thing.shadow.update",
"params": {
"reported": {
"temperature": 25.6,
"humidity": 68
},
"version": 5
}
}成功响应:
{
"id": "a1b2c3d4...",
"version": "1.0",
"code": 200,
"message": "success",
"data": { "version": 6 }
}版本冲突响应(code=6300):
{
"id": "a1b2c3d4...",
"version": "1.0",
"code": 6300,
"message": "shadow version conflict",
"data": { "version": 7 }
}四、应用设置期望值
应用端通过 REST API 或 MQTT 设置期望状态到影子的 desired 字段。
请求示例(MQTT):
{
"id": "b2c3d4e5...",
"version": "1.0",
"method": "thing.shadow.desired",
"params": {
"desired": {
"temperature": 26,
"switch": 0
},
"version": 5
}
}desired 中的 null 值
当 desired 中某个属性值为 null 时,表示删除该属性的期望值:
{ "desired": { "temperature": 26, "switch": null } }上述请求会设置 temperature=26,同时移除 switch 的期望值。
五、设备上线同步影子
设备上线后,平台自动检查是否有未处理的 Delta,如有则推送给设备。
Delta 推送报文:
{
"id": "d4e5f6a7...",
"version": "1.0",
"method": "thing.shadow.delta",
"params": {
"delta": {
"temperature": 26,
"switch": 0
},
"version": 6,
"timestamp": 1711584100000
}
}六、设备确认 Delta
设备处理完 Delta 后,上报确认和最新状态。
确认报文:
{
"id": "d4e5f6a7...",
"version": "1.0",
"method": "thing.shadow.delta.reply",
"params": {
"reported": {
"temperature": 26,
"switch": 0
},
"version": 6
}
}七、设备主动获取影子
设备上电或重连后,可主动请求获取完整影子文档,检查是否存在待处理的 delta。
请求报文:
{
"id": "c3d4e5f6...",
"version": "1.0",
"method": "thing.shadow.get"
}响应报文(通过 shadow/get_reply 返回):
{
"id": "c3d4e5f6...",
"version": "1.0",
"code": 200,
"data": {
"state": {
"reported": { "temperature": 25.6, "humidity": 68 },
"desired": { "temperature": 26 },
"delta": { "temperature": 26 }
},
"metadata": { "..." },
"version": 6,
"timestamp": 1711584100000
}
}八、应用查询设备影子
应用通过 REST API 查询影子文档,即使设备已离线也能获取其最后已知状态。
| 返回字段 | 含义 |
|---|---|
reported | 设备最后上报的真实状态(即使设备已离线) |
desired | 当前还未被设备执行的期望值 |
delta | 设备还需要执行的变更差异 |
version | 影子版本号,用于乐观锁并发控制 |
九、影子清除
清除整个影子
{
"id": "e5f6a7b8...",
"version": "1.0",
"method": "thing.shadow.delete",
"params": { "version": -1 }
}清除 desired 中的指定属性
{
"id": "e5f6a7b8...",
"version": "1.0",
"method": "thing.shadow.delete",
"params": {
"desired": {
"temperature": null,
"switch": null
},
"version": 6
}
}