更新时间:2024-06-11 GMT+08:00

属性下发

概述

属性下发分为查询设备属性和修改属性参数两种,查询设备属性用于应用侧或平台主动获取设备属性数据,修改属性参数用于应用侧或平台设置设备属性值并同步到设备侧。设备接收到属性下发指令后需要立即响应,如果设备没有响应,平台会认为命令执行超时。

使用场景

  • 用于平台主动获取或修改设备属性值。
  • 进行平台规范、解析、过滤的数据。

使用限制

  • 单个消息内容不大于64K。
  • 需要定义产品模型

属性下发使用说明

属性下发分为修改属性与获取属性值,下列以修改属性为例,介绍属性下发。

图1 属性下发流程图
  1. 应用调用修改设备属性接口,下发请求到物联网平台,属性下发消息样例如下:
    PUT https://{endpoint}/v5/iot/{project_id}/devices/{device_id}/properties  
    {   
        "services" : [ {     
            "service_id" : "Temperature",     
            "properties" : {
                "value" : 57     
            }  
         }, {     
            "service_id" : "Battery",     
            "properties" : { 
                "level" : 80     
            }   
        } ] 
    }
  2. 物联网平台根据协议规范下发属性给设备。通过MQTT协议中平台设置设备属性接口下发属性为样例:
    Topic: $oc/devices/{device_id}/sys/properties/set/request_id={request_id}  
    数据格式:   
    {
        "object_device_id": "{object_device_id} ",
        "services": [
            {
                "service_id": "Temperature",
                "properties": {
                    "value": 57,
                    "value2": 60
                }
            },
            {
                "service_id": "Battery",
                "properties": {
                    "level": 80,
                    "level2": 90
                }
            }
        ]
    }
  3. 设备执行属性下发命令后返回命令执行结果,消息样例如下:
    Topic:$oc/devices/{device_id}/sys/properties/set/response/request_id={request_id} 
    数据格式:
    {
        "result_code": 0,
        "result_desc": "success"
    }
  4. 应用侧收到发送HTTP下发命令的同步响应结果。消息样例如下:
    Status Code: 200 OK
    Content-Type: application/json
    {   
        "response" : {     
            "result_code" : 0,     
            "result_desc" : "success"   
        } 
    }

属性下发Java SDK使用示例

本部分介绍如何使用JAVA SDK进行属性配置的开发。SDK代码获取:SDK下载。本示例使用的开发环境为JDK 1.8及以上版本。

配置应用侧SDK步骤如下:

  1. 配置Maven依赖。

    <dependency>
        <groupId>com.huaweicloud.sdk</groupId>
        <artifactId>huaweicloud-sdk-core</artifactId>
        <version>[3.0.40-rc, 3.2.0)</version>
    </dependency>
    <dependency>
        <groupId>com.huaweicloud.sdk</groupId>
        <artifactId>huaweicloud-sdk-iotda</artifactId>
        <version>[3.0.40-rc, 3.2.0)</version>
    </dependency>

  2. 应用侧设置某个设备的属性值,样例如下:

    public class AttributeDistributionSolution {
        // REGION_ID:如果是上海一,请填写"cn-east-3";如果是北京四,请填写"cn-north-4";如果是华南广州,请填写"cn-south-4"
        private static final String REGION_ID = "<YOUR REGION ID>";
        // ENDPOINT:请在控制台的"总览"界面的"平台接入地址"中查看“应用侧”的https接入地址。
        private static final String ENDPOINT = "<YOUR ENDPOINT>";
        // 标准版/企业版:需自行创建Region对象
        public static final Region REGION_CN_NORTH_4 = new Region(REGION_ID, ENDPOINT);
        public static void main(String[] args) {
            String ak = "<YOUR AK>";
            String sk = "<YOUR SK>";
            String projectId = "<YOUR PROJECTID>";
            // 创建认证
            ICredential auth = new BasicCredentials().withDerivedPredicate(AbstractCredentials.DEFAULT_DERIVED_PREDICATE)
                .withAk(ak)
                .withSk(sk)
                .withProjectId(projectId);
            // 创建IoTDAClient实例并初始化
            IoTDAClient client = IoTDAClient.newBuilder().withCredential(auth)
                // 基础版:请选择IoTDARegion中的Region对象
                //.withRegion(IoTDARegion.CN_NORTH_4)
                // 标准版/企业版:需自行创建Region对象
                .withRegion(REGION_CN_NORTH_4).build();
            // 实例化请求对象
            UpdatePropertiesRequest request = new UpdatePropertiesRequest();
            request.withDeviceId("<YOUR DEVICE_ID>");
            DevicePropertiesRequest body = new DevicePropertiesRequest();
            body.withServices("[{\"service_id\":\"smokeDetector\",\"properties\":{\"alarm\":\"hello\"," +
                    "\"temperature\":10.323,\"humidity\":654.32,\"smokeConcentration\":342.4}}]");
            request.withBody(body);
            try {
                UpdatePropertiesResponse response = client.updateProperties(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());
            }
        }
    }
    表1 参数说明

    参数

    说明

    ak

    您的华为云账号访问密钥ID(Access Key ID)。请在华为云控制台我的凭证 > 访问密钥页面上创建和查看您的 AK/SK。更多信息请查看访问密钥

    sk

    您的华为云账号秘密访问密钥(Secret Access Key)。

    projectId

    项目ID。获取方法请参见 获取项目ID

    IoTDARegion.CN_NORTH_4

    请替换为您要访问的物联网平台的区域,当前物联网平台可以访问的区域,在SDK代码IoTDARegion.java中已经定义。

    您可以在控制台上查看当前服务所在区域名称,区域名称、区域和终端节点的对应关系,具体步骤请参考平台对接信息

    REGION_ID

    如果是上海一,请填写“cn-east-3”;如果是北京四,请填写“cn-north-4”;如果是华南广州,请填写“cn-south-4”。

    ENDPOINT

    请在控制台的总览界面的“接入信息”中查看“应用接入”的https接入地址。

    DEVICE_ID

    下发消息的设备ID,用于唯一标识一个设备,在注册设备时由物联网平台分配获得。 取值范围:长度不超过128,只允许字母、数字、下划线(_)、连接符(-)的组合。

