物联网平台提供设备影子功能,用于缓存设备状态。设备在线时,可以直接获取云端指令;设备离线后,再次上线可以主动拉取云端指令。
设备影子是一个 JSON 文档,用于存储设备上报状态、应用程序期望状态信息。
每个设备有且只有一个设备影子,设备可以通过MQTT获取和设置设备影子来同步状态,该同步可以是影子同步给设备,也可以是设备同步给影子。
云端获取设备影子需要使用云端开发的SDK,这里我们使用的是python SDK中的QueryDeviceDesiredProperty,其中set_Identifiers传入的是一个数组,由需要查看的属性的标识符组成。
#!/usr/bin/env python
#coding=utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkiot.request.v20180120.QueryDeviceDesiredPropertyRequest import QueryDeviceDesiredPropertyRequest
client = AcsClient('*************', '*************R', 'cn-shanghai')
request = QueryDeviceDesiredPropertyRequest()
request.set_accept_format('json')
# request.set_IotId("IotId")
request.set_DeviceName("*************")
request.set_ProductKey("*************")
request.set_Identifiers(["deviceswitch",])
response = client.do_action_with_exception(request)
# python2: print(response)
print(response)
Version:4代表了当前设备影子的版本经过了几次更新或者上报
新建设备的最新属性值和期望属性值都为null,期望属性值版本为0
在进行期望属性值设置之前,首先要通过期望属性值的查询,获取到当前设备影子的版本号,在设置属性值的参数中需要填写。
#!/usr/bin/env python
#coding=utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkiot.request.v20180120.SetDeviceDesiredPropertyRequest import SetDeviceDesiredPropertyRequest
client = AcsClient('*************', '*************', 'cn-shanghai')
request = SetDeviceDesiredPropertyRequest()
request.set_accept_format('json')
request.set_Versions({'deviceswitch':4}) # 填写当前的版本号
request.set_Items({"deviceswitch":0}) # 填写需要设置的属性的标识符和期望的值
# request.set_IotId("IotId")
request.set_DeviceName("testdevice2")
request.set_ProductKey("a1qfDPbUCyE")
response = client.do_action_with_exception(request)
# python2: print(response)
print(response)
在设备端使用Nodejs SDK中的onShadow来监听设备影子的变化,不论是设备端主动更新影子、设备端获取影子都会被调用
const iot = require('alibabacloud-iot-device-sdk');
// init device and connect linkplatform
const device = iot.device({
"ProductKey": "*************",
"DeviceName": "*************",
"DeviceSecret": "*************"
});
device.on('message', (topic, payload) => {
console.log('topic:',topic);
if(payload){
console.log('payload',payload.toString());
}
});
device.on('connect', () => {
console.log('>>>>>connect');
});
device.onShadow((res) => {
console.log('获取最新设备影子,%o', res);
});
连接物联网平台,并开启设备影子监听,当对设备期望属性值进行设置时,设备端就会监听到设备影子的变化,这是设备影子的版本号就会自动增加1.
设备端更新的属性信息,都放在desired中。
#!/usr/bin/env python
#coding=utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkiot.request.v20180120.UpdateDeviceShadowRequest import UpdateDeviceShadowRequest
client = AcsClient('*************', '*************', 'cn-shanghai')
request = UpdateDeviceShadowRequest()
request.set_accept_format('json')
request.set_DeviceName("*************")
request.set_ProductKey("*************")
# 设置影子消息可以直接使用JSON格式的数据,method一定要设置为update
request.set_ShadowMessage({
"method": "update",
"state": {
"desired": {
"deviceswitch": 0
}
},
"version": 2
})
response = client.do_action_with_exception(request)
# python2: print(response)
print(response)
设备端监控到设备影子的变化
用户可以通过“method”的数值为“control”得知这时云端更新了影子。同时通过”state”->”desired”得知修改的内容
const iot = require('alibabacloud-iot-device-sdk');
// init device and connect linkplatform
const device = iot.device({
"ProductKey": "********",
"DeviceName": "********",
"DeviceSecret": "****************"
});
/* device.on('message', (topic, payload) => {
console.log('topic:',topic);
if(payload){
console.log('payload',payload.toString());
}
});
*/
Json = {
"method": "update", //必须是update方法
"state": {
"reported": {
"deviceswitch": 1
}
},
"version": 0
};
json = JSON.stringify(Json);//将js对象转化为json格式
device.on('connect', () => {
console.log('>>>>>device connect succeed');
device.subscribe('/shadow/get/a1qfDPbUCyE/testdevice2')
device.publish('/shadow/update/a1qfDPbUCyE/testdevice2', new Buffer(json)); // 发布的消息类型必须为string或者Buffer
device.getShadow();
// device.deleteShadow()
});
//subscribe platform response
device.onShadow((res) => {
console.log('获取最新设备影子,%o', res);
})