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

寫在前面html

本文在LinkEdge快速入門樣例驅動的基礎上,加載了MQTT訂閱的客戶端,使得邊緣端容器能夠經過MQTT得到外部數據。node

1. 系統需求程序員

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

本文在該樣例的基礎上,在光照傳感器的驅動程序上加載了MQTT訂閱的客戶端,使得光照傳感器能夠經過訂閱的方式得到光照強度值。npm

2. 系統架構centos

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

圖 1 邊緣實例架構服務器

表格 1 模擬值生成代碼架構

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

delta = -100;

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

delta = 100;

}

self.lightSensor.illuminance += delta;

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


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

3. 安裝部署

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

4. 改寫驅動

4.1. 下載驅動

下載LightSensor驅動源碼,下載解壓後是一個index.js文件。


圖 3 下載驅動

4.2. 編寫驅動

(1) index.js中添加MQTT訂閱客戶端代碼

表格 2 MQTT訂閱客戶端代碼

'use strict';

const {

RESULT_SUCCESS,

RESULT_FAILURE,

ThingAccessClient,

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

var mqtt = require('/usr/bin/mqtt');

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

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

var num = 0;

var qtt = {};

qtt.id = '2002';

qtt.name = 'shoen';

qtt.age= 5000;

client.subscribe('test',{qos:1}); //訂閱主題爲test的消息

client.on('message',function(top,message) {

qtt=JSON.parse(message.toString());

});

// Max retry interval in seconds for registerAndOnline.

const MAX_RETRY_INTERVAL = 30;

(2) 註釋原有模擬部分代碼,添加得到值代碼。

表格 3 得到數據來源

setInterval(function () {

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

// delta = -100;

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

// delta = 100;

// }

// self.lightSensor.illuminance += delta;

if (self.client) {

try {

self.lightSensor.illuminance = qtt.age;

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文件。


圖 4新建驅動

(3) 部署實例


圖 5 部署實例

5. 腳本解析

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

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


圖 6 link-iot-edge.h源碼(局部)

n docker pull "$LINKEDGE_IMG"

Ø LINKEDGE_IMG=$IMAGE_NAME_PREFIX:$1

Ø registry.cn-hangzhou.aliyuncs.com/iotedge/edge_x86_centosversion

n docker run -d --rm --privileged=true -v linkedge_vol1:/usr/.security -v linkedge_vol2:/etc/.sec/ -v linkedge_vol3:/linkedge/gateway/build/.sst -v linkedge_vol4:/tmp/var/run/ -v linkedge_vol5:/linkedge/run --name=config-params $LINKEDGE_IMG $2 $3 $4

n docker

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

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

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

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

Ø -v linkedge_vol1:/usr/.security

宿主機的linkedge_vol1目錄掛載到容器的/usr/.security

Ø -v linkedge_vol2:/etc/.sec/

Ø -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 -v c:/test:/data -v linkedge_vol1:/usr/.security -v linkedge_vol2:/etc/.sec/ -v linkedge_vol3:/linkedge/gateway/build/.sst -v linkedge_vol4:/tmp/var/run/ -v linkedge_vol5:/linkedge/run --name=config-params $LINKEDGE_IMG $2 $3 $4

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,系統配置以下:


圖 7 Windows系統配置

10. 最終效果

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


圖 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.


原文連接

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索