华为IoT平台NB编解码插件开发详细教程【上篇】
目錄
0、前言
一、環境搭建
1.1 安裝JDK
1.2 安裝eclipse
1.3 安裝Maven
二、Profile說明
三、插件編寫
3.1 源文件說明
3.2 修改文件路徑(包含)
3.3 修改pom.xml
3.4 導入工程
3.5 代碼實現
3.6 生成jar包
0、前言
本教程分為上、下篇,原作者是我的同事llb90,征得其同意后在這里再次發布,希望能幫到有需求的人,demo可在Github下載。
本文通過一個比較簡單又不失全面的例子,說明一下華為IoT平臺編解碼插件線下開發的整個開發流程。對于環境的搭建盡量一筆帶過,對核心編碼部分做比較詳細的講解。第二章Profile部分會先出給一個小例子作為demo,編解碼的編寫按照該pfofile中定義的字段來解析,以方便大家理解編解碼插件中的代碼。本文編寫過程中主要參考了“華為IoT平臺NB-IoT設備集成開發指南.pdf”。
一、環境搭建
開發編解碼插件使用的IDE是eclipse,語言是Java。本文盡量以簡單的方式告訴你如何將華為提供的編解碼樣例修改為適合自己的編解碼插件。即使你沒有什么Java基礎,只要懂得編程邏輯就好。跟著一起來吧!
1.1 安裝JDK
JDK版本1.8以上。參考網絡教程:https://blog.csdn.net/u010058695/article/details/100983213
1.2 安裝eclipse
下載并安裝eclipse。eclipse下載后解壓縮到本地即可運行。
1.3 安裝Maven
下載地址是: http://maven.apache.org/download.cgi? 下載后的文件解壓縮即可,然后添加環境變量。
在eclipse中配置maven插件。打開eclipse,點擊window->Preferences,彈出如下窗口:
在彈出的窗口左側欄中,依次找到并點擊Maven->Installations,在右側點擊Add按鈕,彈出如下圖所示窗口:
點擊Directory,選擇Maven的路徑,然后Finish。到此,Maven配置完成。
二、Profile說明
Profile實際上是一系列關于設備模型的描述文件,每個文件都使用JSON格式(鍵值對)。
Profile中首先需要說明設備的基本信息,包括廠商ID,廠商名稱,設備類型,接入協議,以及設備可以提供的哪些服務等;其次,profile中要針對每一項服務,用一個獨立的文件進行詳細描述。服務,可以理解為是對設備消息(上下行)功能的一個分類,一個服務就代表一類功能;每個服務下包含若干屬性和命令,每個屬性對應上報消息中的某一個數據,每個命令字段則對應下行消息中的某些字段。比如,一個電表設備,會上報電池電量、功率、電能、電壓等,可以將電池電量放在Battery服務中,屬性值為batteryLevel,將功率、電能、電壓都放在Transmission服務中,分別對應該服務下的Power、Energy、Voltage屬性??梢栽谝粭l消息中上報所有服務的所有屬性,也可以分開上報。
本例中提供的profile信息,基本信息如下:
設備類型: MyType 設備型號: MyModel 廠商ID : ThirdParty 廠商名稱: ThirdParty 協議: Coap數據服務有兩項:Battery,包含一個屬性BatteryLevel,兩個字節;Transmission,包含一個屬性upData,不定長數組(profile中表示不定長數組,需將屬性類型定義為string,長度設為一個比較大的數);包含一條下行命令CLOUDREQ,有兩個命令字段;cmdType,一個字節;downData,不定長數組。
profile采用在線開發的方式,如下圖所示:
本例中,采用一條消息上報所有服務屬性的方式。上報數據格式為:前兩個字節表示batteryLevel屬性,大端方式;第三個字節表示后續數據長度;第四個字節至最后,表示upData屬性。下行命令數據格式為:第一個字節表示cmdType;第二個字節至最后,表示downData。(請仔細理解該數據格式,插件的編寫就是按照數據格式解析出對應的屬性值)。
三、插件編寫
3.1 源文件說明
從華為資源中心下載編解碼插件Demo,并解壓到本地。文件結構如下圖所示:
源代碼在src文件夾下;編譯生成的插件包在target文件夾下。src 文件夾包含 main 、test 兩個子文件夾,main下存放源碼,test下是單元測試代碼。官網下載的Demo中,源碼的路徑是:src\main\java\com\Huawei\NBIoTDevice\WaterMeter,單元測試代碼的路徑是:src\test\java\com\Huawei\NBIoTDevice\WaterMeter。
插件源碼文件有5個:
(a)ProtocolAdapterImpl.java 可以理解為是插件的入口文件,對外提供調用接口。該文件只需要修改兩個字符串的定義即可:
// 廠商名稱 private static final String MANU_FACTURERID = "Huawei"; // 設備型號 private static final String MODEL = "NBIoTDevice";? 修改為profile當中定義的廠商ID和設備型號。
(b)CmdProcess.java 實現下行命令的編碼工作,將從收到的服務器報文中提取出命令字段對應的內容,并將其轉換成字節流。需要實現的函數是:
public byte[] toByte()(c)ReportProcess.java 實現將收到的二進制碼流按照格式解碼出對應profile中的屬性值,并生成JSON格式。需要實現的函數是:
//根據二進制碼流的格式,從中取出對應字節,轉換成profile中對應屬性的值 public ReportProcess(byte[] binaryData) //將解碼出來的屬性值封裝成JSON格式 public ObjectNode toJsonNode()(d)ByteBufUtils.java 和 Utilty.java文件封裝了一些公共方法,不用做修改。也不會使用到。
3.2 修改文件路徑(包含)
插件包名的要求是:com.廠商名稱.設備型號.設備類型。因此下載下來的代碼,要根據自己的設備修改下文件路徑。即將Huawei文件夾重命名為profile中定義的廠商名稱,NBIoTDevice文件夾重命名為profile中定義的設備型號,WaterMeter文件夾重命名為profile中定義的設備類型。注意:src\main 和src\test 下都要修改。在本例中,需要修改為:
src\main\java\com\ThirdParty\MyModel\MyTyp, src\test\java\com\ThirdParty\MyModel\MyType3.3 修改pom.xml
打開pom.xml文件,修改第7行“artifactId”和第88行“Bundle-SymbolicName”的值為:設備類型-廠商ID-設備型號。在本例中,需要修改為:MyType-ThirdParty-MyModel。
3.4 導入工程
打開eclipse,點擊file->import,在彈出窗口中選擇maven工程,如下圖所示:
之后在彈出的窗口中,點擊Browse,選擇工程路徑(pom.xml文件所在路徑)。工程導入后如下圖所示:
從圖8可以看到首次導入工程后是有錯誤的。這是因為我們在第2節中將文件路徑修改了,與代碼里面的包路徑不一致引起的。解決方法為:依次打開源文件,將第一行的
package com.Huawei.NBIoTDevice.WaterMeter;
修改為
package com.ThirdParty.MyModel.MyType;
打開OSGI_INF目錄下的CodeProvideHandler.xml 文件:
打開后,文件內容如下圖所示:
將Name 、 Class* 內的路徑也修改為對應的包路徑:
3.5 代碼實現
前面說明了各個源文件要修改的地方,本節中具體講解實現的方法。
(a)修改ProtocolAdatpterImpl.java文件
在文件中找到如下兩行:
// 廠商名稱 private static final String MANU_FACTURERID = "Huawei"; // 設備型號 private static final String MODEL = "NBIoTDevice";將MANU_FACTURERID?和 MODEL定義修改為profile中定義的廠商ID和設備型號,本例中需要修改為:
// 廠商名稱 private static final String MANU_FACTURERID = "ThirdParty"; // 設備型號 private static final String MODEL = "MyModel";(b)解碼實現
解碼,是將NB模組上報的二進制碼流按格式解析出對應字段的過程。解碼的代碼在ReportProcess.java 文件中。
第一個函數:public ReportProcess(byte[] binaryData) 入參 byte[] binaryData就是NB模組上報的二進制碼流。解碼得到數據存儲在成員變量當中。本例中的代碼實現如下:
NB上報二進制數據的格式為:前兩個字節表示batteryLevel,大端,整型;第三個字節表示后邊還有多少字節;第四個字節往后表示不定長字段upData。因此,解碼的思路便是:
System.arraycopy 是JDK提供的數組拷貝函數:第一個參數是源數組,第二個參數是偏移,表示從源數組的第幾個字節開始拷貝,第三個參數是目的數組,第四個參數是目的數組的偏移,第5個參數表示拷貝的長度。
第二個函數:public ObjectNode toJsonNode() 返回一個ObjectNode對象(JSON)。該函數的功能,是將解碼后得到的數據,按照規定格式填入一個JSON對象中。本例中,生成的JSON對象的內容格式如下圖所示:
JSON對象的內容格式要求是:"msgType":? "deviceReq",? 表示設備上報數據,固定不動;“data”:數組對象,數組中的每個元素分別對應profile中的一個服務;“serviceID”的值是profile中定義的服務名稱;“serviceData”的值是該服務下所有的屬性值。(本例中,profile定義了兩個服務,Battery服務中有一個BatteryLevel屬性;Transmission服務中有一個upData屬性)。由圖13的“upData”的值可以看出,數組類型的值,需要將二進制流轉成base64編碼的格式。
該函數的代碼實現如下圖所示:
該函數代碼比較簡單,主要是用到了 ObjectMapper 這個類,該類提供了JAVA中操作JSON數據的方法,可對照圖13上報數據格式,仔細理解該部分代碼。
(c)編碼實現
編碼,是將IoT平臺收到的服務器下行數據(服務器下行數據是http或者https協議),從中提取出下行字段,并將其拼成二進制碼流。編碼部分的代碼在 CmdProcess.java 文件中。需要實現的函數是:public byte[] toByte()
本例中,該函數的實現代碼如下圖所示:
服務器下行命令的JSON數據格式是:
"msgType": "cloudReq", 固定值,表示服務器下行命令;
"serviceId",profile中對應的服務,本例中是"Transmission",
"cmd",profile中定義的下行命令,本例中是"CLOUDREQ",
"paras",profile中定義的下行命令的各個字段,本例中是cmdType和downData兩個字段;圖16中,cmdType的值是2,downData是一個不定長數組,base64編碼格式。
因此,編碼的思路是:
3.6 生成jar包
經過前面的工作后,代碼就已經準備好了,接下來是生成JAR包。在DOS窗口中進入pom.xml文件所在路徑,執行 mvn package 命令,最后彈出如下圖所示的結果,則表明生成Jar包成功。如果有錯誤,則根據提示再去修改代碼,然后重新執行 mvn package。
在工程目錄的target文件夾下,存放生成的JAR包“MyType-ThirdParty-MyModel-1.0.0.jar”。JAR包的命名規則是:
設備類型-廠商ID-設備型號-版本號.jar
好,至此插件編寫任務完成。插件打包、插件質檢、插件簽名等內容見下篇教程。
?
?
?
?
總結
以上是生活随笔為你收集整理的华为IoT平台NB编解码插件开发详细教程【上篇】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络技术课程代码02141模拟试题
- 下一篇: 汇编语言程序设计-钱晓捷(第五版)第三章