AWS Device shadow 是AWS 官方推荐管理控制IOT设备的方式。

Device:aws iot device sdk(nodejs)
client端:aws sdk(nodejs)

关于更多AWS IOT内容可参考:https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/iot-device-shadows.html
如需要了解device端 C语言操作影子可参考后续文章:

  • 1 Device shadow基本概念

    • 1.1 Device shadow控制模型
    • 1.2 AWS IOT设备影子工作原理
    • 1.3 Device shadow一些关键属性
    • 1.4 DeviceShadow提供了三种API 操作
    • 1.5 Deviceshadow底层实现
  • 2 Sample
    • 2.1 device端代码
    • 2.2MQTT client代码
    • 2.3 测试结果
      • 2.3.1device端打印
      • 2.3.2 client端打印

1 Device shadow基本概念

设备的影子是用于存储和检索设备的当前状态信息的 JSON 文档。(存储在AWS IOT cloud内)
Device Shadow 服务可以为您连接到 AWS IoT 的每台设备保留一个影子。您可以使用该影子通过 MQTT 或 HTTP 获取和设置设备的状态,无论该设备是否连接到 Internet。每台设备的影子都由相应事物的名称唯一标识。

这里借用AWS 架构师两幅图说明如何使用shadow

1.1 Device shadow控制模型

1.2 AWS IOT设备影子工作原理

1.3 Device shadow一些关键属性


Device shadow在 AWS IOT中是JSON格式存储 有这个固定的格式这里进行说明:

statedesired事物的预期状态。应用程序可以向本文档部分写入数据来更新事物的状态,且无需直接连接到该事物。reported事物的报告状态。事物可以向本文档部分写入数据,以报告其新状态。应用程序可以读取本文档部分,以确定事物的状态Delta增量状态是一种虚拟类型的状态,包含 desired 状态和 reported 状态之间的差异。
timestamp指明 AWS IoT 传输消息的时间。通过在消息中使用时间戳并对 desired 或 reported 部分中的不同属性使用时间戳,事物可以确定已更新项目的存在时间,即使它不具有内部时钟特性。
version文档版本。文档每次更新时,此版本号都会递增。用于确保正在更新的文档为最新版本。

所以图中内容即为当前状态engine为on,light color为GREEN,预期状态为engine为on,light color为RED。
关于状态具体内容可以自己定义相关属性。

1.4 DeviceShadow提供了三种API 操作

GetThingShadow 获取事物影子 返回内容即为1.3图中格式
UpdateThingShadow 更新指定事物影子 参数为包含state中json:{ state:{…} }
DeleteThingShadow 删除指定事物的影子

1.5 Deviceshadow底层实现

Device Shadow实质是一个系列约定的内部topic组成控制逻辑,并提供了持久化数据存储功能。
即为内部固定topic。
这里介绍几个会用到的topic类型:

$aws/things/myLightBulb/shadow/update/accepted
当设备的影子更新成功时,Device Shadow 服务将向此主题发送消息。
$aws/things/myLightBulb/shadow/update/delta
当检测到设备的影子的“reported”部分与“desired”部分之间存在差异时,Device Shadow 服务将向此主题发送消息。有关更多信息,请参阅 /update/delta。
$aws/things/myLightBulb/shadow/update/documents
每次设备的影子更新成功执行时,Device Shadow 服务都会向此主题发布状态文档。

Mqtt client通过更新影子(UpdateThingShadow )将灯由红色改变成绿色的底层流程:

