物联网平台为每个设备预定义了两个Topic实现数据流转,定义的Topic都以固定格式呈现。
  • topic/shadow/update/${productKey}/${deviceName}

    设备和应用程序发布消息到此Topic,物联网平台收到该topic的消息后,将消息中的状态更新到设备影子中。

  • topic/shadow/get/${productKey}/${deviceName}

    设备影子更新状态到该Topic,设备订阅此Topic的消息。

此处以产品灯泡1号下某个具体灯泡设备为例,productkey:10000;deviceName:lightbulb,设备以QoS=1发布订阅定义的两个Topic,举例说明设备、设备影子以及应用程序之间的通信。

设备主动上报状态

处理流程图如图 1所示。

图 1. 设备主动上报


  1. 当灯泡lightbulb联网时,设备使用Topic/shadow/update/10000/lightbulb上报最新状态到影子。
    发送的JSON消息格式:
    
    {
    "method": "update",
    "state": {
    "reported": {
    "color": "red"
    }
    },
    "version": 1
    }

    参数说明如表 1所示。

    表 1. 上报参数说明
    参数 说明
    method 表示设备或者应用程序请求设备影子时的操作类型。

    当执行更新操作时,method为必填字段,设置为update。

    state 表示设备发送给设备影子的状态信息。

    reported为必填字段,状态信息会同步更新到设备影子的reported部分。

    version 表示设备影子检查请求中的版本信息。

    只有当新版本大于当前版本时,设备影子才会接受设备端的请求,更新设备影子版本到相应的版本。

  2. 当设备影子接受到灯泡上报状态时,成功更新影子文档。
    
    {
    "state" : {
    "reported" : {
    "color" : "red"
    }
    },
    "metadata" : {
    "reported" : {
    "color" : {
    "timestamp" : 1469564492
    }
    }
    },
    "timestamp" : 1469564492,
    "version" : 1
    }
  3. 更新设备影子之后,设备影子会返回结果给设备(灯泡),即发消息到/shadow/get/10000/lightbulb中,设备订阅该Topic。
    • 若更新成功,发送到Topic中的消息为:
      
      {
      "method":"reply",
      "payload": {
      "status":"success",
      "version": 1
      },
      "timestamp": 1469564576
      }
    • 若更新失败,发送到Topic中的消息为:
      
      {
      "method":"reply",
      "payload": {
      "status":"error",
      "content": {
      "errorcode": "${errorcode}",
      "errormessage": "${errormessage}"
      }
      },
      "timestamp": 1469564576
      }

    错误码说明如表 2所示。

    表 2. 错误码说明
    errorCode errorMessage
    400 不正确的json格式
    401 影子json缺少method信息
    402 影子json缺少state字段
    403 影子json version不是数字
    404 影子json缺少reported字段
    405 影子json reported属性字段为空
    406 影子json method是无效的方法
    407 影子内容为空
    408 影子reported属性个数超过128个
    409 影子版本冲突
    500 服务端处理异常

应用程序改变设备状态

处理流程图如图 2所示。

