设备影子概览

物联网平台提供设备影子功能,用于缓存设备状态。设备在线时,可以直接获取物联网平台指令;设备离线后,再次上线可以主动拉取物联网平台指令。

什么是设备影子

设备影子是一个JSON文档,用于存储设备上报状态、应用程序期望状态信息。
每个设备有且只有一个设备影子,设备可以通过MQTT获取和设置设备影子来同步状态,该同步可以是影子同步给设备,也可以是设备同步给影子。

应用场景

  • 应用程序请求获取设备状态。场景描述:使用设备影子机制,设备状态变更,只需同步状态给设备影子一次,应用程序请求获取设备状态,不论应用程序请求数量,和设备是否联网在线,都可从设备影子中获取设备当前状态,实现应用程序与设备解耦。应用程序获取设备影子中状态的流程图如下。设备影子 - 图1
    • 设备网络不稳定,设备频繁上下线,无法正常响应应用程序的请求。
    • 设备网络稳定,同时响应多个应用程序的请求,即使响应的结果一样,设备本身处理能力有限,也会无法负载多次请求。
  • 应用程序下发指令给设备,变更设备状态。场景描述:设备处于下线状态,或设备网络不稳定,设备频繁上下线,应用程序发送控制指令给设备,设备不在线,指令就会发送失败。使用设备影子机制,可以将应用程序下发的指令,携带时间戳存储到设备影子中。设备再上线时,获取设备影子中指令,并根据时间戳确定是否执行。应用程序更新设备状态的流程图如下.设备影子 - 图2

设备影子数据流

设备影子数据通过Topic 进行流转,主要包括设备上报状态到设备影子、应用程序更改设备状态、设备离线再上线后主动获取设备影子信息,和设备端请求删除设备影子中的属性信息。本文介绍设备影子Topic 及其数据格式。

设备影子Topic

物联网平台已为每个设备预定义了两个Topic ,用于实现设备影子数据流转。

  • /keepsoft/{tenantKey}/shadow/update/{productKey}/{deviceKey} 设备和应用程序发布消息到此Topic 。物联网平台收到该Topic 的消息后,将消息中的状态更新到设备影子中。
  • /keepsoft/{tenantKey}/keepsoft/{tenantKey}/shadow/get/{productKey}/{deviceKey}设备影子更新状态到该Topic ,设备订阅此Topic 获取最新消息。

    使用示例

    本文以灯泡设备为例,说明设备、设备影子以及应用程序之间的通信,主要介绍设备主动上报状态、应用程序改变设备状态、设备主动获取影子内容,和设备主动删除影子属性。
    示例中,产品的ProductKey是a1PbRCF**;设备名称DeviceName**是lightbulb。设备以QoS=1发布消息和订阅两个设备影子Topic 。
    设备影子 - 图3

    设备主动上报状态

    设备在线时,主动上报设备状态到影子,应用程序主动获取设备影子状态。
    数据流转过程如下图所示。
  1. 当灯泡lightbulb上线时,使用Topic /keepsoft/{tenantKey}/shadow/update/a1PbRCF**/lightbulb**上报最新状态到影子。发送的JSON消息格式:

    1. {
    2. "method": "update",
    3. "state": {
    4. "reported": {
    5. "color": "red"
    6. }
    7. },
    8. "version": 1
    9. }

    | 参数 | 说明 | | —- | —- | | method | 表示设备或者应用程序请求设备影子时的操作类型。
    当执行更新操作时,method为必填字段,设置为update。 | | state | 表示设备发送给设备影子的状态信息。
    reported为必填字段,状态信息会同步更新到设备影子的reported部分。 | | version | 表示设备影子检查请求中的版本信息。
    只有当新版本大于当前版本时,设备影子才会接收设备端的请求,并更新设备影子版本。
    如果version设置为-1时,表示清空设备影子数据,设备影子会接收设备端的请求,并将设备影子版本更新为0。 |

  2. 设备影子接收到灯泡上报的状态数据后,更新影子文档。

    1. {
    2. "state": {
    3. "reported": {
    4. "color": "red"
    5. }
    6. },
    7. "metadata": {
    8. "reported": {
    9. "color": {
    10. "timestamp": 1469564492
    11. }
    12. }
    13. },
    14. "timestamp": 1469564492,
    15. "version": 1
    16. }
  3. 影子文件更新后,设备影子会返回结果给设备(灯泡),即发送消息到设备订阅的Topic /keepsoft/{tenantKey}/shadow/get/a1PbRCF**/lightbulb**中。

    • 若更新成功,发送到该Topic 中的消息为:

      1. {
      2. "method": "reply",
      3. "payload": {
      4. "status": "success",
      5. "version": 1
      6. },
      7. "timestamp": 1469564576
      8. }
    • 若更新失败,发送到该Topic 中的消息为:

      1. {
      2. "method": "reply",
      3. "payload": {
      4. "status": "error",
      5. "content": {
      6. "errorcode": "${errorcode}",
      7. "errormessage": "${errormessage}"
      8. }
      9. },
      10. "timestamp": 1469564576
      11. }

      | errorCode | errorMessage | | —- | —- | | 400 | 不正确的JSON格式。 | | 401 | 影子数据缺少method信息。 | | 402 | 影子数据缺少state字段。 | | 403 | 影子数据中version值不是数字。 | | 404 | 影子数据缺少reported字段。 | | 405 | 影子数据中 reported属性字段为空。 | | 406 | 影子数据中 method是无效的方法。 | | 407 | 影子内容为空。 | | 408 | 影子数据中reported属性个数超过128个。 | | 409 | 影子版本冲突。 | | 500 | 服务端处理异常。 |

