产品战略专家梁宁确认出席AICon北京站,分享AI时代下的商业逻辑与产品需求 了解详情
写点什么

AWS IoT 物联网系列,第四篇:如何使用 AWS IoT 做 OTA 升级

  • 2019-10-23
  • 本文字数:5313 字

    阅读完需:约 17 分钟

AWS IoT 物联网系列,第四篇:如何使用 AWS IoT 做 OTA 升级

AWS IoT 物联网系列博客

当前物联网环境中,设备类型多种多样,连接方式不一而足。为了帮助读者更好的理解并运用 AWS IoT 相关服务,我们提供了一个完整的 IoT 起步指南,包含设备的注册及上线、设备管理、用户身份及权限管理以及成本控制,通过这一系列的起步指南,也可以快速了解到 AWS IoT 服务如何与 Amazon Alexa 语音助手进行集成。AWS IoT 物联网系列共 4 篇,本篇是该系列的第一篇,其他篇链接请在本文结尾处查看。



背景介绍

在实际的物联网设备生产中,一般会量产部署上百万设备。这些设备到达客户手上,或者部署到生产系统后,如何安全管理设备,例如远程升级设备这些常见操作,会成为一个难题。物联网设备往往没有屏幕,也没有工作人员在设备前进行手动管理。升级操作如何触发?升级失败后如何回滚,并上报升级状态?这种场景需要提前设计一套系统,自动化进行设备管理。


借助 AWS IoT 设备管理功能,可以很方便的为设备接入到物联网,远程监控和远程管理物联网设备。AWS IoT 设备管理中的任务管理允许用户对设备进行分组和跟踪,同时允许快速查找设备,排查设备功能故障,远程更新设备固件,以及远程重新启动、修复以及将设备恢复到出厂设置,并降低管理大型物联网设备部署的成本和工作量。本博客将介绍如何使用 AWS IoT 设备管理功能帮助您完成设备生命周期管理,简化开发和运维部署,进行远程任务下发。


AWS IoT 任务执行时序图

使用 AWS IoT 创建 OTA 任务时,根据终端设备设置的处理流程,AWS 会把任务分别发布到以下两个预留的 MQTT 主题:


  • $ aws / things / {thingName} / jobs / notify

  • $ aws / things / {thingName} / jobs / notify-next


这两个主题对应两种不同的设备处理流程:第一种是由设备判断任务优先度,选择一个需要执行的任务。第二种是完成一个任务之后,自动按顺序获取下一个任务。针对不同的设备处理流程,设备需要主动订阅这两个 MQTT 主题之一。下述会对两种方法的流程逐步进行介绍。

方法一:获取需要执行的任务:


  1. 设备连接到 AWS IoT 平台后,订阅 aws/things/ThingName/jobs/get 请求之前订阅 $aws/things/ThingName/jobs/notify 主题,否则在后续的第三步无法收到任务列表。)

  2. 当终端设备订阅 aws/things/ThingName/jobs/get 获取待执行的 job 列表。(可以根据需要自定义轮询时间,例如 10 分钟取一次,具体可以根据场景来设定。)

  3. 此时设备会收到 $aws/things/ThingName/jobs/notify 消息,内容包含有任务列表。如果列表中包含了一个或多个任务,设备可自行选择需优先执行的任务。

  4. 获取到任务列表后,我们可以根据 job 的优先级自行选择优先需要运行的 job,然后把消息发送到 aws/things/thingName/jobs/jobId/get/accepted,终端设备能够获取到指定任务文档和任务状态。

  5. 在任务执行过程中,设备向 $aws/things/thingName/jobs/jobId/update 持续发布消息以更新任务状态,使得 AWS IoT 平台获悉设备当前任务的执行状况。同时控制端设备,例如手机端,也可以获取设备当前的更新状态。(在执行 job 的时候,可以定期地把 job 运行的状况发布到 update 主题,以便 IoT 服务的提供者知悉 job 的运行状况。向 update 主题发布消息对终端设备的 Job 运行没有任何影响,它只是状态的上报。但如果需要及时知道设备任务状态,应该及时通过此主题进行更新。)最后,任务执行过程可以反复调用第[5]步,上报任务状态,直到任务完成后,更新状态为“SUCCEEDED”。

  6. 设备完成了一个任务之后,可以重复执行[2],获取待执行任务列表,并从任务列表中执行下一个任务。