配置设备侧SDK步骤如下:

  1. 配置设备侧SDK的Maven依赖。

    <dependency>
    	<groupId>com.huaweicloud</groupId>
    	<artifactId>iot-device-sdk-java</artifactId>
    	<version>1.1.4</version>
    </dependency>

  2. 配置设备侧SDK,设备连接参数。

    //加载iot平台的ca证书,获取连接参考:https://support.huaweicloud.com/devg-iothub/iot_02_1004.html#section3
    URL resource = AttributeSample.class.getClassLoader().getResource("ca.jks");
    File file = new File(resource.getPath());
    
    //注意格式为:ssl://域名信息:端口号。
    //域名获取方式:登录华为云IoTDA控制台左侧导航栏“总览”页签,在选择的实例基本信息中,单击“接入信息”。选择8883端口对应的接入域名。
    String serverUrl = "ssl://localhost:8883";
    //在IoT平台创建的设备ID。
    String deviceId = "deviceId";
    //设备ID对应的密钥。
    String deviceSecret = "secret";
    //创建设备
    IoTDevice device = new IoTDevice(serverUrl, deviceId, deviceSecret, file);
    if (device.init() != 0) {
        return;
    }

  3. 定义属性下发回调函数。

    device.getClient().setPropertyListener(new PropertyListener() {
    
        //处理写属性
        @Override
        public void onPropertiesSet(String requestId, List<ServiceProperty> services) {
    
            //遍历service
            for (ServiceProperty serviceProperty: services){
    
                log.info("OnPropertiesSet, serviceId =  " + serviceProperty.getServiceId());
    
                //遍历属性
                for (String name :serviceProperty.getProperties().keySet()){
                    log.info("property name = "+ name);
                    log.info("set property value = "+ serviceProperty.getProperties().get(name));
                    if (name.equals("alarm")){
                        //修改本地值
                        alarm = (Integer) serviceProperty.getProperties().get(name);
                    }
                }
    
            }
            //设置属性响应
            device.getClient().respondPropsSet(requestId, IotResult.SUCCESS);
        }
    
        //处理读属性
        @Override
        public void onPropertiesGet(String requestId, String serviceId) {
            log.info("OnPropertiesGet " + serviceId);
            Map<String ,Object> json = new HashMap<>();
            Random rand = new Random();
            json.put("alarm", alarm);
            json.put("temperature", rand.nextFloat()*100.0f);
            json.put("humidity", rand.nextFloat()*100.0f);
            json.put("smokeConcentration", rand.nextFloat() * 100.0f);
    
            ServiceProperty serviceProperty = new ServiceProperty();
            serviceProperty.setProperties(json);
            serviceProperty.setServiceId("smokeDetector");
            
            //上报读属性响应
            device.getClient().respondPropsGet(requestId, Arrays.asList(serviceProperty));
        }
    });

测试验证步骤如下:

  1. 在设备接入控制台,进入设备 > 所有设备,单击具体设备,启动消息跟踪
  2. 运行设备侧 SDK代码,使设备上线。
  3. 运行应用侧SDK代码,调用修改设备属性接口向设备发送请求,设备侧收到的结果如下:

    图2 处理修改属性设备侧结果

  4. 消息跟踪显示结果如下:

    图3 属性下发在消息跟踪中查看