设备影子 - 图4

应用程序改变设备状态

应用程序通过调用云端API下发期望状态给设备影子,设备影子再将文件下发给设备端。设备根据影子更新状态,并上报最新状态至影子。
数据流转流程如下图所示。

  1. 应用程序调用云端API UpdateDeviceShadow,下发消息更改灯泡状态,例如需将灯泡的color属性值改为green。调用API时,参数ShadowMessage的值为:

    1. {
    2. "method": "update",
    3. "state": {
    4. "desired": {
    5. "color": "green"
    6. }
    7. },
    8. "version": 2
    9. }
  2. 设备影子接收到更新请求,更新其影子文档为:

    1. {
    2. "state": {
    3. "reported": {
    4. "color": "red"
    5. },
    6. "desired": {
    7. "color": "green"
    8. }
    9. },
    10. "metadata": {
    11. "reported": {
    12. "color": {
    13. "timestamp": 1469564492
    14. }
    15. },
    16. "desired": {
    17. "color": {
    18. "timestamp": 1469564576
    19. }
    20. }
    21. },
    22. "timestamp": 1469564576,
    23. "version": 2
    24. }
  3. 设备影子更新完成后,发送返回结果到Topic /keepsoft/{tenantKey}/shadow/get/a1PbRCF**/lightbulb**中。返回结果信息构成由设备影子决定。

    1. {
    2. "method": "control",
    3. "payload": {
    4. "state": {
    5. "reported": {
    6. "color": "red"
    7. },
    8. "desired": {
    9. "color": "green"
    10. }
    11. },
    12. "metadata": {
    13. "reported": {
    14. "color": {
    15. "timestamp": 1469564492
    16. }
    17. },
    18. "desired": {
    19. "color": {
    20. "timestamp": 1469564576
    21. }
    22. }
    23. }
    24. },
    25. "version": 2,
    26. "timestamp": 1469564576
    27. }
  4. 如果设备灯泡在线,并且订阅了Topic /keepsoft/{tenantKey}/shadow/get/a1PbRCF**/lightbulb,则会立即收到消息。收到消息后,根据请求文档中desired**的值,将灯泡颜色变成绿色。灯泡更新完状态后,上报最新状态到物联网平台。

    1. {
    2. "method": "update",
    3. "state": {
    4. "reported": {
    5. "color": "green"
    6. }
    7. },
    8. "version": 3
    9. }

    说明 如果有时间戳判断指令过期,也可以选择不更新。

  5. 设备影子会返回响应结果给设备,发送消息到设备订阅的Topic /keepsoft/{tenantKey}/shadow/get/a1PbRCF**/lightbulb**中。详细说明,请参见设备主动上报状态。

  6. 最新状态上报成功后, 设备端和设备影子进行以下操作。

    • 设备端发消息到Topic /keepsoft/{tenantKey}/shadow/update/a1PbRCF**/lightbulb中清空desired**属性。消息如下:

      1. {
      2. "method": "update",
      3. "state": {
      4. "desired": "null"
      5. },
      6. "version": 4
      7. }
    • 设备影子会同步更新影子文档,此时的影子文档如下:

      1. {
      2. "state": {
      3. "reported": {
      4. "color": "green"
      5. }
      6. },
      7. "metadata": {
      8. "reported": {
      9. "color": {
      10. "timestamp": 1469564577
      11. }
      12. },
      13. "desired": {
      14. "timestamp": 1469564576
      15. }
      16. },
      17. "version": 4
      18. }

      设备影子 - 图5

      设备主动获取影子内容

      若应用程序发送指令时,设备离线。设备再次上线后,将主动获取设备影子内容。
      数据流转过程如下图所示。

  7. 灯泡主动发送以下消息到Topic /keepsoft/{tenantKey}/shadow/update/a1PbRCF**/lightbulb**中,请求获取设备影子中保存的最新状态。

    1. {
    2. "method": "get"
    3. }
  8. 当设备影子收到这条消息后,发送最新状态到Topic /keepsoft/{tenantKey}/shadow/get/a1PbRCF**/lightbulb**。灯泡通过订阅该Topic 获取最新状态。消息内容如下:

    1. {
    2. "method": "reply",
    3. "payload": {
    4. "status": "success",
    5. "state": {
    6. "reported": {
    7. "color": "red"
    8. },
    9. "desired": {
    10. "color": "green"
    11. }
    12. },
    13. "metadata": {
    14. "reported": {
    15. "color": {
    16. "timestamp": 1469564492
    17. }
    18. },
    19. "desired": {
    20. "color": {
    21. "timestamp": 1469564492
    22. }
    23. }
    24. }
    25. },
    26. "version": 2,
    27. "timestamp": 1469564576
    28. }

    设备影子 - 图6

    设备主动删除影子属性

    若设备端已经是最新状态,设备端可以主动发送指令,删除设备影子中保存的某条属性状态。
    数据流转过程如下图所示。
    设备发送以下内容到Topic /keepsoft/{tenantKey}/shadow/update/a1PbRCF**/lightbulb中。
    其中,
    method**为delete,属性的值为null。

  • 删除影子中某一属性。

    1. {
    2. "method": "delete",
    3. "state": {
    4. "reported": {
    5. "color": "null",
    6. "temperature": "null"
    7. }
    8. },
    9. "version": 1
    10. }
  • 删除影子全部属性。

    1. {
    2. "method": "delete",
    3. "state": {
    4. "reported": "null"
    5. },
    6. "version": 1
    7. }