方法二:自动获取下一个任务:


方法二的实现原理和方法一极其相似,但有微小的区别:


  1. 当设备在线时,订阅 $aws/things/ThingName/jobs/notify-next 主题以获取设备任务信息。

  2. 发布消息到 next。(注意:这里的 aws/things/thingName/jobs/aws/things/thingName/jobs/jobId/get/accepted 获得任务的返回值。)

  3. Job 被创建后通过 notify-next 主题下发 Job 文档。

  4. 在执行过程中设备通过发布消息到 $aws/things/thingName/jobs/jobId/update 持续更新任务状态。

  5. 任务执行过程可以反复调用第[4]步,上报任务状态,直到任务完成后,更新状态为 “SUCCEEDED”。

  6. 设备完成了一个任务后,通过重复执行[2],自动获取下一个任务并相应执行。


相比于方法一,方法二能够自动执行下一个 Job,操作更加简单。但方法二无法在终端设备自定义 Job 的执行顺序,它只能按照 Job 提交的顺序往下执行。因此如果 Job 需要按照优先级(而不是提交顺序)执行,方法一会更加灵活。方法一能够允许终端设备根据自身设定的代码逻辑,例如任务文档中设置的优先级字段,让设备执行优先度高的任务。

AWS IoT 任务执行时序图

在说完整体流程之后,我们通过实际操作,从创建升级任务到执行任务,一步步的完成整个流程。

1. 使用 AWS IoT 找出需要控制的设备

首先需要在 AWS IoT 从海量设备中找出需要执行 Job 的设备。AWS IoT 提供了设备状态索引服务,此服务可以帮助我们在 IoT 平台索引和搜索注册表和设备影子数据。打开 AWS IoT 控制台,点击左边设置,选择队列索引设置,打开索引:



同样地,也可以使用 AWSCLI 所示开启设备索引。命令如下


Json


aws iot update-indexing-configuration --thing-indexing-configuration thingIndexingMode=REGISTRY_AND_SHADOW
复制代码


开启索引之后,我们就可以使用索引查询我们的目标设备,假设设备当前已经注册到 AWS IoT 平台,并且通过 MQTT 把设备状态更新到设备影子上。下述展示如何在 AWS 控制台查询系统版本号为“bc78fd46f845”的设备。后续我们将向这些设备推送升级任务,升级到新的固件系统:



同样的,我们也可以使用 AWS Cli 去查询设备影子,以获得系统版本号为 bc78fd46f845 的设备:


Json


aws iot search-index  --query-string "shadow.reported.ver:( bc78fd46f845)"
复制代码


查询完毕之后我们把这些设备加入一个设备组里面,这里我们把这些设备都加入名为 “jobdemo” 组里面,稍后我们将向这个组里面的设备发送升级任务。


2. 在控制台创建任务

创建任务前我们需要定义一个任务文档,这个任务文档将使用 json 形式描述了设备需要执行的远程操作,任务文档可能还包括了需要下载的固件升级包地址,以下是一个示例任务文档,我把这个任务文档保存到 S3 存储桶上。


Json


[  {     "operation":"install",     "packageName":"uniquePackageName",     "autoStart":"true",    "workingDirectory":"./root/directory/for/files/and/launch/command/execution",     "launchCommand":"command to pass to child_process exec in order to launch executable package",     "files":[        {           "fileName":"destinationFileName",           "fileSource":{              "url":"https://s3-example-bucket-name.s3.amazonaws.com/exampleFileName"           }        }     ]  }]
复制代码


把任务文档上传到 S3 之后,就可以使用 AWS IoT 控制台点开左侧管理,选择任务,到下一屏之后选择创建新任务,在此我选择的是“创建自定义作业”:



您会看到需要输入任务 ID、描述等,这些自定义即可:



然后在“选择要更新的设备”在之前步骤创建的 jobdemo:



“添加任务文件”选择您存放上述 job 文件的 S3 存储桶位置:



创建完任务作业后,就可以向指定的设备下发任务指令。我们使用上述创建的任务文档,向 jobdemo 推送这个任务,其他配置默认即可。



同样地,也可以使用 AWSCLI 完成整个 Job 创建流程:


Json


aws iot create-job --job-id 020 --targets arn:aws:iot:us-west-2:123456789012:thinggroup/jobdemo --document-source https://s3-us-west-2.amazonaws.com/{iotjobsbuckets}/jobtest.json
复制代码

3. 设备订阅任务并执行

如概述所述,设备为了接收新的任务,需要主动订阅这两个 MQTT 主题,两个主题分别对应不同的执行方法。以下展示两个主题订阅和执行任务信息的差异。


在方法一中,订阅 $ aws / things / {thingName} / jobs / notify 将得到待执行的任务列表。注意:返回的任务列表中没有具体 Job 的任务文档。


Json


{  "timestamp": unixtime,  "jobs": {    "IN_PROGRESS": [      {        "jobId": "jobdemo",        "queuedAt": unixtime,        "lastUpdatedAt": unixtime,        "startedAt": unixtime,        "executionNumber": 1,        "versionNumber": 3      }    ],    "QUEUED": [      {        "jobId": "jobdemo",        "queuedAt": unixtime,        "lastUpdatedAt": unixtime,        "startedAt": unixtime,        "executionNumber": 1,        "versionNumber": 1      }    ]  }}
复制代码


在方法二中,设备只有在空闲时才会收到 $ aws / things / {thingName} / jobs / notify-next 通知。(也就是说,如果设备正在处理 Job,那么设备是不会同时收到其他 Job 的通知,直到设备完成当前 Job 任务)这个消息的内容中包含了任务文档:


Json


{  "timestamp": unixtime,  "execution": {    "jobId": "jobdemo",    "status": "QUEUED",    "queuedAt": unixtime,    "lastUpdatedAt": unixtime,    "versionNumber": 1,    "executionNumber": 1,    "jobDocument": {      "operation": "install",      "packageName": "uniquePackageName",      "autoStart": "true",  ……    }  }}
复制代码


注意:再次强调,在方法二中,任务总是以队列的形式存在设备执行队列里面,如果设备存在之前的任务还没有处理完, 则不会发出 notify-next。


设备可以在接受任务之后,可以向 AWS IoT 特定 MQTT 主题:$ aws / things / thingName / jobs / jobId /update,报告设备当前任务状态:


Json


{  "status": ["IN_PROGRESS", "FAILED", "SUCCEEDED", "REJECTED"],  "statusDetails": {    "progress": "0%"  },  "expectedVersion":"",  "clientToken":""}
复制代码


设备更新状态需要指定四种状态(”IN_PROGRESS”、”FAILED”、”SUCCEEDED”、”REJECTED”)的一种。如上所述,在方法二中,如果任务下发通知时存在 “IN_PROGRESS” 状态的目标设备,则不会发出 notify-next。直到任务变成 “SUCCEEDED” 状态,目标设备才会接收到 notify-next 主题的消息。这样设备在执行完一个任务之后就可以有序地执行下一个任务。


读者可以自由地描述 statusDetails 内容,这里以处理进度为例进行描述。当设备通知 AWS IoT 完成任务“jobdemo”后,AWS IoT 会通过 $ aws / things / {thingName} / jobs / notify-next 主题发布下一个任务通知。


至此,就完成一个任务的执行。

结束语

在实际生产中,我们会从方法一和方法二中选择一种设备处理任务方法,把其编码在硬件设备上。管理员通过 AWS IoT 平台就能够下发任务并自动化进行处理。