图 2. 应用程序改变设备状态


  1. 应用程序下发指令给设备影子,更改灯泡状态。
    应用程序发消息到Topic /shadow/update/10000/lightbulb/中,消息码流如下:
    
    {
    "method": "update",
    "state": {
    "desired": {
    "color": "green"
    }
    },
    "version": 2
    }
  2. 应用程序发出更新请求,设备影子更新其文档,影子文档更改为:
    
    {
    "state" : {
    "reported" : {
    "color" : "red"
    },
    "desired" : {
    "color" : "green"
    }
    },
    "metadata" : {
    "reported" : {
    "color" : {
    "timestamp" : 1469564492
    }
    },
    "desired" : {
    "color" : {
    "timestamp" : 1469564576
    }
    }
    },
    "timestamp" : 1469564576,
    "version" : 2
    }
  3. 设备影子更新完成后,发送消息到topic/shadow/get/10000/lightbulb中,返回结果给设备,返回结果由设备影子决定其构成。
    
    {
    "method":"control",
    "payload": {
    "status":"success",
    "state": {
    "reported": {
    "color": "red"
    },
    "desired": {
    "color": "green"
    }
    },
    "metadata": {
    "reported": {
    "color": {
    "timestamp": 1469564492
    }
    },
    "desired" : {
    "color" : {
    "timestamp" : 1469564576
    }
    }
    }
    },
    "version": 2,
    "timestamp": 1469564576
    }

  4. 灯泡在线,并且订阅了topic/shadow/get/10000/lightbulb,就会收到消息,并根据请求文档中desired的值更新状态,将灯泡颜色变成绿色。

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

  5. 更新完之后,发消息到topic/shadow/update/10000/lightbulb中上报最新状态,消息如下:
    
    {
    "method": "update",
    "state": {
    "desired":"null"
    },
    "version": 3
    }
  6. 上报状态成功后,设备影子会同步更新,此时的影子文档如下:
    
    {
    "state" : {
    "reported" : {
    "color" : "green"
    }
    },
    "metadata" : {
    "reported" : {
    "color" : {
    "timestamp" : 1469564577
    }
    },
    "desired" : {
    "timestamp" : 1469564576
    }
    },
    "version" : 3
    }

设备主动获取设备影子内容

处理流程图如图 3所示。

图 3. 获取设备影子内容


  1. 灯泡获取设备影子中保存的灯泡最新状态,发送固定消息到topic/shadow/update/10000/lightbulb中,具体的消息如下:
    
    {
    "method": "get"
    }
  2. 当设备影子收到这条消息时,发送消息到topic/shadow/get/10000/lightbulb中,灯泡订阅该topic,获得消息,消息内容如下:
    
    {
    "method":"reply",
    "payload": {
    "status":"success",
    "state": {
    "reported": {
    "color": "red"
    },
    "desired": {
    "color": "green"
    }
    },
    "metadata": {
    "reported": {
    "color": {
    "timestamp": 1469564492
    }
    },
    "desired": {
    "color": {
    "timestamp": 1469564492
    }
    }
    }
    },
    "version": 2,
    "timestamp": 1469564576
    }
  3. SDK使用API IOT_Shadow_Pull 完成获取设备影子的动作。
    IOT_Shadow_Pull(h_shadow);
    函数原型:
    
    /**
    * @brief Synchronize device shadow data from cloud.
    * It is a synchronous interface.
    * @param [in] handle: The handle of device shaodw.
    * @retval SUCCESS_RETURN : Success.
    * @retval other : See iotx_err_t.
    * @see None.
    */
    iotx_err_t IOT_Shadow_Pull(void *handle);

设备端删除影子属性

处理流程图如 图 4所示。
图 4. 删除影子属性


  1. 灯泡想要删除设备影子中保存的灯泡某条属性状态,发送删除影子属性的json内容到topic/shadow/update/10000/lightbulb中,具体的消息如下:
    • 删除影子某一属性的 json格式
      
      {
      "method": "delete",
      "state": {
      "reported": {
      "color": "null",
      "temperature":"null"
      }
      },
      "version": 1
      }
    • 删除影子全部属性的json格式
      
      {
      "method": "delete",
      "state": {
      "reported":"null"
      },
      "version": 1
      }

    删除属性只需要把method置为delete,并且属性的值设置为null即可。

  2. SDK使用IOT_Shadow_DeleteAttribute参数,取消设备影子的属性。
    
    IOT_Shadow_DeleteAttribute(h_shadow, &attr_temperature);
    IOT_Shadow_DeleteAttribute(h_shadow, &attr_light);
    IOT_Shadow_Destroy(h_shadow);
    函数原型:
    
    /**
    * @brief Delete the specific attribute.
    *
    * @param [in] handle: The handle of device shaodw.
    * @param [in] pattr: The parameter to be deleted from server.
    * @retval SUCCESS_RETURN : Success.
    * @retval other : See iotx_err_t.
    * @see None.
    */
    iotx_err_t IOT_Shadow_DeleteAttribute(void *handle, iotx_shadow_attr_pt pattr);