1. 程式人生 > >阿里雲物聯網邊緣計算載入MQTT驅動

阿里雲物聯網邊緣計算載入MQTT驅動

寫在前面

    本文在LinkEdge快速入門樣例驅動的基礎上,載入了MQTT訂閱的客戶端,使得邊緣端容器可以通過MQTT獲得外部資料。

1. 系統需求

物聯網邊緣計算平臺,又名Link IoT Edge[1]。在物聯網邊緣計算幫助文件中的 “快速入門”描述了這樣一種應用場景,“光照感測器檢測室內光照強度是否大於500 Lux,若光照強度大於500 Lux,則光照感測器認為室內不需要開燈,從而去關閉燈(客廳燈開關等於1),否則開啟燈(客廳燈開關等於0)。”

本文在該樣例的基礎上,在光照感測器的驅動程式上載入了MQTT訂閱的客戶端,使得光照感測器可以通過訂閱的方式獲得光照強度值。

2. 系統架構

    圖 1 給出了樣例的邊緣例項架構,樣例中LightSensor值是模擬值,通過定時器每2000毫秒執行表格 1中程式碼。

 3f9b6e5a64fb0104c0d5091de1fde34233b8ac8d

圖 1 邊緣例項架構

表格 1 模擬值生成程式碼

          if (self.lightSensor.illuminance >= 600) {

             delta = -100;

           } else if (self.lightSensor.illuminance <= 100) {

             delta = 100;

           }

          self.lightSensor.illuminance += delta;

   圖 2給出了在在光照感測器的驅動程式上載入了MQTT訂閱的客戶端的架構。

8d3dd9c1e0fafb8a815017050ede9e990d449332

圖 2 光照感測器驅動掛載MQTT訂閱客戶端

3.  安裝部署

樣例完整的安裝和配置流程詳見幫助[2]。

4. 改寫驅動

4.1. 下載驅動

下載LightSensor驅動原始碼,下載解壓後是一個index.js檔案。

5e02272912abedad264da8dc8fafb3c76bd1170a

圖 3 下載驅動

4.2. 編寫驅動

(1) index.js中新增MQTT訂閱客戶端程式碼

表格 2 MQTT訂閱客戶端程式碼

'use strict';

 

const {

  RESULT_SUCCESS,

  RESULT_FAILURE,

  ThingAccessClient,

} = require('linkedge-thing-access-sdk');

 

連線到訂閱主題為 

// Max retry interval in seconds for registerAndOnline.

const MAX_RETRY_INTERVAL = 30;

(2) 註釋原有模擬部分程式碼,新增獲得值程式碼。

表格 3 獲得資料來源

        setInterval(function () {

           

          if (self.client) {

            try {

                            var properties = {'MeasuredIlluminance': self.lightSensor.illuminance};

              console.log(`Report properties: ${JSON.stringify(properties)}`);

              self.client.reportProperties(properties);

            } catch (err) {

              console.log(err);

              self.client.cleanup();

            }

          }

        }, 2000);

4.3. 重新部署

(1) 將index.js壓縮成index.zip檔案,注意index.zip僅包含index.js檔案,不含其他任何資料夾。

(2) 新建驅動myLightSensor,上傳index.zip檔案。

3a901361653a5338266935ae176170eeef487272

圖 4新建驅動

(3) 部署例項

daa15a2aad671dee43b076c926afa91f2c9fda2e

圖 5 部署例項

5. 指令碼解析

在部署過程中,我們通過link-iot-edge.sh {productkey} {devicename} {devicesecret}下載和啟動邊緣計算平臺。

分析link-iot-edge.sh後,發現邊緣端實際是就是一個docker容器。其中主要幾行指令碼含義如下描述:

b543ec29d46866e9f555567503f9fc4164d7afdd

圖 6 link-iot-edge.h原始碼(區域性)

n  docker pull "$LINKEDGE_IMG"

Ø  LINKEDGE_IMG=$IMAGE_NAME_PREFIX:$1

Ø  registry.cn-hangzhou.aliyuncs.com/iotedge/edge_x86_centosn  docker

Ø  run建立一個新的容器並執行一個命令

Ø  -d後臺執行容器,並返回容器ID

Ø  --rm 容器退出時自動清理容器並刪除檔案系統,

Ø  --privileged=true 以特權方式啟動容器,允許掛載宿主機目錄

Ø  -v Ø  -v linkedge_vol3:/linkedge/gateway/build/.sst

Ø  -v linkedge_vol4:/tmp/var/run/

Ø  -v linkedge_vol5:/linkedge/run

Ø  --name=config-params 為容器指定一個名稱config-params

Ø  $LINKEDGE_IMG 容器名稱

Ø  $2 $3 $4三個均作為引數

n  為了方便訪問,修改以上啟動指令碼,使得容器內可以訪問宿主機c:/test目錄。

Ø  ${preflag} docker run --rm --privileged=true 6. Node.js實現MQTT

n  安裝node

n  安裝npm install mqtt

6.1. MQTT服務端

