本文共享自华为云社区《【华为云IoTEdge开发实战】Java开发如何经过IoT边际ModuleSDK进行协议转化》,作者: 华为IoT云服务 。

操作场景

运用ModuleSDK开发插件运用,接入其他协议设备(如HTTP恳求数据),将其他协议的数据转化为MQTT协议JSON数据上签到IoTDA。

代码解析

项目结构如下

Java开发如何通过IoT边缘ModuleSDK进行协议转换

Java开发如何通过IoT边缘ModuleSDK进行协议转换

ModbusDriver代码解析

片段一

经过DriverClient.createFromEnv初始化客户端,调用driverClient来完结数据的发送。

public ModbusDriver() throws GeneraException {

driverClient = DriverClient.createFromEnv();

}

public void start() throws Exception {

//设置回调,打开客户端

driverClient.setGatewayCallback(this);

driverClient.open();

loadConfig();

startCollection();

}

片段二

此为模拟http恳求的代码,随机数模拟设备数采。

private void startCollection() {

scheduler.scheduleAtFixedRate(() -> {

String s = null;

//todo 收集点位数据,保存到points

try {

//1、主动发HTTP恳求收集子设备数据

// s = HttpUtils.doGet(“http://127.0.0.1:8080/module/sdk”, null);

// System.out.println(s);

// Module module = JSON.parseObject(s, Module.class);

//2、模拟设备数采数据

//构造上报参数 设备id.服务id.特点

Module module = new Module();

module.setStatus(String.valueOf(Math.random()));

module.setTemp(String.valueOf(Math.random()));

points.put(“bf40f0c4-4022-41c6-a201-c5133122054a.BasicData.status”, module.getStatus());

points.put(“bf40f0c4-4022-41c6-a201-c5133122054a.BasicData.temp”, module.getTemp());

} catch (Exception exception) {

System.out.println(“http恳求反常”);

}

//上报数据

List devices = new LinkedList<>();

for (Device device : modbusCfg.getDevices()) {

List services = new LinkedList<>();

for (Service service : device.getServices()) {

Map<String, Object> properties = new HashMap<>();

for (Property property : service.getProperties()) {

String key = device.getId() + “.” + service.getServiceId() + “.” + property.getPropertyName();

properties.put(property.getPropertyName(), points.get(key));

}

services.add(new ServiceData(service.getServiceId(), properties, ZonedDateTime.now()));

}

String deviceId = deviceIds.get(device.getId());

if (deviceId != null) {

devices.add(new DeviceService(deviceId, services));

}

}

try {

driverClient.reportSubDevicesProperties(new SubDevicesPropsReport(devices));

} catch (Exception e) {

System.out.println(“上报数据反常” + e.getMessage());

}

}, 0, modbusCfg.getPeriod(), TimeUnit.SECONDS);

}

片段三

检查“modbus.json”文件,点位上报数据联系对应:设备id.模型id.服务id.特点名;设备id需要与增加边际设备时设置的“设备标识码”共同。

{

“period”: 10,

“server”: “10.69.33.154:502”,

“devices”: [{

“id”: “bf40f0c4-4022-41c6-a201-c5133122054a”,

“product_id”: “6247f7e36fe7862a3aa0d803”,

“name”: “TEST1”,

“slave_id”: 1,

“services”: [{

“service_id”: “BasicData”,

“properties”: [{

“property_name”: “status”,

“register_address”: 0,

“data_type”: “string”

},{

“property_name”: “temp”,

“register_address”: 1,

“data_type”: “string”

}]

}]

}]

}

片段四

检查“device_ids.json”文件,设备id需要与增加边际设备时设置的“设备标识码”共同。

{

“bf40f0c4-4022-41c6-a201-c5133122054a”: “bf40f0c4-4022-41c6-a201-c5133122054a”

}

片段五

渠道对布置此运用模块下的设备下发指令后,回调此函数。

@Override

public CommandRsp onDeviceCommandCalled(String requestId, Command command) {

// command json体

//{

// “object_device_id”: “bf40f0c4-4022-41c6-a201-c5133122054a”, 设备id

// “service_id”: “BasicData”, 模型service_id

// “command_name”: “Control”, 指令下发称号

// “paras”: { 指令下发参数

// “State”: “1”

//}

//}

// 呼应示例

return new CommandRsp(200, “supported ok”, null);

}

片段六

渠道对布置此运用模块下的设备的影子特点装备后,回调此函数。

@Override

