编解码概述
书写编解码插件之前首先需要书写Profile文件,定义如下。
Profile文件用于描述一款设备的能力特性。IOT平台通过解析Profile文件,获取该设备支持的服务(通信协议里面的一条完整报文)、属性(报文中的一个字段)、命令(报文中的一个字段)等信息。
IOT平台通过编解码插件,对NB设备上报的数据和下发给NB设备的命令进行格式转换,即将设备上报的16进制格式的报文转换成json,json数据的具体属性名称将由Profile文件来确定。
前期准备
知识储备
熟悉javase基础编程,maven项目管理工具基本命令,jackson类库。
开发工具
Eclipse,jdk1.8,maven,NB设备通信协议。
编解码结构解析
Profile结构
Profile文件是一个深度为四级的文件夹如图3‑4所示。
红色方框中为第一级目录,目录名称为当前项目的名称,命名规则为:设备类型-厂商ID-设备型号,例如WellMonitor_Chinastar_CSiTWLM05,对应图3‑4功能结构中的Product模块。
绿色方框中为第二级目录,包含两个文件夹profile和service。profile文件夹下放置一个devicetype-capability.json,被用来描述一款设备的能力特征,包括设备类型、厂商、型号、协议类型以及提供的服务类型。相当于对当前整个Profile项目信息的一个概述。service文件夹下则包含设备具备的服务能力,每个服务具备的属性、命令以及命令的参数,对应图3‑4中Service模块。
蓝色方框中代表三级目录,代表具体的服务,每个服务中又包含了属性和命令,属性用于描述设备上报数据,命令用于下发指令给设备,分别对应图3‑4中的Property模块和Command模块。
此外只有红色与蓝色方框中文件的命名可以改动,其他名称固定不变。
例如图2‑1service中包含了WellWaterCommand代表井盖+水位设备所有的下行命令;WellWaterDeviceInfo代表该设备上报的设备信息;WellWaterTiming代表该设备定时上报的信息,共计三个服务。关于如何根据设备的通信协议划分服务,将在第三章中详细介绍。
media/4e8ad1d840e65bfc32b745a7004fb776.png
图2‑1 Profile文件结构
图2‑2 Profile功能结构
编解码插件结构
编解码插件使用java开发且jdk版本必须为1.8,maven进行项目管理,建议使用eclipse开发工具。其工程目录结构如图3‑4所示。工程的命名建议和Profile项目相同,即采用:设备类型-厂商ID-设备型号的格式。其余包名类名无需更改,即使用华为提供的名称。
其中下行数据编码表示该类将平台下发的json格式的命令转化为字节数组。
上行数据解码则表示该类将设备上报的字节数组转化为json格式数据。
主类则负责调用下行数据编码或者上行数据解码。
工具类中包含了不同数据类型之间转换的方法。
图2‑3 编解码插件工程结构
编解码插件开发
Profile开发
新建工程
新建名称为:设备类型-厂商ID-设备型号的文件夹,例如WellMonitor_Chinastar_CSiTWLM05,打开该文件夹新建profile和service两个子文件夹,如图3‑4所示。注意profile和service这两个文件夹名称是固定不变的。
图3‑1 Profile文件夹
创建概述文件
打开profile文件夹新建devicetype-capability.json文件,编辑该json文件如图3‑4所示。其中每个字段所代表的含义如图3‑4所示。serviceTypeCapabilities
Json数组包含了该Profile文件所有的服务模块,即每增加一个service都需要在这个数组中添加一个对应的json对象。例如Chinstar公司采用CoAP协议,设备型号为CSiTWLM05的井盖设备包含三个服务(功能)模块,井盖命令、井盖开机信息,井盖定时上报信息。
Service划分
关于一个设备service的划分,可以采用根据设备通信协议中上报报文的功能码进行划分的方法,即协议中一条上报报文对应一个service(通常一条报文占用一个功能码)。
Service划分步骤:
将通信协议中的报文区分为上行数据和下行数据两类。
将下行数据(命令)写在一个service里面。
将上行数据根据功能码的不同,分成若干个不同的service。
图3‑2 Profile概述文件
图3‑3 Profile文件字段含义
创建service
打开第二级目录的service文件夹,根据步骤二devicetype-capability.json文件中serviceTypeCapabilities数组中定义的service创建对应的文件夹,文件夹名称为serviceId对应的值。每个文件夹下分别创建profile文件夹,profile文件夹下创建servicetype-capability.json文件,用来描述具体服务的功能,如图3‑4所示。
图3‑4 service文件结构
接下来编写每个service对应的servicetype-capability.json,如图3‑4所示的Profile,将井盖水位设备的所有命令下发模块单独写在了一个service中,即WellWaterCommand模块;将设备的上报数据信息按照通信协议中每个报文的功能码区分为不同的service,即WellWaterDeviceInfo(开机信息)模块与WellWaterTiming(定时上报)模块。
编写下行service
下行命令在service中的书写格式如图3‑5所示。Commands数组里面存放若干个命令对象,每个命令对象包含CommandName命令的名称和paras命令携带的参数数组,以及responses命令回应数组。paras数组里面包含若干个参数对象。参数对象包含paraName等一系列属性。这每一个参数对象都对应通信协议报文中的一个属性。serviceType的值一定要与当前服务文件夹名称保持一致。
图3‑5 命令service
编写上行service
上行属性service比命令service要简单,properties数组中存放的是设备上报上来的数据,每一个json对象对应通信协议报文中的一个属性。propertyName的值可以随意定义,dataType的值如不能根据通信协议中的默认参数值明显的判断该属性的数据类型,应找相关人员确认,否则解析将会出现数据错误。
打包Profile
将WellMonitor_Chinastar_CSiTWLM05文件夹下的profile和service文件打包为zip格式,命名为WellMonitor_Chinastar_CSiTWLM05,并且压缩包内不能包含WellMonitor_Chinastar_CSiTWLM05文件夹这一层目录。
编解码开发
使用eclipse配置本地maven仓库,并导入华为提供的demo工程。
修改pom.xml中的<artifactId>XXX</artifactId>和<Bundle-SymbolicName>XXX</Bundle-SymbolicName>命名规范:设备类型-厂商ID-设备型号,与Profile文件保持一致。如图3‑6、图3‑7所示。
图3‑6 pom修改厂商名称
图3‑7 pom修改厂商名称
修改ProtocolAdapterImpl.java中的厂商名称与设备型号,注意与Profile保持一致。如图3‑8所示。
图3‑8 修改Protocol文件
编写下行编码
数据下行编码流程如图3‑9所示,通过获取OC平台发送过来的json数据,首先根据serviceId将对应数据保存到全局变量中,然后调用toByte方法,将各种类型的数据装换为16进制的比特数组。拼装成一条完整的报文并返回。其中mid为消息序号,根据通信协议中是否使用消息序号来决定代码中是否使用。详情请参照文末样例代码。
图3‑9 数据下行编码流程图
编写上行解码
数据上行解码流程如图3‑10所示。通过获取OC平台发送过来的16进制比特数组格式数据,首先根据比特数组中的功能码(功能码在数据哪个位置,请从通信协议中查看),将不同服务对应的不同数据,根据通信协议将byte类型的属性转换为所需类型,保存到全局变量中,然后调用toJsonNode方法,拼装成一个Json对象并返回。其中mid为消息序号,根据通信协议中是否使用消息序号来决定代码中是否使用。详情请参照文末样例代码。
图3‑10 数据上行解码流程图
打包编解码
打包编解码,即将该maven工程打包成jar文件。检查pom.xml中的<packaging>bundle</packaging>值是否为bundle,不能为jar。以eclipse为例,在工程上右键选择Run
As然后选择Maven build…如图3‑11所示。
图3‑11 Mavenbuild
在Goals中输入clean package点击Run按钮,如图3‑12所示。
图3‑12 Mavenpackage
等待控制台出现BUILD
SUCCESS,即可在当前项目的target目录下找到打包好的jar文件,如图3‑13所示,打包编解码完成。
图3‑13 Build
附录
上行代码。
1 | package com.thrid.party.codec.demo; |
下行数据代码。
1 | package com.thrid.party.codec.demo; |