Mqtt client调用UpdateThingShadow API后IOT 网络行为
1 Mqtt client即会向server发布一个$aws/things/myLightBulb/shadow/update消息。消息中携带期望更新的状态{“state”: {“desired”: {“color”: “green” }}}
2 IOT server收到这条消息,会发布$aws/things/myLightBulb/shadow/accepted 响应 update请求消息表示更新已收到。同时又会发布一条$aws/things/myLightBulb/shadow/delta通知设备进行更新。再发布一条 $aws/things/myLightBulb/shadow/update/documents 消息作为更新记录。
3 device 上线即订阅了delta消息,收到IOT server 发布的delta消息后,device执行相应更新操作,完成后设备发布一条$aws/things/myLightbulb/shadow/update {“state”: {“reported”: {“color”: “green” }}} 向IOT server通知状态更新好了
4 IOT server 收到update消息reported),会发布$aws/things/myLightBulb/shadow/accepted 响应 update请求消息表示更新已收到。再发布一条 $aws/things/myLightBulb/shadow/update/documents 消息作为更新记录。

我们编写device端代码时需要自己编写delta处理函数,处理完成后需要调用update 去reported更新结果。

2 Sample

Sample mqtt端和device均采用 node编写。
device端使用aws-iot-device-sdk 连接到AWS IOT cloud中
client端使用 AWS SDK 通过restful API 访问device shadow

Device Node SDK API: https://github.com/aws/aws-iot-device-sdk-js
AWS SDK API: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/IotData.html

2.1 device端代码

