1. 程式人生 > >第四篇:如何使用 AWS IoT 做 OTA 升級

第四篇:如何使用 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/notify 以獲取任務通知資訊。(訂閱該 topic 不會實時收到job的推送通知。Job 的獲取需要在下述第二步通過定時輪詢的方法定期獲取訊息通知。但需要注意的是,一定要在 $aws/things/ThingName/jobs/get 請求之前訂閱 $aws/things/ThingName/jobs/notify 主題,否則在後續的第三步無法收到任務列表。)
  2. 當終端裝置訂閱 $aws/things/ThingName/jobs/notify 後,硬體裝置主動釋出訊息到 $aws/things/ThingName/jobs/get 獲取待執行的 job 列表。(可以根據需要自定義輪詢時間,例如10分鐘取一次,具體可以根據場景來設定。)
  3. 此時裝置會收到 $aws/things/ThingName/jobs/notify 訊息,內容包含有任務列表。如果列表中包含了一個或多個任務,裝置可自行選擇需優先執行的任務。
  4. 獲取到任務列表後,我們可以根據 job 的優先順序自行選擇優先需要執行的 job,然後把訊息傳送到 $aws/things/thingName/jobs/jobId/get 獲取該 jobid 詳細的任務資訊。通過訂閱 $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. 釋出訊息到 $aws/things/thingName/jobs/jobId/get 主題獲取待執行列表,注意這裡 jobId 應該為 $next。(注意:這裡的 $next 並非一個變數名,而是一個真實的引數值。因此在 get 的時候,應該傳送的 topic 為 $aws/things/thingName/jobs/$next/get。同樣地,裝置也要定期輪詢以獲取下一個任務。訂閱 $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 所示開啟裝置索引。命令如下

 aws iot update-indexing-configuration --thing-indexing-configuration thingIndexingMode=REGISTRY_AND_SHADOW

開啟索引之後,我們就可以使用索引查詢我們的目標裝置,假設裝置當前已經註冊到 AWS IoT 平臺,並且通過 MQTT 把裝置狀態更新到裝置影子上。下述展示如何在AWS控制檯查詢系統版本號為“bc78fd46f845”的裝置。後續我們將向這些裝置推送升級任務,升級到新的韌體系統:

同樣的,我們也可以使用 AWS Cli 去查詢裝置影子,以獲得系統版本號為 bc78fd46f845 的裝置:

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

查詢完畢之後我們把這些裝置加入一個裝置組裡面,這裡我們把這些裝置都加入名為 “jobdemo” 組裡面,稍後我們將向這個組裡面的裝置傳送升級任務。

2. 在控制檯建立任務

建立任務前我們需要定義一個任務文件,這個任務文件將使用 json 形式描述了裝置需要執行的遠端操作,任務文件可能還包括了需要下載的韌體升級包地址,以下是一個示例任務文件,我把這個任務文件儲存到 S3 儲存桶上。

[
  {
     "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建立流程:

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的任務文件。

{
  "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 任務)這個訊息的內容中包含了任務文件:

{
  "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,報告裝置當前任務狀態:

{
  "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 IoT OTA 升級

AWS IoT 物聯網系列部落格 當前物聯網環境中,裝置型別多種多樣,連線方式不一而足。為了幫助讀者更好的理解並運用 AWS IoT 相關服務,我們提供了一個完整的 IoT 起步指南,包含裝置的註冊及上線、裝置管理、使用者身份及許可權管理以及成本控制,通過這一系列的起步指南,

AWS IoT Core服務成本優化

AWS IoT 物聯網系列部落格 當前物聯網環境中,裝置型別多種多樣,連線方式不一而足。為了幫助讀者更好的理解並運用 AWS IoT 相關服務,我們提供了一個完整的 IoT 起步指南,包含裝置的註冊及上線、裝置管理、使用者身份及許可權管理以及成本控制,通過這一系列的起步指南,

RabbitMQSpring集成RabbitMQ

led ase don 才會 catch rabl try edt .get 前面幾篇講解了如何使用rabbitMq,這一篇主要講解spring集成rabbitmq。 首先引入配置文件org.springframework.amqp,如下 &l

Web框架 - Django

執行指定 gin nag nbsp 表達 font con 展現 del 前言 Django是一個開放源代碼的Web應用框架,由Python寫成。它和J2EE一樣,采用了MVC的軟件設計模式,即模型M,視圖V和控制器C。 本文將講解DJang

python函數續

級別 加載 失效 結束 解釋 全局 定義 執行文件 作用 1、名稱空間和作用域 名稱空間:存放名字的地方,準確的說名稱空間是存放名字與變量值綁定關系的地方名稱空間共有三種名稱空間既:  1、內置名稱空間:在python解釋器啟動時產生,存放一些python內置的名字  2

Spark SQL Catalyst源碼分析之TreeNode Library

pla where 並且 手冊 input bst node lec esc /** Spark SQL源碼分析系列文章*/ 前幾篇文章介紹了Spark SQL的Catalyst的核心運行流程、SqlParser,和Analyzer,本來打算直接寫Optimizer

R學習筆記 函數,分支和循環

匿名 操作數 play 控制 als layers null 操作 str 變量用於臨時存儲數據,而函數用於操作數據,實現代碼的重復使用。在R中,函數只是另一種數據類型的變量,可以被分配,操作,甚至把函數作為參數傳遞給其他函數。分支控制和循環控制,和通用編程語言的風格很相似

文件處理

表示 創建 char flush open borde 統一 IT 打開方式 一、文件操作 介紹 計算機系統分為:計算機硬件,曹祖系統,應用程序三部分。 我們用Python或其他語言編寫的應用程序若想要把數據永久保存下來,必須要保存於硬盤中,這就涉

添加一個線程組

HR only 統計信息 dia 負載 conf .com 出現 循環 1.測試需求:建立20個用戶,訪問www.baidu.com,查看在負載達到 30QPS的時候的一個平均的響應時間; QPS:query per second每秒查詢率,是查詢服務器每秒能處理的查詢次

Ansible 常用模塊使用

__name__ 處理 ron mage minute art outfile and 刪除一個用戶 一、 command | shell 模塊 該模塊為:執行命令模塊 (由於命令模塊較為強大,可根據自身對操作系統的熟練程度而增加。所以這裏不再介紹類似可以實

路由網關(zuul)

stat ger ice etl 沒有 aps 服務 lan enter 一 Zuul簡介 Zuul的主要功能是路由轉發和過濾器。路由功能是微服務的一部分,比如/user/**轉發到到user服務,/api/**轉發到到api服務。zuul默認和Ribbon結合實現了負載

韋東山教程需安裝的驅動和軟件

二進制 image test ask x文件 exe info 自制 編輯 目錄 一、eop燒寫器驅動安裝 二、oflash燒寫軟件安裝 三、串口工具(MobaXterm_Portable_v10.4.exe) 四、uboo通過USB燒寫程序需安裝的驅動和軟件 五、hex

數據分析 聚類分析(劃分)

think trace stat pid 函數返回 around 構建 之前 得出 聚類是把一個數據集劃分成多個子集的過程,每一個子集稱作一個簇(Cluster),聚類使得簇內的對象具有很高的相似性,但與其他簇中的對象很不相似,由聚類分析產生的簇的集合稱作一個聚類。在相同的

SpringBoot自學教程 | Spring Boot整合mybatis

整合 com 字段 apach param pack image ice rac   引入依賴   1:在pom文件引入mybatis-spring-boot-starter的依賴: 1 <dependency> 2 <groupId>

史上最簡單的SpringCloud教程 | 斷路器(Hystrix)

技術分享 熔斷器 enable layer get local nsh 12c host 在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互調用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來調用。為了保證

史上最簡單的SpringCloud教程 | 斷路器(Hystrix)(Finchley版本)

stat api serve 依賴 網頁 固定 lock 不能 mar 在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互調用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來調用。為了保證其高可用,單個服務

python基礎之雜貨鋪

  在這一篇中我們將對上幾篇的Python零碎的知識進行補充,即字串的格式化輸出,以及深淺拷貝,接下來我們將對這兩種進行一一介紹。 一、字串格式化輸出   關於字串的格式化輸出,我們需要了解為什麼需要字串的格式化,同時掌握格式化輸出的兩種用法:百分號方式、format方式。接下來我們就這兩種

java讀取Excel簡單模板

場景:對於經常需要匯入Excel模板或資料來解析後加以應用的,使用頻率非常之高,做了一個比較穩定的版本,體現在這些地方工具:org.apache.poi使用前必須瞭解這些:1、要解析,那肯定先判斷是不是Excel2、xls字尾的Excel,是03版及以前的用HSSFWorkbook類  &

從零開始學產品BUG的生命週期

本篇為【從零開始學產品】系列課第1章第3節 歡迎到公眾號選單欄,獲取產品經理課程更多資料   “從開始到死亡,這是世間萬物的宿命嗎?” “是的,連Bug都如此。”   --摘自【修真神界】第三千六百五十一章 為了女神寫Bug

Docker $ Docker 倉庫的使用

一.Docker倉庫簡介 1.倉庫(Repository)是集中存放映象的地方,每個倉庫有多個映象。Docker hub是Docker官方維護的公共倉庫,這裡存放了大量的映象,大部分映象都可以在這裡拉取。 2.註冊伺服器(Registry)和倉庫不同,註冊伺服器是管理倉庫的地方,註冊