摘要:使用ModuleSDK開發插件應用,接入其他協議設備(如HTTP請求資料),將其他協議的資料轉化為MQTT協議JSON資料上報到IoTDA,
本文分享自華為云社區《【華為云IoTEdge開發實戰】Java開發如何通過IoT邊緣ModuleSDK進行協議轉換》,作者: 華為IoT云服務 ,
操作場景
使用ModuleSDK開發插件應用,接入其他協議設備(如HTTP請求資料),將其他協議的資料轉化為MQTT協議JSON資料上報到IoTDA,
代碼決議
專案結構如下

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<DeviceService> devices = new LinkedList<>(); for (Device device : modbusCfg.getDevices()) { List<ServiceData> 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.在左側導航中選擇“設備建模”,單擊頁面右上角“創建產品”,
3.填寫引數資訊,如圖所示,單擊“立即創建”,
4.進入產品詳情頁,單擊“自定義模型”,添加“BasicData”服務ID,并“確認”,
5.展開服務串列,依次添加“temp”、“status”兩個屬性,

6.單擊添加命令,添加Control命令名稱,
7.單擊新增下發引數,填寫對應引數,
說明:產品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邊緣單擊創建應用,進入軟體部署配置、運行配置,并確認發布,
2.在左側導航欄,單擊“應用管理”,選擇“應用名稱”進入頁面,查看應用為“已發布”狀態,
部署應用
部署應用,具體請參考部署應用,進入我們的節點詳情頁安裝應用,
添加邊緣設備
1.進入邊緣節點概覽頁,在左側導航中選擇“邊緣設備”,單擊“添加邊緣設備”,
- 所屬產品:選擇設備建模中創建的產品
- 設備標識碼:與代碼示例保持一致
- 設備名稱:與代碼示例保持一致
- 模塊ID: 與部署應用的模塊id保持一致
2.單擊“確認”,添加設備完成,
啟動HTTP服務端,進入設備詳情頁可看到上報的資料,設備狀態顯示未激活,如需更改可參照集成ModuleSDK后,上報資料成功后,設備狀態顯示為未激活,如何上報子設備狀態?

點擊關注,第一時間了解華為云新鮮技術~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/539852.html
標籤:其他
上一篇:一個起點---從零開始寫博客
下一篇:java服裝經銷系統服裝進銷系統