public IotResult onDevicePropertiesSet(String requestId, PropsSet propsSet) {

//propsSet的json结构体

// {

// “object_device_id”: “bf40f0c4-4022-41c6-a201-c5133122054a”, 设备id

// “services”: [

// {

// “service_id”: “$config”, 模型service_id

// “properties”: {

// “password”: “” 模型特点

// }

// },

// {

// “service_id”: “BasicData”, 模型service_id

// “properties”: { 模型特点

// “status”: “123”,

// “temp”: “123”

// }

// }

//]

// }

// 呼应

return new IotResult(200, “supported”);

}

片段七

子设备收到特点获取的恳求后,调用此函数。

设备接入后,可经过IOTDA供给的接口触发此函数,请参阅IOTDA接口指引。

@Override

public PropsGetRsp onDevicePropertiesGet(String requestId, PropsGet propsGet) {

//propsGet的json结构体

//{

// “objectDeviceId”: “bf40f0c4-4022-41c6-a201-c5133122054a”,

// “serviceId”: “BasicData”

//}

return new PropsGetRsp();

}

片段八

边际设备的影子特点装备后,回调此函数。

@Override

public void onDeviceShadowReceived(String requestId, ShadowGetRsp shadowGetRsp) {

// {

// “objectDeviceId”: “bf40f0c4-4022-41c6-a201-c5133122054a”, 设备id

// “shadow”: [

// {

// “desired”: {

// “eventTime”: “2022-05-07T07:44:53Z[UTC]”,

// “properties”: {

// “status”: “22222222222”, 设备影子希望特点

// “temp”: “11111111111111” 设备影子希望特点

// }

// },

// “reported”: {

// “eventTime”: “2022-05-07T07:34:15Z[UTC]”,

// “properties”: {

// “status”: “1595803812”, 设备上报特点

// “temp”: “-947623559” 设备上报特点

// }

// },

// “serviceId”: “BasicData”, 模型服务id

// “version”: 19

// }

//]

// }

}

片段九

渠道对布置此运用模块下的节点的增加边际设备后,回调此函数。

留意:

布置边际设备的模块id是集成了ModuleSDK运用的模块ID。

@Override

public void onSubDevicesAdded(String eventId, AddSubDevicesEvent addSubDevicesEvent) {

// addSubDevicesEvent的json结构体

// {

// “devices”: [

// {

// “description”: “”, 描绘

// “deviceId”: “bf40f0c4-4022-41c6-a201-c5133122054a”, 设备id

// “extensionInfo”: {

// “module_id”: “user_ot_test” 模块id

// },

// “fwVersion”: “”,

// “name”: “TEST1”,

// “nodeId”: “bf40f0c4-4022-41c6-a201-c5133122054a”, 设备id

// “parentDeviceId”: “720259701929160704”, 父设备id

// “productId”: “6247f7e36fe7862a3aa0d803”, 模型id

// “status”: “INACTIVE”, 状况

// “swVersion”: “”

// }

//],

// “version”: 13

// }

//保存本地设备Id与云端设备Id映射联系

}

片段十

渠道对布置此运用模块下的节点的删除边际设备后,回调此函数。

留意:

布置边际设备的模块id是集成了ModuleSDK运用的模块ID。

@Override

public void onSubDevicesDeleted(String eventId, DeleteSubDevicesEvent deleteSubDevicesEvent) {

// deleteSubDevicesEvent的json结构体

// {

// “devices”: [

// {

// “description”: “”,

// “deviceId”: “bf40f0c4-4022-41c6-a201-c5133122054a”,

// “fwVersion”: “”,

// “name”: “”,

// “nodeId”: “bf40f0c4-4022-41c6-a201-c5133122054a”,

// “parentDeviceId”: “720259701929160704”,

// “productId”: “”,

// “status”: “”,

// “swVersion”: “”

// }

//],

// “version”: 14

// }

}

片段十一

收到获取模型的恳求,调用此函数。

@Override