需要注意的是,当前仅有 AWS 的 JavaScript Device SDK 包含了对 job 处理的封装。python 等其他语言 SDK 包还没有实现,需要客户按照本文内容的逻辑实现对 job topic 的订阅。


作者介绍:


谢佰臻


亚马逊 AWS 解决方案架构师,负责基于 AWS 的云计算方案的架构设计,熟悉AWS IoT , Serverless 架构,同时致力于提供 AWS IoT 架构设计及优化。


### AWS IoT 物联网系列其他博客目录如下:
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-1/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-2/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-3/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-4/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-5/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-6/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-7/)
[](https://amazonaws-china.com/cn/blogs/china/aws-iot-series-8/)
复制代码


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/aws-iot-series-4/


2019-10-23 08:001292

评论

发布
暂无评论
发现更多内容

老电影和图片变清晰的秘密!分辨率提升400%的AI算法

百度大脑

人工智能

谈谈对微软Dapr的理解

行云创新

微软 服务网格 dapr

南瓜电影 7 天内全面 Serverless 化实践

Serverless Devs

阿里云 ECS 南瓜电影 SAE

腾讯音乐iOS开发四次面试记录

iOSer

ios 腾讯 面试题 iOS面试 腾讯音乐

Aeron 是如何实现的?—— Ipc Subscription

BUG侦探

共享内存 Aeron Ipc Subscription

中科柏诚持续推进数字网络技术,蓄力元宇宙布局

联营汇聚

Rust 元宇宙 14 —— 创建角色和同步

Miracle

rust 元宇宙

网易云信发布两大元宇宙解决方案,打响进军元宇宙第一枪

网易云信

人工智能 音视频 元宇宙

【等保小知识】信息安全等级保护四级系统有哪些?

行云管家

网络安全 等级保护

元宇宙浪潮之下,数字身份至关重要

CECBC

尚硅谷Maxwell视频教程发布!

@零度

大数据 Maxwell

npm进阶(一) 更换成淘宝镜像源以及 cnpm

No Silver Bullet

npm 12月日更

netty系列之:性能为王!创建多路复用http2服务器

程序那些事

Netty 程序那些事 http2 12月日更

主机入侵检测策略之基线检测

网络安全学海

网络安全 信息安全 渗透测试 安全漏洞 暴力猜解

跨越可观测性鸿沟|高手们都在用的“火焰图”是什么

尔达Erda

程序员 微服务 云原生 可观测性 链路追踪

List 去重的 6 种方法

编程江湖

List java 编程

SpringBoot中如何优雅的使用多线程

编程江湖

JAVA开发 springboot

飞桨双十二礼包,上海“拆箱”啦!

百度大脑

人工智能

【IT运维】公司内网服务器可以远程桌面连接吗?怎么连接?

行云管家

云计算 运维 IT运维 远程运维

大厂高频面试题Spring Bean生命周期最详解

Tom弹架构

Java spring 源码

常见杀毒软件及其引擎的特点

喀拉峻

网络安全 病毒扫描

恒源云(GPUSHARE)_【功能更新】实例日志上线,操作一目了然

恒源云

深度学习 算力加速

Kyligence + 亚马逊云科技丨实现云上的精细化运营和数字化指挥

Kyligence

十年期货股票行情数据轻松处理——TDengine在同心源基金的应用

TDengine

数据库 tdengine 时序数据库

JavaScript 中的 .forEach() 和 for...of

devpoint

JavaScript foreach for...of 12月日更

Go语言学习查缺补漏ing Day5

恒生LIGHT云社区

golang 编程语言

es单机安装及配置其系统服务

elasticsearch

7.《重学JAVA》--运算符

杨鹏Geek

Java 25 周年 28天写作 12月日更

Kafka之为什么需要消息队列

编程江湖

大数据 kafka

Python代码阅读(第68篇):指定值出现次数

Felix

Python 编程 列表 阅读代码 Python初学者

如何搭建批流一体大数据分析架构?

Kyligence

AWS IoT 物联网系列,第四篇:如何使用 AWS IoT 做 OTA 升级_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章