阿里云物联网平台使用教程8-设备影子功能
1. 功能介绍
设备影子是一个 JSON 文档,用于存储设备上报的状态、应用程序期望状态信息。
-
每个设备有且只有一个设备影子,设备可以通过MQTT获取和设置设备影子来同步设备与物联网平台上存储的数据,该同步可以是云端的影子同步给设备,也可以是设备同步给云端的影子。
-
应用程序通过物联网平台的SDK获取和设置设备影子,获取设备最新状态或者下发期望状态给设备。
2.应用场景
-
场景1:网络不稳定,设备频繁上下线。
由于网络不稳定,设备频繁上下线。应用程序发出需要获取当前的设备状态请求时,设备掉线,无法获取设备状态,但下一秒设备又连接成功,应用程序无法正确发起请求。
使用设备影子机制存储设备最新状态,一旦设备状态产生变化,设备会将状态同步到设备影子。应用程序在请求设备当前状态时,只需要获取影子中的状态即可,不需要关心设备是否在线。
-
场景2:多程序同时请求获取设备状态。
如果设备网络稳定,很多应用程序请求获取设备状态,设备需要根据请求响应多次,即使响应的结果是一样的,设备本身处理能力有限,无法负载被请求多次的情况。
使用设备影子机制,设备只需要主动同步状态给设备影子一次,多个应用程序请求设备影子获取设备状态,即可获取设备最新状态,做到应用程序和设备的解耦。
-
场景3:设备掉线。
-
设备网络不稳定,导致设备频繁上下线,应用程序发送控制指令给设备时,设备掉线,指令无法下达到设备。
-
通过QoS=1或者2实现,但是该方法对于服务端的压力比较大,一般不建议使用。
-
使用设备影子机制,应用程序发送控制指令,指令携带时间戳保存在设备影子中。当设备掉线重连时,获取指令并根据时间戳确定是否执行。
-
-
设备真实掉线,指令发送失败。设备再上线时,设备影子功能通过指令加时间戳的模式,保证设备不会执行过期指令。
-
3.查看与更新设备影子
登录阿里云物联网管理平台:设备管理->设备->查看-设备影子
点击更新影子,在“desired”部分,填入期望设备状态。
设备影子文档格式为JSON,JSON内容的具体解释参照官网。
官网设备影子JSON详解传送门:
设备在线时,设备影子保存期望状态,设备通过订阅Topic直接获得期望状态。
设备离线时,设备影子缓存期望状态,设备上线后,主动从云端拉取最新期望状态。
4.设备端功能开发
4.1监听影子变更
//API device.onShadow(callback) //监听设备影子的变化,不论是设备端主动更新影子、设备端获取影子都会被调用 device.onShadow((res) => { console.log('获取最新设备影子,%o', res); })
用户需要分析返回的内容判断是更新成功、失败、还是云端主动向设备推送设备影子等情况,下面将会分情况进行说明
4.2设备端更新云端影子
//API device.postShadow(params) //上报设备影子 device.postShadow({ "a": "avalue" });
设备调用postShadown()之后,device.onShadow()将会被调用,若影子更新成功传递给onShadow()的res内容如下所示:
{ "method": "reply", "payload": { "status": "success", "version": 1 }, "timestamp": 1469564576 }
用户可以根据method的数值“reply”得知res的数值是云端对更新的响应,根据“status”为“success”得知影子更新成功;若影子更新失败,则传递给onShadow()的res内容如下所示:
{ "method": "reply", "payload": { "status": "error", "content": { "errorcode": "${errorcode}", "errormessage": "${errormessage}" } }, "timestamp": 1469564576 }
用户可以根据“status”的值“error”得知更新影子失败,errorcode的数值定义如下:
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 | 服务端处理异常 |
4.3查询云端影子数据
// API device.getShadow() //从物联网平台获取最新的影子数据 // 设备主动获取影子,回调函数会触发onShadow方法,返回设备影子信息 device.getShadow();
该函数调用之后将会触发物联网平台将影子发送给设备,在onShadow()中收到的数据格式示例如下:
{ "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 }
用户可以解析”payload”->”state”中的”reported”得知设备以前上报的影子,分析”desired”得知云端主动修改的影子的数值
4.4 云端修改影子数值
物联网平台上的应用程序可能修改影子的数值,在这种情况下云端会将影子数据发送给设备,onShadow()中的res数据格式示例如下:
{ "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 }
用户可以通过“method”的数值为“control”得知这时云端更新了影子。同时通过”state”->”desired”得知修改的内容
//API device.deleteShadow(keys) // 删除影子的单个属性 device.deleteShadow("a"); // 删除影子的多个属性 device.deleteShadow(["a","b"]); // 删除影子的所有属性 device.deleteShadow()