public void onGetProductsResponse(String eventId, GetProductsRspEvent response) {

//运用 driverClient.getProducts()可获得模型数据

//try {

// GetProductsEvent event = new GetProductsEvent();

//event.setProductIds(Collections.singletonList(“6247f7e36fe7862a3aa0d803”));

// driverClient.getProducts(“12345”, event);

//} catch (JsonException e) {

// log.error(“getProducts exception:” + e);

//}

// response的json结构体

// {

// “products”: [

// {

// “dataFormat”: “json”,

// “description”: “”,

// “deviceType”: “moduleSDK测试“, 模型名字

// “industry”: “”,

// “name”: “moduleSDK测试”,

// “productId”: “6247f7e36fe7862a3aa0d803”, 模型id

// “protocolType”: “MQTT”,

// “serviceCapabilities”: [

// {

// “commands”: [

// {

// “commandName”: “Control”, 指令称号

// “paras”: [ 指令装备

// {

// “dataType”: “string”,

// “max”: “2147483647”,

// “maxLength”: 200,

// “min”: “1”,

// “paraName”: “State”,

// “required”: true,

// “step”: 0.0,

// “unit”: “”

// }

// ]

// }

// ],

// “description”: “”,

// “option”: “Optional”,

// “properties”: [ 特点装备

// {

// “dataType”: “string”,

// “maxLength”: 50,

// “method”: “R”,

// “propertyName”: “temp”,

// “required”: false,

// “step”: 0.0

// },

// {

// “dataType”: “string”,

// “maxLength”: 50,

// “method”: “RW”,

// “propertyName”: “status”,

// “required”: false,

// “step”: 0.0

// }

// ],

// “serviceId”: “BasicData”,

// “serviceType”: “BasicData”

// },

// {

// “description”: “mqtt_config”,

// “option”: “Optional”,

// “properties”: [

// {

// “dataType”: “string”,

// “description”: “mqtt设备接入渠道密码”,

// “max”: “32”,

// “maxLength”: 10240,

// “method”: “RW”,

// “min”: “8”,

// “propertyName”: “password”,

// “required”: false,

// “step”: 0.0

// }

// ],

// “serviceId”: “$config”,

// “serviceType”: “$config”

// }

// ]

// }

//]

// }

}

注册节点

注册节点,请参照注册边际节点。

设备建模

1.访问IoT边际,单击“当即运用”进入IoT边际控制台。

2.在左边导航中挑选“设备建模”,单击页面右上角“创立产品”。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

3.填写参数信息,如图所示,单击“当即创立”。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

4.进入产品详情页,单击“自定义模型”,增加“BasicData”服务ID,并“承认”。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

5.打开服务列表,依次增加“temp”、“status”两个特点。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

Java开发如何通过IoT边缘ModuleSDK进行协议转换

6.单击增加指令,增加Control指令称号。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

7.单击新增下发参数,填写对应参数。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

说明:

产品ID、服务ID、特点称号需要与代码中示例保持共同。

项目打包

打包参阅项目打包

将modbusdriver进行打包得到modbusdriver.jar。

制作镜像包

将jar文件打包成镜像文件上,请参照制作镜像包或插件包。

dockerfile内容参照如下(详细可参阅编写高效的Dockerfile )。

FROM registry-cbu.huawei.com/csopenjdk/openjdk

RUN mkdir -p /opt/iot/edge/monitor / && chmod -R 777 /opt/

COPY monitor /opt/iot/edge/monitor

USER root

EXPOSE 8080

CMD [“java”, “-jar”, “/opt/iot/edge/monitor/monitor-app.jar”, “run”]

#构造镜像

#docker build -t edge_monitor:1.0.0 /home –no-cache

#打标签

#docker tag edge_monitor:1.0.0 swr.cn-north-4.myhuaweicloud.com/iot_edge_test/ot_test:v1

#推送

#docker push swr.cn-north-4.myhuaweicloud.com/iot_edge_test/ot_test:v1

#打成镜像包

#docker save swr.cn-north-4.myhuaweicloud.com/iot_edge_test/ot_test:v1 > ot_test.tar

增加运用

以容器镜像方法为例,镜像包上传到容器镜像服务SWR后,创立运用。

1.在IoT边际单击创立运用,进入软件布置装备、运转装备,并承认发布。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

2.在左边导航栏,单击“运用办理”,挑选“运用称号”进入页面,检查运用为“已发布”状况。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

布置运用

布置运用,详细请参阅布置运用,进入咱们的节点详情页装置运用。

Java开发如何通过IoT边缘ModuleSDK进行协议转换

增加边际设备

1.进入边际节点概览页,在左边导航中挑选“边际设备”,单击“增加边际设备”。

  • 所属产品:挑选设备建模中创立的产品
  • 设备标识码:与代码示例保持共同
  • 设备称号:与代码示例保持共同
  • 模块ID: 与布置运用的模块id保持共同

Java开发如何通过IoT边缘ModuleSDK进行协议转换

2.单击“承认”,增加设备完结。

启动HTTP服务端,进入设备详情页可看到上报的数据。设备状况显现未激活。如需更改可参照集成ModuleSDK后,上报数据成功后,设备状况显现为未激活,如何上报子设备状况?

Java开发如何通过IoT边缘ModuleSDK进行协议转换

Java开发如何通过IoT边缘ModuleSDK进行协议转换

点击重视,第一时间了解华为云新鲜技能~