本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Device Shadow 服务文档
Device Shadow 服务遵守JSON规范的所有规则。值、对象和数组均存储在设备的影子文档中。
影子文档示例
Device Shadow 服务在UPDATE、中使用这些文档GET,并使用RESTAPI或 MQTTPub/Sub Messages 进行DELETE操作。
请求状态文档
请求状态文档具有以下格式:
{ "state": { "desired": { "
attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
}, "reported": { "attribute1
":integer1
, "attribute2
": "string1
", ... "attributeN
":boolean1
} }, "clientToken": "token
", "version":version
}
-
state
— 更新仅影响指定字段。通常,您将使用desired
或reported
属性,但不能在同一请求中同时使用这两个属性。-
desired
— 请求在设备中更新的状态属性和值。 -
reported
— 设备报告的状态属性和值。
-
-
clientToken
— 如果使用,您可以通过客户端令牌匹配请求和相应的响应。 -
version
- 如果使用,仅当指定的版本与 Device Shadow 服务拥有的最新版本相符时,该服务才会处理更新。
响应状态文档
响应状态文档具有以下格式,具体取决于响应类型。
/accepted 响应状态文档
{ "state": { "desired": { "
attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
} }, "metadata": { "desired": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} } }, "timestamp":timestamp
, "clientToken": "token
", "version":version
}
/delta 响应状态文档
{ "state": { "
attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
}, "metadata": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} }, "timestamp":timestamp
, "clientToken": "token
", "version":version
}
/documents 响应状态文档
{ "previous" : { "state": { "desired": { "
attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
}, "reported": { "attribute1
":integer1
, "attribute2
": "string1
", ... "attributeN
":boolean1
} }, "metadata": { "desired": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} }, "reported": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} } }, "version":version
-1 }, "current": { "state": { "desired": { "attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
}, "reported": { "attribute1
":integer2
, "attribute2
": "string2
", ... "attributeN
":boolean2
} }, "metadata": { "desired": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} }, "reported": { "attribute1
": { "timestamp":timestamp
}, "attribute2
": { "timestamp":timestamp
}, ... "attributeN
": { "timestamp":timestamp
} } }, "version":version
}, "timestamp":timestamp
, "clientToken": "token
" }
响应状态文档属性
-
previous
— 成功更新后,包含对象在更新之前的state
。 -
current
— 成功更新后,包含对象在更新之后的state
。 -
state
-
reported
— 只有在事物报告了reported
部分中的任何数据时才存在,并且仅包含请求状态文档中的字段。 -
desired
— 只有在设备报告了desired
部分中的任何数据时才存在,并且仅包含请求状态文档中的字段。 -
delta
— 只有在desired
数据与影子的当前reported
数据不同时才存在。
-
-
metadata
— 包含desired
和reported
部分中每个属性的时间戳,因此,您可以确定状态的更新时间。 -
timestamp
— 生成响应的 Epoch 日期和时间。 AWS IoT -
clientToken
— 仅当发布对/update
主题有效的客户端令牌时才会JSON出现。 -
version
– AWS IoT中共享的设备影子文档的当前版本。它将在文档先前版本号的基础上增加一个数。
错误响应文档
错误响应文档具有以下格式:
{ "code":
error-code
, "message": "error-message
", "timestamp":timestamp
, "clientToken": "token
" }
-
code
— 表示错误类型的HTTP响应代码。 -
message
— 用于提供额外信息的文本消息。 -
timestamp
— 生成响应的日期和时间 AWS IoT。此属性并非在所有错误响应文档中都存在。 -
clientToken
— 只有在发布的消息中使用了客户端令牌时才存在。
有关更多信息,请参阅 Device Shadow 错误消息。
影子名称列表响应文档
影子名称列表响应文档具有以下格式:
{ "results": [ "
shadowName-1
", "shadowName-2
", "shadowName-3
", "shadowName-n
" ], "nextToken": "nextToken
", "timestamp":timestamp
}
-
results
— 影子名称数组。 -
nextToken
— 在获取序列中的下一页的分页请求中使用的令牌值。在没有其它要返回的影子名称时,该属性不存在。 -
timestamp
— 生成响应的日期和时间 AWS IoT。
文档属性
设备的影子文档具有以下属性:
state
-
desired
-
设备的所需状态。应用程序可以写入到文档的该部分以直接更新设备的状态,而无需连接到设备。
reported
-
设备的报告状态。设备写入到文档的该部分以报告其新状态。应用程序读取文档的该部分以确定设备的上次报告状态。
metadata
-
有关存储在文档
state
部分的数据的信息,其中包括state
部分中每个属性的时间戳(以 Epoch 时间表示),让您能够确定它们的更新时间。注意
元数据不会影响服务限制或定价的文档大小。有关更多信息,请参阅 AWS IoT Service Limits。
timestamp
-
表示消息是由何时发送的 AWS IoT。通过使用消息中的时间戳以及
desired
或reported
部分中各个属性的时间戳,设备可以确定属性的存在时间,即使设备没有内部时钟。 clientToken
-
设备独有的字符串,用于将响应与MQTT环境中的请求关联起来。
version
-
文档版本。文档每次更新时,此版本号都会递增。用于确保正在更新的文档为最新版本。
有关更多信息,请参阅 影子文档示例。
增量状态
增量状态是一种虚拟类型的状态,包含 desired
状态和 reported
状态之间的差异。对于 desired
部分中的字段,如果 reported
部分没有这些字段,则它们将包含在增量中。对于 reported
部分中的字段,如果 desired
部分没有这些字段,则它们不会包含在增量中。增量包含元数据,且其值与 desired
字段的元数据相同。例如:
{ "state": { "desired": { "color": "RED", "state": "STOP" }, "reported": { "color": "GREEN", "engine": "ON" }, "delta": { "color": "RED", "state": "STOP" } }, "metadata": { "desired": { "color": { "timestamp": 12345 }, "state": { "timestamp": 12345 } }, "reported": { "color": { "timestamp": 12345 }, "engine": { "timestamp": 12345 } }, "delta": { "color": { "timestamp": 12345 }, "state": { "timestamp": 12345 } } }, "version": 17, "timestamp": 123456789 } }
当嵌套对象不同时,增量将包含根路径。
{ "state": { "desired": { "lights": { "color": { "r": 255, "g": 255, "b": 255 } } }, "reported": { "lights": { "color": { "r": 255, "g": 0, "b": 255 } } }, "delta": { "lights": { "color": { "g": 255 } } } }, "version": 18, "timestamp": 123456789 }
Device Shadow 服务通过循环访问 desired
状态中的每个字段并将其与 reported
状态进行比较来计算增量。
数组的处理方式与值类似。如果 desired
部分中的数组与 reported
部分中的数组不匹配,则整个预期数组将被复制到增量中。
对影子文档进行版本控制
Device Shadow 服务支持在每个更新消息(请求和响应)中进行版本控制。这意味着,每次更新影子时,JSON文档的版本都会增加。这可以确保两件事情:
-
如果客户端尝试使用旧版本号覆盖影子,它将收到错误消息。客户端将被告知必须先进行重新同步,然后才能更新设备的影子。
-
如果消息的版本比客户端存储的版本低,客户端则可决定不对该消息执行操作。
客户端可以在影子文档中不包含版本以绕过版本匹配。
影子文档中的客户端令牌
您可以使用带有MQTT基于消息传递的客户端令牌来验证请求和请求响应中是否包含相同的客户端令牌。这可以确保响应与请求相互关联。
注意
客户端令牌不能超过 64 字节。长度超过 64 字节的客户端令牌会导致 400(错误请求)响应和无效clientToken错误消息。
空影子文档属性
如果影子文档中的 reported
和 desired
属性不适用于当前影子状态,它们可能为空或省略。例如,只有在影子文档具有所需状态时,它才包含 desired
属性。以下是没有 desired
属性的状态文档的有效示例:
{ "reported" : { "temp": 55 } }
reported
属性也可能为空,例如,设备尚未更新影子时:
{ "desired" : { "color" : "RED" } }
如果更新导致 desired
或 reported
属性变为 null,则会将其从文档中删除。下面说明了如何将 desired
属性设置为 null
以删除该属性。例如,在设备更新其状态时,您可以执行该操作。
{ "state": { "reported": { "color": "red" }, "desired": null } }
影子文档也可能没有 desired
或 reported
属性,从而使影子文档为空。这是一个空影子(但有效)文档的示例。
{ }
影子文档中的数组值
影子支持数组,但将其视为正常值进行处理,因为对数组的更新将替换整个数组。无法更新数组的某个部分。
初始状态:
{ "desired" : { "colors" : ["RED", "GREEN", "BLUE" ] } }
更新:
{ "desired" : { "colors" : ["RED"] } }
最终状态:
{ "desired" : { "colors" : ["RED"] } }
数组不能包含空值。例如,以下数组无效并将被拒绝。
{ "desired" : { "colors" : [ null, "RED", "GREEN" ] } }