var awsIot = require('aws-iot-device-sdk');const thingShadows = awsIot.thingShadow({keyPath: `xxxxx-private.pem.key`,caPath: 'root-CA.crt',certPath: `xxxxxx-certificate.pem.crt`,// clientId: `arn:aws:iot:ap-northeast-1:xxxxxxx:thing/test_device_tokyo`,host: `xxxxxxxxxx.iot.ap-northeast-1.amazonaws.com`
});//得到shadow对象var clientTokenUpdate;
var thingName = "test_device_tokyo";//影子唯一标识 事物名
var expectedClientToken;//上线 自检  获取状态 同步状态
thingShadows.on('connect', function() {thingShadows.register(thingName, {}, function() {//shadow 链接成功后注册影子,注册后才可以使用影子相关操作expectedClientToken = thingShadows.get(thingName);//调用 get api检测当前shadow状态});
});var devicestatus = {//模拟设备状态 有三个属性power stream streamurlstream : 0,power: 1,streamurl:"unavailable",
}var updateLoaclStatus= function(cloudStatus){//更新本地状态(模拟控制操作)console.info("update local state:", cloudStatus);for(let key in cloudStatus){devicestatus[key] = cloudStatus[key];}
}var getStatusFromShadow = function(stateObject){//从GET API返回中解析消息let cloudStatus;if(stateObject.state.desired !== undefined){//如果shadow 中desired,即以desired为准,将状态更新为预期状态cloudStatus = stateObject.state.desired ;}else{                                       //没有desired则将状态同步到reported状态。(上次离线之前时的状态)cloudStatus = stateObject.state.reported;}updateLoaclStatus(cloudStatus);//更新本地状态(模拟控制操作)
}thingShadows.on('status', function(thingName, stat, clientToken, stateObject) {//get API 返回Iot server中shadow结果if (expectedClientToken === clientToken) {// console.log('got \'' + stat + '\' status on: ' + JSON.stringify(stateObject));getStatusFromShadow(stateObject);//通过get 得到iot server中shadow状态,并更新同步本地状态// console.info(devicestatus);     update();                        //reported 当前状态}
});var update = function(){//更新操作 用于reported 设备状态var CameraState = {state:{reported:devicestatus, desired:null}};//读取本地状态 用于reportedclientTokenUpdate = thingShadows.update(thingName, CameraState);//updateshadow APIif (clientTokenUpdate === null){console.log('update shadow failed, operation still in progress');}else{console.log('update success');}}thingShadows.on('delta', function(thingName, stateObject) {//接受来自mqtt client 状态更改请求(消息)console.info(thingName, stateObject);updateLoaclStatus(stateObject.state);console.info(devicestatus);update();});

2.2MQTT client代码

使用AWS SDK 通过restful API的方式update shadow或get shadow

var AWS = require('aws-sdk');
AWS.config.loadFromPath('./aws_config.json');
var awsDeviceShadow = new AWS.IotData({accessKeyId:"xxxxxx",secretAccessKey:"xxxxxx",endpoint: 'xxxxxx.iot.ap-northeast-1.amazonaws.com', region:'ap-northeast-1'});
//得到AWS SDK shadow API操作对象
var testThingName = "test_device_tokyo";//事物名是阴影的唯一标识
var Devices = function() {var self = {};return self;
};Devices.get = function(thingName, resmodel, callback){let params = {thingName: thingName/* required */};awsDeviceShadow.getThingShadow(params, function(err, data){// 通过sdk 使用restful API 得到iot shadowif (err){console.error(err, err.stack); // an error occurredreturn callback(err);}return callback(null, data.payload);//返回结果});
};
//only update shadow and No check device response
Devices.update= function(thingName, data, callback) {let payload = {state:{desired:data, reported:null}};let params = {payload: JSON.stringify(payload),thingName: thingName/* required */};console.log("\nupdate param:", payload)awsDeviceShadow.updateThingShadow(params, function(err, data) {//通过sdk 使用restful API 更新iot shadowif (err){console.error(err, err.stack);return callback(err);} return callback(null);});
};Devices.get(testThingName, 0, function(err, state){//调用get 测试if(err)console.error(err);elseconsole.log("\nget thingShadow:",state);
});let cmd = {stream:1, power:1}
Devices.update(testThingName,  cmd, function(err, data){//调用update 测试if(err) console.error(err)elseconsole.info("\nupdate success");
});

2.3 测试结果

2.3.1device端打印

get thing shadow: {"state":{"reported":{"stream":1,"power":1,"streamurl":"unavailable"}},"metadata":{"reported":{"stream":{"timestamp":1531897249},"power":{"timestamp":1531897249},"streamurl":{"timestamp":1531897249}}},"version":839,"timestamp":1531897330}
//程序运行 获取iot shadow状态并进行同步
update local state: { stream: 1, power: 1, streamurl: 'unavailable' }
//同步完成
update success
// 发送reported
delta message: test_device_tokyo { version: 841,timestamp: 1531897399,state: { stream: 1, power: 1 },metadata:{ stream: { timestamp: 1531897399 },power: { timestamp: 1531897399 } } }
//收到来自client端update发送delta消息
update local state: { stream: 1, power: 1 }
//以delta消息中的状态对device进行更新
update success
// 发送reported

2.3.2 client端打印

get thingShadow: {"state":{"reported":{"stream":1,"power":1,"streamurl":"unavailable"}},"metadata":{"reported":{"stream":{"timestamp":1531897331},"power":{"timestamp":1531897331},"streamurl":{"timestamp":1531897331}}},"version":840,"timestamp":1531897397}
//获取shadow状态
update param: { state: { desired: { stream: 1, power: 1 }, reported: null } }
//以该状态发起update
update success
//收到来自IOT server accepted 消息打印成功

AWS Device Shadow使用相关推荐

  1. AWS Device Farm介绍及Appium踩过的坑

    本文记录了在AWS Device Farm上进行Appium TestNG进行手机应用UI自动化测试的流程及遇到的问题,及具体的解决方法.同时记录了使得测试脚本更稳定的一些代码写法. Device F ...

  2. aws iot 连接时间_AWS IoT Core 定价

    定价一览 连接 连接用于在您的设备与 AWS IoT Core 之间提供经验证的安全连接.连接按 1 分钟的增量进行计量,基于您的设备连接到 AWS IoT Core 的总时间. 例如,在美国东部(弗 ...

  3. 云中树莓派(5):利用 AWS IoT Greengrass 进行 IoT 边缘计算

    云中树莓派(5):利用 AWS IoT Greengrass 进行 IoT 边缘计算 云中树莓派(1):环境准备 云中树莓派(2):将传感器数据上传到AWS IoT 并利用Kibana进行展示 云中树 ...

  4. esp8266 aws iot资料收集 可以上传

    1 相关网页 [未解决] 求助 用esp8266 sketch data upload tool 上传aws的cert和key报错 https://www.arduino.cn/thread-8237 ...

  5. 介绍 json_介绍

    介绍 json Are you in control of your IoT devices? Have you invested in their security or will they tur ...

  6. 亚马逊首席技术官:开发者可以像詹姆斯·邦德一样征服整个世界

    作者|Werner Vogels 编辑|江柳 昨天(7 月 26 日),AWS 技术峰会 2017 在北京国家会议中心召开,亚马逊首席技术官沃纳•威格尔博士 (Werner Vogels) 发表了相关 ...

  7. MQTT与TCP 长连接

    前言 在接触到MQTT之后,总是会有疑问,为什么用MQTT不用TCP长连接透传?看起来[TCP长连接+私有协议透传]和[MQTT+业务主题]似乎都能达到同样的目的,甚至用MQTT会使得设备端逻辑实现. ...

  8. 2020测试工具索引

    初次发布文章时,共收集435个工具! 这些测试工具均为博主人肉爬虫出来的,数据来源于: 百度.Google 各大博客.门户网站.论坛 个人测试经验 在整理过程中,我会尽量去官网找到官方对该工具的描述, ...

  9. 云测试平台推荐与简单比较

    相信做APP产品的小伙伴经常会遇到机型兼容问题.特别是Android,各大厂商都在做自己的系统MIUI.EMUI.H2OS等等,更是增加了机型兼容的难度. 小型团队和公司一般没有太多经费购买各种机型, ...

  10. 测试学习--云测试平台

    转载自infoQ 国外主流的云测试平台: Xamarin Test Cloud (https://xamarin.com/test-cloud/) TestDroid (http://testdroi ...

最新文章

  1. VBA最常用的基础代码、基础功能写法总结
  2. JS解析XML文件和XML字符串
  3. android4.3 截屏功能的尝试与失败分析
  4. QT绘制饼图和自定义饼图切片
  5. C#中的继承与多态还有接口
  6. mysql技术内幕sampdb_MySQL技术内幕汇总
  7. SQLi LABS Less-5 报错注入+布尔盲注
  8. turtlebot3 模型没有显示_Turtlebot3新手教程:Open-Manipulator机械臂
  9. 450A - Jzzhu and Children 找规律也可以模拟
  10. 如何用python读取表_Python读取MySQL表数据的方法介绍
  11. python爬虫需要学哪些知识_Python爬虫需要学习那些东西?
  12. 51单片机外设LCD12864显示字符串
  13. linux ntp时间立即同步命令_Linux时间同步,ntpdate命令、ntpd服务详解
  14. 深度揭秘:微软内部爱恨纠葛
  15. c++开源爬虫-Larbin简介
  16. 文献 | 如何快速将英文文献翻译为中文?
  17. 三.ffmpeg 集成av1
  18. python 画隐函数图像 画三维显函数图像
  19. 判别两棵树是否相等 设计算法_BAIR最新RL算法超越谷歌Dreamer,性能提升2.8倍
  20. 冠铭机器人_创新时代 智造引领|众为兴总冠名支持 2019富友会年会圆满落幕

热门文章

  1. Excel图表美化—表格美化
  2. Django文档地址
  3. python金融衍生品有哪些_什么是金融衍生品,金融衍生品有哪些?
  4. 戴尔windows10桌面计算机,戴尔电脑win10怎么在桌面显示我得电脑
  5. 2017,站在巨人肩膀我们一路前行
  6. serverTimezone
  7. 30行代码实现微信自动回复机器人
  8. 自动化测试方案设计和实现
  9. 200个英语常用词根词缀
  10. CSS之颜色和背景的属性设置