本文采用Apollo MQTT作為MQTT伺服器,安裝部署完畢後採用預設使用者名稱admin,密碼password。MQTT伺服器採用預設的1883埠。

6.2. MQTT客戶端釋出

表格 4 MQTT客戶端釋出

var mqtt = require('mqtt');

 

var options={username:'admin',password: 'password',clientId:'Nodejs-ed16ef77-5cf2-4e5c-b511-1af14451df58'};

var client = mqtt.connect('mqtt://*.*.*.*:1883',options);  //連線到MQTT服務端

 

var num = 0;

var qtt = {};

 

qtt.id = '1001';

qtt.name = 'shoen';

qtt.age= 2222;

 

client.publish('test', JSON.stringify(qtt), { qos: 0, retain: true });    

7. 設定容器

通過link-iot-edge.sh啟動邊緣容器後,需要進入容器安裝mqtt庫,並設定容器內環境引數,使得node.js編寫的mqtt客戶端能夠正確引用mqtt庫,即var mqtt = require('/usr/bin/mqtt');

設定主要步驟如下所示:

(1)       啟動容器:link-iot-edge.sh v1.7 a1xwL19pRAZ mygw uPcoNbWHYselHGpwG2HRtMvh********

(2)       進入容器:docker exec -it config-params /bin/bash

(3)       node.js設定引用

n  安裝淘寶cnpm:npm install -g cnpm --registry=https://registry.npm.taobao.org

n  全域性安裝mqtt:cnpm install –g mqtt

n  檢視cnpm全域性倉庫路徑:cnpm config get prefix

n  修改cnpm全域性倉庫路徑:cnpm config set /usr/bin

n  以上設定完畢後,才可以程式碼中新增引用:var mqtt = require('/usr/bin/mqtt');

n  以上設定重啟本容器失效

8. 容器命令

除錯過程中涉及的相關容器命令如下:

(1) 啟動容器時對映宿主機和容器目錄:-v c:/test:/data

(2) 檢視IP地址:ip addr

(3) 下載ifconfig:curl ifconfig.me

(4) find -name "*thing*"

n  linkedge-thing-access-sdk所在位置:./linkedge/gateway/build/bin/iot-gravity/runtime/nodejs8/node_modules/linkedge-thing-access-sdk

(5) 檢視容器映象docker image

(6) 停止容器 docker stop 容器ID

(7) 刪除映象 docker rmi 映象ID

9. 注意事項

(1) 驅動編寫錯誤可能包括:庫檔案未引用、node.js語法錯誤,mqtt連線錯誤;

(2) 邊緣例項部署過程中,如發生以上錯誤發生,光照感測器將始終處於“離線”狀態;

(3) 本文宿主機為Windows 10,系統配置如下:

270f09ce0cb749fed87b5a330c0ac3a48e2ed52a

圖 7 Windows系統配置

10. 最終效果

在宿主機上通過MQTT客戶端釋出一個qtt.age=2222資料,該資料會發送至MQTT伺服器,容器內載入的MQTT訂閱客戶端將收到該資料,並將該資料賦值給self.lightSensor.illuminance,獲取的值將通過self.client.reportProperties(properties);上報至IOT Hub,最終在LightSensor執行狀態中顯示光照度檢測值為2222Lux。

f4d119153d6f52652ae8c1cb0c6ae8a2516ca47c

圖 8 最終效果

寫在後面

今年3月底深圳雲棲大會後,和阿里雲Linkedge團隊幾位同學在西溪園區做了一次簡單的技術交流。阿里的同學介紹了物模型、容器等概念,我則提了異構工業裝置連線對於裝置驅動有較為強烈的需求……眨眼到了年底,Linkedge從公測到釋出,直到今天(12-5)正式釋出了v1.8,新加的幾項特性都值得關注,如“本地日誌可以自動同步到雲端的日誌服務產品中,支援按照業務功能進行查詢。”這極大方便了運維。此外,“支援C版本裝置驅動管理”,這對於我這樣一位老程式設計師(年紀大,而非經驗豐富)的吸引力是非常大的。

自10月17日開始試用Linkedge,學習時斷時續,這個過程中Linkedge的幫助文件不斷更新,導致前面截圖已失效。時至今日,終於輸出此文,雖然還沒有實現了詳細介紹如何在邊緣計算平臺上編寫驅動的目標,但至少走通了關於驅動的helloworld。最後,提幾點意見,希望Linkedge開發團隊能有所改進:

(1) 驅動除錯非常麻煩,幫助中沒有涉及除錯方式。--這點從v1.8中的特性來看應該有很大改善。

(2) 邊緣容器設定細節應對開發者開放。

(3) 希望提供一個能和容器外(宿主機或其他裝置)通訊的樣例,如通過串列埠、乙太網,這樣的樣例對於學習更加有效。

參考文獻

[1] 阿里雲物聯網邊緣計算 [EB/OL]. https://help.aliyun.com/product/69083.html.

[2] 物聯網邊緣計算快速入門[EB/OL]. https://help.aliyun.com/document_detail/85389.html.

 

作者:shoen
原文連結
更多技術乾貨 請關注阿里云云棲社群微訊號 :yunqiinsight