?
?隨著物聯(lián)網(wǎng)行業(yè)的快速發(fā)展,越來(lái)越多的物聯(lián)網(wǎng)云服務(wù)平臺(tái)涌現(xiàn)。如何快速實(shí)現(xiàn)應(yīng)用開(kāi)發(fā),如何管理,如何讓設(shè)備快速上云,成為關(guān)注的焦點(diǎn)。
第一期中我們介紹了基于MQTT協(xié)議快速接入利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái),本期我們將介紹如何使用NB860系列模組通過(guò)云云對(duì)接快速接入利爾達(dá)云平臺(tái),并介紹兩者數(shù)據(jù)交互操作流程,幫助用戶或開(kāi)發(fā)人員盡快完成相關(guān)的應(yīng)用開(kāi)發(fā)。
所需產(chǎn)品
本次接入的利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái)是我司自主研發(fā)的云平臺(tái),為設(shè)備提供安全可靠的連接管理能力,整合物聯(lián)網(wǎng)產(chǎn)業(yè)鏈上下游,向下連接智能設(shè)備,向上承接物聯(lián)網(wǎng)應(yīng)用,形成端到云完整鏈路物聯(lián)網(wǎng)解決方案,賦能企業(yè)各類IOT場(chǎng)景接入。
另外用到的利爾達(dá)NB860/MB960/MB260系列模組是基于5G NB-IoT芯片自主開(kāi)發(fā)的第三代NB-IoT模組。該款模組集高性價(jià)比、高安全性和低功耗等優(yōu)點(diǎn)于一身,擁有藍(lán)牙、OpenCPU等能力,為智能表計(jì)、智能煙感、智能停車、智慧路燈等百萬(wàn)級(jí)成熟NB-IoT應(yīng)用提供了更優(yōu)選擇。
利爾達(dá)NB860/MB960/MB260系列模組支持TCP/UDP、MQTT、LwM2M等多種協(xié)議接入云平臺(tái),為行業(yè)應(yīng)用開(kāi)發(fā)提供了更多的可能性。本文我們將為大家介紹利爾達(dá)NB860模組基于Lwm2m協(xié)議依托AEP平臺(tái)實(shí)現(xiàn)云云對(duì)接功能快速接入利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái),實(shí)現(xiàn)數(shù)據(jù)交互。
設(shè)備端流程:上電即上云
利爾達(dá)NB860/MB960/MB260系列模組支持上電即上云。設(shè)備上電后,模組會(huì)自動(dòng)向云平臺(tái)發(fā)起流程操作,完成一系列駐網(wǎng)注冊(cè)登錄平臺(tái)流程,用戶在此期間無(wú)需任何指令配置即可完成云平臺(tái)對(duì)接。
云平臺(tái)端流程:保姆級(jí)配置教程
利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái)提供了完善的云上配置流程及操作步驟。用戶可通過(guò)文檔中心查閱相關(guān)文檔進(jìn)行快速配置。
01
在電信平臺(tái)添加應(yīng)用和產(chǎn)品
在進(jìn)行物聯(lián)網(wǎng)平臺(tái)云網(wǎng)關(guān)配置前,需在中國(guó)電信AEP平臺(tái)完成產(chǎn)品創(chuàng)建,并添加應(yīng)用。
前提條件
已完成中國(guó)電信AEP平臺(tái)賬號(hào)注冊(cè)和認(rèn)證。
操作步驟
1、登錄中國(guó)電信AEP平臺(tái)。
2、在產(chǎn)品中心頁(yè)面,單擊右上角的創(chuàng)建產(chǎn)品。
3、在彈出的對(duì)話框中,完成參數(shù)配置后,單擊確定。
本示例配置參數(shù)如下表所示。
4、單擊左側(cè)導(dǎo)航欄的應(yīng)用管理,單擊頁(yè)面右上角的新增應(yīng)用,完成參數(shù)配置后,單擊創(chuàng)建。
可根據(jù)頁(yè)面提示,自定義配置參數(shù)。應(yīng)用創(chuàng)建完成后,在應(yīng)用列表,單擊該應(yīng)用的查看詳情按鈕,查看并保存App Key和App Secret的值。
5、在產(chǎn)品中心找到相應(yīng)的產(chǎn)品定義電信物模型,電信非透?jìng)鳟a(chǎn)品才能在電信平臺(tái)定義物模型數(shù)據(jù)。
02
在物聯(lián)網(wǎng)平臺(tái)創(chuàng)建產(chǎn)品
您需要在物聯(lián)網(wǎng)平臺(tái)創(chuàng)建產(chǎn)品,產(chǎn)品名稱最好與中國(guó)電信AEP平臺(tái)產(chǎn)品名稱一致,方便對(duì)應(yīng)相應(yīng)產(chǎn)品。
向上滑動(dòng)閱覽
前提條件
已在中國(guó)電信AEP平臺(tái)完成應(yīng)用和產(chǎn)品添加。
操作步驟
1、登錄物聯(lián)網(wǎng)平臺(tái)控制臺(tái)。
2、在右側(cè)導(dǎo)航欄,單擊創(chuàng)建產(chǎn)品,完成參數(shù)配置,單擊確認(rèn),創(chuàng)建產(chǎn)品完成后系統(tǒng)將會(huì)自動(dòng)訂閱(包括設(shè)備上下線通知,設(shè)備數(shù)據(jù)變化通知,設(shè)備事件上報(bào)通知,設(shè)備指令響應(yīng)通知),刪除產(chǎn)品將會(huì)刪除所有訂閱。
此處參數(shù)配置如下。
3、在物聯(lián)網(wǎng)云平臺(tái)側(cè)邊欄點(diǎn)擊產(chǎn)品管理,點(diǎn)擊創(chuàng)建好的產(chǎn)品名稱查看產(chǎn)品詳情,點(diǎn)擊物模型定義,點(diǎn)擊編輯物模型進(jìn)行新增物模型數(shù)據(jù)如下:
屬性:
4、單擊左側(cè)導(dǎo)航欄的應(yīng)用管理,單擊頁(yè)面右上角的新增應(yīng)用,完成參數(shù)配置后,單擊創(chuàng)建。
*提示:在物聯(lián)網(wǎng)云平臺(tái)添加的物模型和電信平臺(tái)添加的物模型可以不一致,中間通過(guò)物聯(lián)網(wǎng)平臺(tái)的數(shù)據(jù)腳本解析將兩種物模型數(shù)據(jù)進(jìn)行解析對(duì)應(yīng),但還是建議兩個(gè)平臺(tái)物模型保持一致,方便使用和創(chuàng)建數(shù)據(jù)解析腳本。
03
使用云網(wǎng)關(guān)創(chuàng)建設(shè)備
您只需要在物聯(lián)網(wǎng)平臺(tái)某一產(chǎn)品下創(chuàng)建設(shè)備,平臺(tái)將會(huì)同步在電信平臺(tái)相應(yīng)的產(chǎn)品下創(chuàng)建設(shè)備,設(shè)備名稱與中國(guó)電信AEP平臺(tái)設(shè)備名稱建議一致,以便對(duì)應(yīng)查找。
向上滑動(dòng)閱覽
前提條件
已在中國(guó)電信AEP平臺(tái)完成應(yīng)用和產(chǎn)品添加,已在物聯(lián)網(wǎng)平臺(tái)完成電信關(guān)聯(lián)產(chǎn)品添加。
操作步驟
1、登錄物聯(lián)網(wǎng)平臺(tái)控制臺(tái)。
2、點(diǎn)擊上面導(dǎo)航欄中云平臺(tái),單擊側(cè)邊欄設(shè)備管理,點(diǎn)擊添加設(shè)備完成參數(shù)配置,單擊確認(rèn)。
3、按照頁(yè)面提示填寫(xiě)信息,然后單擊確認(rèn)。
也可以使用批量導(dǎo)入導(dǎo)入電信設(shè)備,請(qǐng)下載模板使用模板導(dǎo)入。
*提示:電信設(shè)備的設(shè)備ID需要去電信AEP平臺(tái)查找,本平臺(tái)不可見(jiàn)。
04
創(chuàng)建云云對(duì)接數(shù)據(jù)解析腳本
完成設(shè)備和產(chǎn)品物模型的創(chuàng)建,為了和電信AEP平臺(tái)進(jìn)行通信,物聯(lián)網(wǎng)平臺(tái)的物模型和中國(guó)電信平臺(tái)物模型的數(shù)據(jù)格式不同,需要在產(chǎn)品管理相應(yīng)產(chǎn)品下創(chuàng)建數(shù)據(jù)解析腳本進(jìn)行格式轉(zhuǎn)換。
示例編寫(xiě)了電信非透?jìng)髟O(shè)備的JS腳本,如下:
向上滑動(dòng)閱覽
1? ?//上行:屬性上報(bào),事件上報(bào)
2? ?var PROPERTY_REPORT_NAME = "property_report"; //屬性上報(bào)。
3? ?var EVENT_REPORT_NAME = "event_report"; //事件上報(bào)。
4? ?var EVENT_HUMI_WARNING_PROPERTY = "TEST_EVENT"; ?// 測(cè)試事件,和后臺(tái)物模型定義事件標(biāo)識(shí)保持一致
5
6? ?// 下行:服務(wù)調(diào)用
7? ?var EXAMPLE_SERVCE_IDENTIFY = "ontemp";
8
9
10? ?/**
11? ?* 上行平臺(tái)間物模型數(shù)據(jù)格式轉(zhuǎn)換
12? ?*
13? ?*/
14? ?function rawDataToProtocol(strString) {
15? ? ? var jsonMap = {}
16? ? ? var report = JSON.parse(strString);
17
18? ? ? if (report.reportType == 1) {
19? ? ? ? ? jsonMap['report_type'] = PROPERTY_REPORT_NAME; //必要字段,JSON格式,屬性上報(bào)
20? ? ? var params = {};
21? ? ? params['temp'] = report.temp; //對(duì)應(yīng)產(chǎn)品屬性中temp。
22? ? ? jsonMap['params'] = params; //必要字段,JSON格式,屬性上報(bào)參數(shù)。
23? ?} else if(report.reportType == 2) {
24? ? ? ?jsonMap['report_type'] = EVENT_REPORT_NAME; //必要字段,JSON格式,事件標(biāo)識(shí)。
25? ? ? // 判斷事件標(biāo)識(shí)
26? ? ? ?jsonMap['event'] = EVENT_HUMI_WARNING_PROPERTY;
27? ? ? ?var params = {};
28? ? ? ?params['temp'] = report.temp; //對(duì)應(yīng)產(chǎn)品屬性中prop_int16。
29? ? ? jsonMap['params'] = params; //必要字段,JSON格式,事件上報(bào)參數(shù)。
30? ?}
31? ? // 必須stringify 格式化
32? ?return JSON.stringify(jsonMap);
33? ?}
34
35? ?/**
36? ?* 下行平臺(tái)間物模型數(shù)據(jù)格式轉(zhuǎn)換
37? ?*
38? ?*/
39? ?function protocolToRawData(json) {
40? ? ? var result ={};
41? ? ? var obj= JSON.parse(json);
42? ? ? var params=obj.params;
43 result.serviceIdentify=EXAMPLE_SERVICE_IDENTIFY; //必要字段,JSON格式,服務(wù)標(biāo)識(shí)。
44? ? ? result.params=params; //必要字段,JSON格式,服務(wù)調(diào)用參數(shù)。
45? ? ? return JSON.stringify(result);
46? ?}
腳本寫(xiě)完后可以在旁邊的模擬數(shù)據(jù)中先進(jìn)行測(cè)試,如果所有的模擬數(shù)據(jù)對(duì)應(yīng)的模擬運(yùn)行結(jié)果如預(yù)期一樣則說(shuō)明腳本編寫(xiě)完成,如下:
電信透?jìng)髟O(shè)備JS腳本編寫(xiě)可參考如下:
向上滑動(dòng)閱覽
1?? var PROPERTY_REPORT_VALUE = 0x00; //屬性上報(bào)。
2? ?var PROPERTY_REPORT_NAME = "property_report"; //屬性上報(bào)。
3? ?var EVENT_REPORT_VALUE = 0x01; //事件上報(bào)。
4? ?var EVENT_REPORT_NAME = "event_report"; //事件上報(bào)。
5
6
7? ?var EVENT_HUMI_WARNING_VALUE =1; ?// 濕度告警標(biāo)識(shí)
8? ?var EVENT_HUMI_WARNING_PROPERTY = "TEST_EVENT"; ?// 濕度告警標(biāo)識(shí),和后臺(tái)物模型定義事件標(biāo)識(shí)保持一致
9
10? ?var COMMAND_TYPE_FLAG =?
"command_type"; ?//下行指令類型標(biāo)識(shí)符號(hào)
11
12
13? ?// service 示例
14? ?var EXAMPLE_SERVICE_IDENTIFY = "service1";
15? ?var EXAMPLE_SERVICE_IDENTIFY_VALUE = 1;
16
17
18? ?// 屬性上報(bào) ?head+參數(shù)1+參數(shù)2+......
19? ?var property_report = "00f0ff013FA00000";
20? ?// 事件上報(bào) head+ 事件標(biāo)識(shí) + 參數(shù)1+參數(shù)2+......
21? ?var event_report = "0101f0ff013FA00000";
22
23? ?/**
24? ?* 上行16進(jìn)制字符串轉(zhuǎn)物模型JSON入口
25? ?*
26? ?*/
27? ?function rawDataToProtocol(strString) {
28? ? ? var bytes = str2Bytes(strString);
29? ? ? var uint8Array = new Uint8Array(bytes.length);
30? ? ? for (var i = 0; i < bytes.length; i++) {
31? ? ? ? ? uint8Array[i] = bytes[i] & 0xff;
32? ? ? }
33? ? ? var dataView = new DataView(uint8Array.buffer, 0);
34? ? ? var jsonMap = new Object();
35? ? ? var fHead = uint8Array[0]; // command
36
37? ? ? if (fHead == PROPERTY_REPORT_VALUE) {
38? ? ? ? ?jsonMap['report_type'] = PROPERTY_REPORT_NAME; //必要字段,JSON格式,屬性上報(bào)topic。
39? ? ? ? ? var params = {};
40? ? ? ? ? params['prop_int'] = dataView.getInt8(1); //對(duì)應(yīng)產(chǎn)品屬性中prop_int16。
41? ? ? ?params['uint8_prop'] = dataView.getUint8(2); //對(duì)應(yīng)產(chǎn)品屬性中prop_bool。
42? ? ? ? ? params['bool_prop'] = ?uint8Array[3];
43? ? ? ? ? params['prop_float'] = dataView.getFloat32(4); //對(duì)應(yīng)產(chǎn)品屬性中prop_float。
44? ? ? ? ? jsonMap['params'] = params; //必要字段,JSON格式,屬性上報(bào)參數(shù)。
45? ? ? } else if(fHead == EVENT_REPORT_VALUE) {
46? ? ? ? ?jsonMap['report_type'] = EVENT_REPORT_NAME; //必要字段,JSON格式,屬性上報(bào)。
47
48? ? ? ? ?var event_flag_value = uint8Array[1];
49? ? ? ? ?// 判斷事件標(biāo)識(shí)
50? ? ? ? ?if(event_flag_value == EVENT_HUMI_WARNING_VALUE){
51? ? ? ? ? ? ?jsonMap['event'] = EVENT_HUMI_WARNING_PROPERTY;
52? ? ? ? ?}
53? ? ? ? ?var params = {};
54? ? ? ? ?params['prop_int'] = dataView.getInt8(2); //對(duì)應(yīng)產(chǎn)品屬性中prop_int16。
55? ? ? jsonMap['params'] = params; //必要字段,JSON格式,事件上報(bào)參數(shù)。
56? ? ? }
57? ? ? ?// 必須stringify 格式化
58? ? ? return JSON.stringify(jsonMap);
59? ? ? }
60
61
62? ? ? /**
63? ? ? * 下行json格式數(shù)據(jù)轉(zhuǎn)十六進(jìn)制字符串入口
64? ? ? *
65? ? ? */
66? ? ? function protocolToRawData(json) {
67? ? ? var command_type = json['command_type'];
68? ? ? var payloadArray = [];
69
70? ? ? // 參數(shù)
71? ? ? var params = json['params'];
72? ? ? var prop_float = params['prop_float'];
73? ? ? var prop_int16 = params['prop_int'];
74? ? ? var prop_bool = params['prop_bool'];
75? ? ? var prop_int = params['on'];
76
77? ? ? payloadArray = payloadArray.concat(buffer_uint8(COMMAND_SERVICE_CALL_VALUE)); ?//command字段。
78
79? ? ? //判斷服務(wù)標(biāo)識(shí),自定義服務(wù)標(biāo)識(shí)對(duì)應(yīng)的標(biāo)識(shí)值
80? ?if(json['service_identify']==EXAMPLE_SERVICE_IDENTIFY){
81? ? ? ? ? payloadArray = payloadArray.concat(buffer_uint8(EXAMPLE_SERVICE_IDENTIFY_VALUE));
82? ? ? }
83? ? ? payloadArray = payloadArray.concat(buffer_int16(prop_int16)); //屬性'prop_int16'的值。 ? ? ?
84
85? ? ? return bytes2Str(payloadArray);
86? ?}
87
88
89? ?//以下是部分輔助函數(shù)。
90? ?function buffer_uint8(value) {
91? ? ? var uint8Array = new Uint8Array(1);
92? ? ? var dv = new DataView(uint8Array.buffer, 0);
93? ? ? dv.setUint8(0, value);
94? ? ? return [].slice.call(uint8Array);
95? ?}
96? ?function buffer_int16(value) {
97? ? ? var uint8Array = new Uint8Array(2);
98? ? ? var dv = new DataView(uint8Array.buffer, 0);
99? ? ? ?dv.setInt16(0, value);
100? ? ? return [].slice.call(uint8Array);
101? ?}
102? ?function buffer_int32(value) {
103? ? ?var uint8Array = new Uint8Array(4);
104? ? ?var dv = new DataView(uint8Array.buffer, 0);
105? ? ?dv.setInt32(0, value);
106? ? ?return [].slice.call(uint8Array);
107? ?}
108
109
110? ?/*
111? ?字符串轉(zhuǎn)字節(jié)數(shù)組
112? ?*/
113? ?function str2Bytes(str)
114? ?{
115? ? ? var pos = 0;
116? ? ? var len = str.length;
117? ? ? if(len %2 != 0)
118? ? ? {
119? ? ? return null;
120? ? ? }
121
122? ?len /= 2;
123? ? ? var hexA = new Array();
124? ? ? for(var i=0; i
125? ? ? {
126? ? ? ? ?var s = str.substr(pos, 2);
127? ? ? ? ?var v = parseInt(s, 16);
128? ? ? ? ?hexA.push(v);
129? ? ? ? ?pos += 2;
130? ? ? }
131? ? ? return hexA;
132? ?}
133
134? ?/* 字節(jié)數(shù)組轉(zhuǎn)字符串 */
135? ?function bytes2Str(arr)
136? ?{
137? ?var str = "";
138? ? ? for(var i=0; i
139? ? ? {
140? ? ? var tmp = arr[i].toString(16);
141? ? ? if(tmp.length == 1)
142? ? ? ? ?{
143? ? ? ? ? ? ?tmp = "0" + tmp;
144? ? ? }
145? ? ? ? ?str += tmp;
146? ?}
147? ? ? return str;
148? ?}
05
效果展示
至此,我們已完成電信平臺(tái)應(yīng)用,產(chǎn)品,產(chǎn)品物模型創(chuàng)建,物聯(lián)網(wǎng)平臺(tái)電信關(guān)聯(lián)產(chǎn)品,設(shè)備,產(chǎn)品物模型創(chuàng)建,數(shù)據(jù)解析腳本編寫(xiě)。
數(shù)據(jù)上行
設(shè)備上電入網(wǎng)后自動(dòng)注冊(cè)到平臺(tái),可在設(shè)備列表中看到設(shè)備連接狀態(tài)為在線。
通過(guò)AT指令A(yù)T+NMGS向平臺(tái)發(fā)送數(shù)據(jù)(如不符合定義的物模型數(shù)據(jù),將會(huì)解析錯(cuò)誤),即可在物聯(lián)網(wǎng)平臺(tái)的設(shè)備物模型設(shè)備數(shù)據(jù)中的屬性上報(bào)看到結(jié)果。
數(shù)據(jù)下行
在線調(diào)試,選擇透?jìng)髡{(diào)試,輸入有效的數(shù)據(jù)點(diǎn)擊發(fā)送。
設(shè)備收到消息為:
?
至此,我們已完成依托AEP平臺(tái)與利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái)進(jìn)行云云對(duì)接的端(Lierda?NB860模組)到云(物聯(lián)網(wǎng)全連接云平臺(tái))對(duì)接實(shí)現(xiàn)數(shù)據(jù)交互功能。第三期我們將介紹NB860模組配合利爾達(dá)物聯(lián)網(wǎng)全連接云平臺(tái)基于TCP協(xié)議進(jìn)行直連對(duì)接快速上云,敬請(qǐng)期待。
評(píng)論
查看更多