设备影子充当中介,支持设备和用户应用程序查看和更新设备状态。设备、用户应用程序、设备影子三者之间通过两个特殊的 Topic 来实现通信:
$shadow/operation/${productId}/${deviceName}
:用于发布(上行)消息,可实现对设备影子数据的 get/update 操作。$shadow/operation/result/${productId}/${deviceName}
:用于订阅(下行)消息,影子服务端通过此 Topic 发送应答和推送消息。说明:以上主题均为设备创建时由系统默认创建,设备 SDK 内部会自动订阅上述主题。
如果设备想要获取设备影子最近的状态时,需要向 $shadow/operation/${productId}/${deviceName}
主题发布 get 消息。SDK 会提供 API 发送 get 消息,get 消息使用特定的 JSON 字符串格式:
{
"type": "get",
"clientToken": "clientToken"
}
说明:clientToken 是用于唯一标识会话业务的 TOKEN ,由请求端生成,应答端原样传回。
例如:空调设备,可以通过 SDK 提供的 API 向 $shadow/operation/ABC1234567/AirConditioner
发送 get 消息,获取最新的设备参数。
设备影子服务端通过向 $shadow/operation/result/${productId}/${deviceName}
主题发布消息进行响应,通过 JSON 数据返回设备影子所有数据内容,SDK 会通过相应的回调函数通知业务层。
影子服务端通过向 $shadow/operation/result/ABC1234567/AirConditioner
发送下列数据来响应空调设备的 get 请求。示例代码如下:
{
"type": "get",
"result": 0,
"timestamp": 1514967088,
"clientToken": "clientToken",
"payload": {
"state": {
"reported": {
"temperature": 27
},
"desired": {
"temperature": 25
},
"delta": {
"temperature": 25
}
},
"metadata": {
"reported": {
"temperature": {
"timestamp": 1514967066
}
},
"desired": {
"temperature": {
"timestamp": 1514967076
}
},
"delta": {
"temperature": {
"timestamp": 1514967076
}
}
},
"version": 1,
"timestamp": 1514967076
}
}
如果设备影子文档中有 desired 部分,则设备影子服务会自动生成相应的 delta 部分。如果没有 desired 部分,则没有 desired 和 delta 部分的内容。
说明:设备影子服务 不存储 delta 消息。
设备通过向 $shadow/operation/${productId}/${deviceName}
主题发送 update 消息,告知设备影子服务端其当前状态。SDK 提供相应的 API 发送 update 消息,业务层只需指定 reported 字段的内容。消息内容使用特定的 JSON 字符串格式。
空调设备向 $shadow/operation/ABC1234567/AirConditioner
发送 update 消息以报告设备当前的设备状态。示例代码如下:
{
"type": "update",
"state": {
"reported": {
"temperature": 27
}
},
"version": 1,
"clientToken": "clientToken"
}
当设备影子服务端收到此消息时,首先判断消息中的 version 是否与设备影子服务端中的 version 一致。如果一致,则设备影子服务端执行更新设备影子流程。
影子服务端向空调设备应答消息。示例代码如下:
{
"type": "update",
"result": 0,
"timestamp": 1514967066,
"clientToken": "clientToken",
"payload": {
"state": {
"reported": {
"temperature": 27
}
},
"metadata": {
"reported": {
"temperature": {
"timestamp": 1514967066
}
}
},
"version": 2,
"timestamp": 1514967066
}
}
如果消息中的 version 与设备影子服务端的 version 不一致,则设备影子服务向 $shadow/operation/result/ABC1234567/AirConditioner
发送以下消息进行回应。
{
"type": "update",
"result": 5005,
"timestamp": 1514967066,
"clientToken": "clientToken",
"payload": {
"state": {
"reported": {
"temperature": 27,
"mode": "cool"
}
},
"metadata": {
"reported": {
"temperature": {
"timestamp": 1514967066
},
"mode": {
"timestamp": 1514967050
}
}
},
"version": 2,
"timestamp": 1514967066
}
}
此时 payload 中的内容将返回完整的设备影子文档内容。
用户应用程序通过 HTTP RESTful API 修改设备影子 desired 字段。
用户应用程序通过 HTTP RESTful API 修改空调运行参数。示例代码如下:
{
"type": "update",
"state": {
"desired": {
"temperature": 25
}
},
"version": 2,
"clientToken": "clientToken"
}
当设备影子服务端收到此消息后,首先判断消息中的 version 是否与设备影子服务端中的 version 一致。如果一致,则执行更新设备影子流程,并通过 HTTP RESTful API 给应用程序应答 JSON 消息。
{
"type": "update",
"result": 0,
"timestamp": 1514967076,
"clientToken": "clientToken",
"payload": {
"state": {
"desired": {
"temperature": 25
}
},
"metadata": {
"desired": {
"temperature": {
"timestamp": 1514967076
}
}
},
"version": 3,
"timestamp": 1514967076
}
}
另外,影子服务端通过向 $shadow/operation/result/ABC1234567/AirConditioner
发送 delta 消息。
{
"type": "delta",
"timestamp": 1514967076,
"payload": {
"state": {
"temperature": 25
},
"metadata": {
"temperature": {
"timestamp": 1514967076
}
},
"version": 3,
"timestamp": 1514967076
}
}
SDK 通过相应的回调函数通知业务层消息已收到。
当设备收到 delta 消息后,业务层可以将 desired 字段内容置空并发送给设备影子服务端,表示设备已经 响应 本次 delta 消息,方式是通过向 $shadow/operation/${productId}/${deviceName}
主题发送消息。
例如:空调调整温度后,向 $shadow/operation/ABC1234567/AirConditioner
发送消息:
{
"type": "update",
"state": {
"desired": null
},
"version": 3,
"clientToken": "clientToken"
}
SDK 提供相应的 API 发送上述消息。当设备影子服务端收到该消息后,会将 desired 字段内容清除,防止由于 reported 与 desired 中属性值不同引起的重复下发。
影子服务端收到消息后,通过向: $shadow/operation/result/${productId}/${deviceName}
发送应答消息。
例如:影子服务端收到空调的 "desired":null
消息后,通过向 $shadow/operation/result/ABC1234567/AirConditioner
发送更新设备影子文档成功的消息。
{
"type": "update",
"result": 0,
"timestamp": 1514967086,
"clientToken": "clientToken",
"payload": {
"state": {
"reported": {
"temperature": 25
},
"desired": null
},
"metadata": {
"reported": {
"temperature": {
"timestamp": 1514967086
}
},
"desired": {
"temperature": {
"timestamp": 1514967086
}
}
},
"version": 4,
"timestamp": 1514967086
}
}
如果设备 reported 某些属性字段为 null,则代表要将设备影子中相应的字段删除。update 成功时,返回的 payload 内容中,字段仅包含对此次更新字段的相关内容。
如果设备 update 时携带上的 version 值小于服务端上保存的 version 值,则代表设备上的数据是旧的。此时服务端将发送失败消息,其中的返回码( result 字段)会明确告知 SDK 本次 update 失败,原因是 version 版本过低,同时在 payload 中携带最新的内容一同下发给设备端。
本页内容是否解决了您的问题?