物模型通信场景迁移实践
本文以第三方云智慧路灯设备迁移到华为云IoT为例,介绍如何进行物模型场景的设备迁移。
业务场景说明
假设路灯设备上报一条光照强度(luminance)消息;支持远程控制路灯开关状态的命令(switch)。
业务场景 |
物模型样例 |
---|---|
设备属性上报数据 |
{ "service_id": "BasicData", "properties": { "luminance": 30 } } |
服务端控制指令 |
{ "command_name": "switch", "service_id": "LightControl", "paras": { "value": "ON" } } |
- 设备使用一机一密的认证方式。
- 设备集成了第三方云SDK,采用物模型通信进行属性上报。
- 服务端集成了第三方云SDK,进行指令下发。
迁移方案说明
物模型通通信场景的迁移方案分为下面三个步骤:
-
在控制台进行存量设备信息、物模型数据的迁移和配置数据流转规则,请参见平台端配置开发。
-
设备端集成华为云SDK,请参见设备端集成华为云SDK。
-
应用端集成华为云SDK进行业务开发,实现接收设备数据和下发控制指令,请参见服务端集成华为云SDK。
平台端配置开发
- 存量设备信息迁移。
- 选择左侧导航栏的“创建同步任务”。 ,单击页面右侧的
- 参考下表填写参数后,单击“确定”。
表2 同步任务参数说明 参数名
配置说明
同步平台类型
选择“第三方物联网平台”。
第三方平台接入凭证
添加第三方平台接入凭证。
源平台所在区域
第三方物联网平台平台所在区域。
源平台实例
第三方物联网平台平台所属实例,有多个实例时需要填写。
目标平台所在区域
选择“北京四”。
目标平台实例
选择设备需要同步的目标平台所在实例。
同步方式
选择“按资源空间整体”。
所属产品
选择设备所属的产品。
- 完成设备数据同步配置后,会自动进行设备数据同步。
- 配置数据转发规则。
- 参考配置AMQP服务端订阅,配置AMQP订阅。配置参数如下:
表3 AMQP订阅参数说明 参数值
配置说明
规则名称
填写为“MyRule”。
规则描述
填写为“RuleTest”。
数据来源
选择“设备属性”。
触发事件
选择“设备属性上报”。
资源空间
选择对应资源空间。
- 添加到AMQP推送消息队列目标,配置参数如下:
表4 参数说明 参数名
配置说明
转发目标
选择“AMQP推送消息队列”。
消息队列
选择“DefaultQueue”。
- 参考配置AMQP服务端订阅,配置AMQP订阅。配置参数如下:
设备端集成华为云SDK
设备端可以通过集成华为云IoT提供的设备端SDK,快速连接华为云IoT,进行命令的接收和属性上报。
- 配置设备侧SDK,配置连接参数,并进行命令的监听。
//加载iot平台的ca证书,获取连接参考:https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section3 URL resource = MessageSample.class.getClassLoader().getResource("ca.jks"); File file = new File(resource.getPath()); //域名获取方式:登录华为云IoTDA控制台左侧导航栏“总览”页签,在选择的实例基本信息中,单击“接入信息”。选择8883端口对应的接入域名。 String serverUrl = "ssl://******.st1.iotda-device.cn-north-4.myhuaweicloud.com:8883"; //在IoT平台创建的设备ID。 String deviceId = "deviceId"; //设备ID对应的密钥。 String deviceSecret = "******"; //创建设备 IoTDevice device = new IoTDevice(serverUrl, deviceId, deviceSecret, file); if (device.init() != 0) { return; } //设置命令下发回调函数、发送响应。 client.setCommandListener(new CommandListener() { @Override public void onCommand(String requestId, String serviceId, String commandName, Map<String, Object> paras) { log.info("onCommand, serviceId = " +serviceId); log.info("onCommand , name = " + commandName); log.info("onCommand, paras = " + paras.toString()); //处理命令用户自定义 //发送命令响应 device.getClient().respondCommand(requestId, new CommandRsp(0)); } });
- 上报设备属性。
Map<String ,Object> json = new HashMap<>(); Random rand = new Random(); //按照物模型设置属性 json.put("luminance", 30); ServiceProperty serviceProperty = new ServiceProperty(); serviceProperty.setProperties(json); serviceProperty.setServiceId("BasicData");//serviceId要和物模型一致 device.getClient().reportProperties(Arrays.asList(serviceProperty), new ActionListener() { @Override public void onSuccess(Object context) { log.info("reportProperties success" ); } @Override public void onFailure(Object context, Throwable var2) { log.error("reportProperties failed" + var2.toString()); } });
服务端集成华为云SDK
华为云IoTDA提供应用端SDK,开发者只需做少量代码修改就可完成应用端适配,实现应用端的快速迁移。下面以应用端接收设备属性上报和应用端下发命令给设备为例,介绍如何进行应用端适配。
- 参考AMQP客户端接入说明,Java SDK接入示例进行设备属性上报的适配处理。
try { MessageConsumer consumer = amqpClient.newConsumer(AmqpConstants.DEFAULT_QUEUE); consumer.setMessageListener(message -> { try { // 此处进行消息处理。如果处理比较耗时,最好进行开启新的线程处理,否则可能造成心跳超时链接断开。 processMessage(message.getBody(String.class)); // 如果options.isAutoAcknowledge==false,此处应该调用message.acknowledge(); } catch (Exception e) { log.warn("message.getBody error,exception is ", e); } }); } catch (Exception e) { log.warn("Consumer initialize error,", e); }
- 参考命令下发使用示例 ,下发设备命令。服务端向单个设备下发命令样例如下:
public class MessageDistributionSolution { .................. DeviceCommandRequest body = new DeviceCommandRequest(); body.commandName("switch"); body.serviceId("LightControl"); body.withParas({"value": "ON"}); request.withBody(body); try { CreateMessageResponse response = client.createMessage(request); System.out.println(response.toString()); } catch (ConnectionException e) { e.printStackTrace(); } catch (RequestTimeoutException e) { e.printStackTrace(); } catch (ServiceResponseException e) { e.printStackTrace(); System.out.println(e.getHttpStatusCode()); System.out.println(e.getRequestId()); System.out.println(e.getErrorCode()); System.out.println(e.getErrorMsg()); } } }