You can set desired property values in IoT Platform to control device properties. This article describes how to set a desired property value in IoT Platform to control the bulb status.

Background information

After a bulb device is connected to IoT Platform, you must keep the bulb online all the time to control the bulb status. The bulb status in IoT Platform includes On (1) and Off (0). However, the bulb may not be online all the time in production environment.

You can set and store the desired property value of the bulb in IoT Platform. After the device goes online, it can read the desired property value that is stored in IoT Platform and update the property value. Then, the updated property value is submitted to IoT Platform and displayed in the IoT Platform device status.

Create a product and a device

  1. Log on to the IoT Platform console.
  2. In the left-side navigation pane, choose Devices > Products. On the Products page, click Create Product to create a bulb product.
    Create a product
  3. After you create the product, click Create TSL to add Thing Specification Language (TSL) features to the product and publish the TSL model. For more information, see Add a TSL feature.
    In this example, add the LightStatus property. TSL model
  4. In the left-side navigation pane, choose Devices > Devices, and click Add Device to add the Lamp device to the product.
    Add a device
    After you add the device, obtain the certificate information of the device. The certificate information includes the ProductKey, DeviceName, and DeviceSecret.

    In the device list, click View to go to the Device Details page. You can view the device property value and desired property value on the Status tab. In this example, both the values are empty. The version of the desired property value is 0.

    Initial status

Set and query the desired property value in IoT Platform

You can set and query the latest desired property values of a device in IoT Platform by calling API operations.

For more information, see API operations. In this example, IoT Platform SDK for Java is used.

  • Call the SetDeviceDesiredProperty operation to set desired property values of the device.
    DefaultProfile profile = DefaultProfile.getProfile(
            "<RegionId>", // The region ID.
            "<accessKey>", // The AccessKey ID of the Alibaba Cloud account.
            "<accessSecret>"); // The AccessKey secret of Alibaba Cloud account.
    IAcsClient client = new DefaultAcsClient(profile);
    
    // Create an API request and set the parameters.
    SetDeviceDesiredPropertyRequest request = new SetDeviceDesiredPropertyRequest();
    request.setIotInstanceId("iot-060***");
    request.setDeviceName("Lamp");
    request.setProductKey("g4r***");
    //The identifiers and desired values of the properties that you want to set.
    request.setItems("{\"LightStatus\": 1}");
    request.setVersions("{\"LightStatus\": 0}");
    
    // Send the request and handle the response or exception.
    try {
        SetDeviceDesiredPropertyResponse response = client.getAcsResponse(request);
        System.out.println(new Gson().toJson(response));
    } catch (ServerException e) {
        e.printStackTrace();
    } catch (ClientException e) {
        System.out.println("ErrCode:" + e.getErrCode());
        System.out.println("ErrMsg:" + e.getErrMsg());
        System.out.println("RequestId:" + e.getRequestId());
    }
  • Call the QueryDeviceDesiredProperty operation to query the desired property values of the device.
    DefaultProfile profile = DefaultProfile.getProfile(
            "<RegionId>", // The region ID.
            "<accessKey>", // The AccessKey ID of the Alibaba Cloud account.
            "<accessSecret>"); // The AccessKey secret of Alibaba Cloud account.
    IAcsClient client = new DefaultAcsClient(profile);
    
    // Create an API request and set the parameters.
    QueryDeviceDesiredPropertyRequest request = new QueryDeviceDesiredPropertyRequest();
    request.setIotInstanceId("iot-060a02fq");
    request.setProductKey("g4rmjb5q40O");
    request.setDeviceName("Lamp");
    // The identifiers of the properties that you want to query. If you do not specify a property identifier, the desired values of all properties except the read-only properties are queried.
    List<String> identifierList = new ArrayList<String>();
    identifierList.add("LightStatus");
    request.setIdentifiers(identifierList);
    
    // Send the request and handle the response or exception.
    try {
        QueryDeviceDesiredPropertyResponse response = client.getAcsResponse(request);
        System.out.println(new Gson().toJson(response));
    } catch (ServerException e) {
        e.printStackTrace();
    } catch (ClientException e) {
        System.out.println("ErrCode:" + e.getErrCode());
        System.out.println("ErrMsg:" + e.getErrMsg());
        System.out.println("RequestId:" + e.getRequestId());
    }

For more information about how to set the parameters in the code, see Use IoT Platform SDK for Java.

After you set the desired property value of the Lamp device, the value is displayed on the Status tab in IoT Platform.

Develop the device

The bulb device can obtain desired property values in the following scenarios:

  • If the bulb device goes from offline to online, it requests the desired property value that is cached in IoT Platform.
  • If the bulb device is online, it receives the desired property value that is pushed by IoT Platform in real time.

For more information, see Download device SDKs.

This article provides complete device-side sample code. For more information, see Appendix: Sample code to configure a device.

  1. Specify the certificate information and region ID of the device.
    /**
    * The certificate information about the device.
    */
    private static String productKey = "******";
    private static String deviceName = "********";
    private static String deviceSecret = "**************";
    /**
    * The MQTT connection information.
    */
    private static String regionId = "******";
    Note
    • For more information about the device certificate, see Create a product and a device.
    • regionId specifies the ID of the region where your service resides. You can view the region in the upper-left corner of the IoT Platform console. For more information about region IDs, see Regions and zones.
  2. Add the following methods. These methods can be used to change the actual property values of the bulb and automatically report the changes to IoT Platform.
    /**
     * When the device handles a property value change, the methods are called in the following scenarios:
     * Scenario 1. Pull mode: After the device is connected to IoT Platform again, the device automatically requests the latest desired property value from IoT Platform.
     * Scenario 2. Push mode: When the device is online, it receives the desired property values that IoT Platform pushes to the property.set topic.
     * @param identifier: the property identifier.
     * @param value: the desired property value.
     * @param needReport: specifies whether to report the property value to IoT Platform by using the property.post topic.
     * In Scenario 2, the property report capability is integrated into the processing function and the needReport parameter is set to false.
     * @return
     */
    private boolean handlePropertySet(String identifier, ValueWrapper value, boolean needReport) {
        ALog.d(TAG, "The device handles property changes= [" + identifier + "], value = [" + value + "]");
        // Check whether the property settings are successful based on the response. In this example, a success message is returned.
        boolean success = true;
        if (needReport) {
            reportProperty(identifier, value);
        }
        return success;
    }
    
    private void reportProperty(String identifier, ValueWrapper value){
        if (StringUtils.isEmptyString(identifier) || value == null) {
            return;
        }
    
        ALog.d(TAG, "Report property identity=" + identifier);
    
        Map<String, ValueWrapper> reportData = new HashMap<>();
        reportData.put(identifier, value);
        LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {
    
            public void onSuccess(String s, Object o) {
                // The property value is reported.
                ALog.d(TAG, "Report success onSuccess() called with: s = [" + s + "], o = [" + o + "]");
            }
    
            public void onError(String s, AError aError) {
                // The property value fails to be reported.
                ALog.d(TAG, "Report failure onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]");
            }
        });
    }
  3. If the bulb is online and a desired property value is set for the bulb in IoT Platform, IoT Platform pushes the value to the bulb. The bulb processes the message and changes the status.

    In the following code, the connectNotifyListener() method is called to process the message. For information about the Alink protocol, see Report device properties.

    After the device receives an asynchronous message from IoT Platform, the device calls the mCommonHandler() method and then the handlePropertySet method to update the property value.

    /**
     * Register a function to respond to service calls and property settings.
     * When IoT Platform calls a service from the device, the device must respond to the call and return a response.
     */
    public void connectNotifyListener() {
        List<Service> serviceList = LinkKit.getInstance().getDeviceThing().getServices();
        for (int i = 0; serviceList != null && i < serviceList.size(); i++) {
            Service service = serviceList.get(i);
            LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
        }
    }
    
    private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
        public void onProcess(String serviceIdentifier, Object result, ITResResponseCallback itResResponseCallback) {
            ALog.d(TAG, "onProcess() called with: s = [" + serviceIdentifier + "]," +
                    " o = [" + result + "], itResResponseCallback = [" + itResResponseCallback + "]");
            ALog.d(TAG, "Received an asynchronous service call from IoT Platform " + serviceIdentifier);
            try {
                if (SERVICE_SET.equals(serviceIdentifier)) {
                    Map<String, ValueWrapper> data = (Map<String, ValueWrapper>)((InputParams)result).getData();
                    ALog.d(TAG, "Received asynchronous downstream data " + data);
                    //Set the property of the device and then report the property value to IoT Platform.
                    boolean isSetPropertySuccess =
                            handlePropertySet("LightStatus", data.get("LightStatus"), false);
                    if (isSetPropertySuccess) {
                        if (result instanceof InputParams) {
                            // Return a response to IoT Platform.
                            itResResponseCallback.onComplete(serviceIdentifier, null, null);
                        } else {
                            itResResponseCallback.onComplete(serviceIdentifier, null, null);
                        }
                    } else {
                        AError error = new AError();
                        error.setCode(100);
                        error.setMsg("setPropertyFailed.");
                        itResResponseCallback.onComplete(serviceIdentifier, new ErrorInfo(error), null);
                    }
                } else if (SERVICE_GET.equals(serviceIdentifier)) {
                } else {
                    // The device operation varies by service.
                    ALog.d(TAG, "Return a response to IoT Platform.");
                    OutputParams outputParams = new OutputParams();
                    // outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                    itResResponseCallback.onComplete(serviceIdentifier, null, outputParams);
                }
            } catch (Exception e) {
                e.printStackTrace();
                ALog.d(TAG, "The format of the returned data is invalid");
            }
        }
    
        public void onSuccess(Object o, OutputParams outputParams) {
            ALog.d(TAG, "onSuccess() called with: o = [" + o + "], outputParams = [" + outputParams + "]");
            ALog.d(TAG, "The service was registered");
        }
    
        public void onFail(Object o, ErrorInfo errorInfo) {
            ALog.d(TAG, "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
            ALog.d(TAG, "Service registration failed.");
        }
    };
  4. If the bulb is offline and a desired property value is set for the bulb in IoT Platform, the value is stored in IoT Platform.

    After the bulb goes online, it requests the desired property value from IoT Platform and call the handlePropertySet() method to update the property value.

    LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
        public void onError(AError aError) {
            ALog.e(TAG, "Init Error error=" + aError);
        }
        public void onInitDone(InitResult initResult) {
            ALog.i(TAG, "onInitDone result=" + initResult);
    
            connectNotifyListener();
    
            // Request the latest desired property value from IoT Platform.
            getDesiredProperty(deviceInfo, Arrays.asList("LightStatus"), new IConnectSendListener() {
                public void onResponse(ARequest aRequest, AResponse aResponse) {
                    if(aRequest instanceof MqttPublishRequest && aResponse.data != null) {
                        JSONObject jsonObject = JSONObject.parseObject(aResponse.data.toString());
                        ALog.i(TAG, "onResponse result=" + jsonObject);
                        JSONObject dataObj = jsonObject.getJSONObject("data");
                        if (dataObj != null) {
                            if (dataObj.getJSONObject("LightStatus") == null) {
                                // No desired value is set.
                            } else {
                                Integer value = dataObj.getJSONObject("LightStatus").getInteger("value");
                                handlePropertySet("LightStatus", new ValueWrapper.IntValueWrapper(value), true);
                            }
                        }
                    }
                }
                public void onFailure(ARequest aRequest, AError aError) {
                    ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
                }
            });
        }
    });
    
    private void getDesiredProperty(BaseInfo info, List<String> properties, IConnectSendListener listener) {
        ALog.d(TAG, "getDesiredProperty() called with: info = [" + info + "], listener = [" + listener + "]");
        if(info != null && !StringUtils.isEmptyString(info.productKey) && !StringUtils.isEmptyString(info.deviceName)) {
            MqttPublishRequest request = new MqttPublishRequest();
            request.topic = DESIRED_PROPERTY_GET.replace("{productKey}", info.productKey).replace("{deviceName}", info.deviceName);
            request.replyTopic = DESIRED_PROPERTY_GET_REPLY.replace("{productKey}", info.productKey).replace("{deviceName}", info.deviceName);
            request.isRPC = true;
            RequestModel<List<String>> model = new RequestModel<>();
            model.id = String.valueOf(IDGeneraterUtils.getId());
            model.method = METHOD_GET_DESIRED_PROPERTY;
            model.params = properties;
            model.version = "1.0";
            request.payloadObj = model.toString();
            ALog.d(TAG, "getDesiredProperty: payloadObj=" + request.payloadObj);
            ConnectSDK.getInstance().send(request, listener);
        } else {
            ALog.w(TAG, "getDesiredProperty failed, baseInfo Empty.");
            if(listener != null) {
                AError error = new AError();
                error.setMsg("BaseInfoEmpty.");
                listener.onFailure(null, error);
            }
        }
    }

Verify the result

Run the sample code based on scenarios to verify the online and offline status of the bulb. You can change the device property value by setting the desired property value in IoT Platform.

  • If the bulb is online, you can change the bulb status in IoT Platform. The bulb responds to the change in real time. Online update
  • If the bulb is offline, you can also change the bulb status in IoT Platform. In this case, the desired property value in IoT Platform and the latest device property value are different. Offline update
  • If the bulb goes from offline to online, it requests the desired property value. The latest property value is immediately synchronized to the desired value. Reconnection and update

Appendix: Sample code to configure a device

package com.aliyun.alink.devicesdk.demo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.alink.apiclient.utils.StringUtils;
import com.aliyun.alink.dm.api.BaseInfo;
import com.aliyun.alink.dm.api.DeviceInfo;
import com.aliyun.alink.dm.api.InitResult;
import com.aliyun.alink.dm.model.RequestModel;
import com.aliyun.alink.dm.utils.IDGeneraterUtils;
import com.aliyun.alink.linkkit.api.ILinkKitConnectListener;
import com.aliyun.alink.linkkit.api.IoTMqttClientConfig;
import com.aliyun.alink.linkkit.api.LinkKit;
import com.aliyun.alink.linkkit.api.LinkKitInitParams;
import com.aliyun.alink.linksdk.cmp.api.ConnectSDK;
import com.aliyun.alink.linksdk.cmp.connect.channel.MqttPublishRequest;
import com.aliyun.alink.linksdk.cmp.core.base.ARequest;
import com.aliyun.alink.linksdk.cmp.core.base.AResponse;
import com.aliyun.alink.linksdk.cmp.core.listener.IConnectSendListener;
import com.aliyun.alink.linksdk.tmp.api.InputParams;
import com.aliyun.alink.linksdk.tmp.api.OutputParams;
import com.aliyun.alink.linksdk.tmp.device.payload.ValueWrapper;
import com.aliyun.alink.linksdk.tmp.devicemodel.Service;
import com.aliyun.alink.linksdk.tmp.listener.IPublishResourceListener;
import com.aliyun.alink.linksdk.tmp.listener.ITResRequestHandler;
import com.aliyun.alink.linksdk.tmp.listener.ITResResponseCallback;
import com.aliyun.alink.linksdk.tmp.utils.ErrorInfo;
import com.aliyun.alink.linksdk.tools.AError;
import com.aliyun.alink.linksdk.tools.ALog;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LampDemo {
    private static final String TAG = "LampDemo";

    private final static String SERVICE_SET = "set";
    private final static String SERVICE_GET = "get";

    public static String DESIRED_PROPERTY_GET = "/sys/{productKey}/{deviceName}/thing/property/desired/get";
    public static String DESIRED_PROPERTY_GET_REPLY = "/sys/{productKey}/{deviceName}/thing/property/desired/get_reply";
    public static String METHOD_GET_DESIRED_PROPERTY = "thing.property.desired.get";

    public static void main(String[] args) {
        /**
         * The certificate information about the device.
         */
        String productKey = "****";
        String deviceName = "Lamp";
        String deviceSecret = "****";
        /**
         * The MQTT connection information.
         */
        String regionId = "cn-shanghai";

        LampDemo manager = new LampDemo();

        DeviceInfo deviceInfo = new DeviceInfo();
        deviceInfo.productKey = productKey;
        deviceInfo.deviceName = deviceName;
        deviceInfo.deviceSecret = deviceSecret;

        manager.init(deviceInfo, regionId);
    }

    public void init(final DeviceInfo deviceInfo, String region) {
        LinkKitInitParams params = new LinkKitInitParams();
        /**
         * Specify the parameters for MQTT initialization.
         */
        IoTMqttClientConfig config = new IoTMqttClientConfig();
        config.productKey = deviceInfo.productKey;
        config.deviceName = deviceInfo.deviceName;
        config.deviceSecret = deviceInfo.deviceSecret;
        config.channelHost = deviceInfo.productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
        /**
         * Specify whether to receive offline messages.
         * The cleanSession field that corresponds to the MQTT connection.
         */
        config.receiveOfflineMsg = false;
        params.mqttClientConfig = config;

        /**
         * Configure the initialization and pass in the certificate information about the device.
         */
        params.deviceInfo = deviceInfo;

        LinkKit.getInstance().init(params, new ILinkKitConnectListener() {
            public void onError(AError aError) {
                ALog.e(TAG, "Init Error error=" + aError);
            }
            public void onInitDone(InitResult initResult) {
                ALog.i(TAG, "onInitDone result=" + initResult);

                connectNotifyListener();

                // Request the latest desired property value from IoT Platform.
                getDesiredProperty(deviceInfo, Arrays.asList("LightStatus"), new IConnectSendListener() {
                    public void onResponse(ARequest aRequest, AResponse aResponse) {
                        if(aRequest instanceof MqttPublishRequest && aResponse.data != null) {
                            JSONObject jsonObject = JSONObject.parseObject(aResponse.data.toString());
                            ALog.i(TAG, "onResponse result=" + jsonObject);
                            JSONObject dataObj = jsonObject.getJSONObject("data");
                            if (dataObj != null) {
                                if (dataObj.getJSONObject("LightStatus") == null) {
                                    // No desired value is set.
                                } else {
                                    Integer value = dataObj.getJSONObject("LightStatus").getInteger("value");
                                    handlePropertySet("LightStatus", new ValueWrapper.IntValueWrapper(value), true);
                                }
                            }
                        }
                    }
                    public void onFailure(ARequest aRequest, AError aError) {
                        ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
                    }
                });
            }
        });
    }

    /**
     * When the device handles a property value change, the methods are called in the following scenarios:
     * Scenario 1. Pull mode: After the device is connected to IoT Platform again, the device automatically requests the latest desired property value from IoT Platform.
     * Scenario 2. Push mode: When the device is online, it receives the desired property values that IoT Platform pushes to the property.set topic.
     * @param identifier: the property identifier.
     * @param value: the desired property value.
     * @param needReport: specifies whether to report the property value to IoT Platform by using the property.post topic.
     * In Scenario 2, the property report capability is integrated into the processing function and the needReport parameter is set to false.
     * @return
     */
    private boolean handlePropertySet(String identifier, ValueWrapper value, boolean needReport) {
        ALog.d(TAG, "The device handles property changes= [" + identifier + "], value = [" + value + "]");
        // Check whether the property settings are successful based on the response. In this example, a success message is returned.
        boolean success = true;
        if (needReport) {
            reportProperty(identifier, value);
        }
        return success;
    }

    private void reportProperty(String identifier, ValueWrapper value){
        if (StringUtils.isEmptyString(identifier) || value == null) {
            return;
        }

        ALog.d(TAG, "Report property identity=" + identifier);

        Map<String, ValueWrapper> reportData = new HashMap<>();
        reportData.put(identifier, value);
        LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {

            public void onSuccess(String s, Object o) {
                // The property value is reported.
                ALog.d(TAG, "Report success onSuccess() called with: s = [" + s + "], o = [" + o + "]");
            }

            public void onError(String s, AError aError) {
                // The property value fails to be reported.
                ALog.d(TAG, "Report failure onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]");
            }
        });
    }

    /**
     * Register a function to respond to service calls and property settings.
     * When IoT Platform calls a service from the device, the device must respond to the call and return a response.
     */
    public void connectNotifyListener() {
        List<Service> serviceList = LinkKit.getInstance().getDeviceThing().getServices();
        for (int i = 0; serviceList != null && i < serviceList.size(); i++) {
            Service service = serviceList.get(i);
            LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
        }
    }

    private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
        public void onProcess(String serviceIdentifier, Object result, ITResResponseCallback itResResponseCallback) {
            ALog.d(TAG, "onProcess() called with: s = [" + serviceIdentifier + "]," +
                    " o = [" + result + "], itResResponseCallback = [" + itResResponseCallback + "]");
            ALog.d(TAG, "Received an asynchronous service call from IoT Platform " + serviceIdentifier);
            try {
                if (SERVICE_SET.equals(serviceIdentifier)) {
                    Map<String, ValueWrapper> data = (Map<String, ValueWrapper>)((InputParams)result).getData();
                    ALog.d(TAG, "Received asynchronous downstream data " + data);
                    // Set the property value of the device and report the property value to IoT Platform.
                    boolean isSetPropertySuccess =
                            handlePropertySet("LightStatus", data.get("LightStatus"), false);
                    if (isSetPropertySuccess) {
                        if (result instanceof InputParams) {
                            // Return a response to IoT Platform.
                            itResResponseCallback.onComplete(serviceIdentifier, null, null);
                        } else {
                            itResResponseCallback.onComplete(serviceIdentifier, null, null);
                        }
                    } else {
                        AError error = new AError();
                        error.setCode(100);
                        error.setMsg("setPropertyFailed.");
                        itResResponseCallback.onComplete(serviceIdentifier, new ErrorInfo(error), null);
                    }
                } else if (SERVICE_GET.equals(serviceIdentifier)) {
                } else {
                    // The device operation varies by service.
                    ALog.d(TAG, "The returned values corresponding to the service.");
                    OutputParams outputParams = new OutputParams();
                    // outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                    itResResponseCallback.onComplete(serviceIdentifier, null, outputParams);
                }
            } catch (Exception e) {
                e.printStackTrace();
                ALog.d(TAG, "The format of the returned data is invalid");
            }
        }

        public void onSuccess(Object o, OutputParams outputParams) {
            ALog.d(TAG, "onSuccess() called with: o = [" + o + "], outputParams = [" + outputParams + "]");
            ALog.d(TAG, "The service was registered");
        }

        public void onFail(Object o, ErrorInfo errorInfo) {
            ALog.d(TAG, "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
            ALog.d(TAG, "Service registration failed.");
        }
    };

    private void getDesiredProperty(BaseInfo info, List<String> properties, IConnectSendListener listener) {
        ALog.d(TAG, "getDesiredProperty() called with: info = [" + info + "], listener = [" + listener + "]");
        if(info != null && !StringUtils.isEmptyString(info.productKey) && !StringUtils.isEmptyString(info.deviceName)) {
            MqttPublishRequest request = new MqttPublishRequest();
            request.topic = DESIRED_PROPERTY_GET.replace("{productKey}", info.productKey).replace("{deviceName}", info.deviceName);
            request.replyTopic = DESIRED_PROPERTY_GET_REPLY.replace("{productKey}", info.productKey).replace("{deviceName}", info.deviceName);
            request.isRPC = true;
            RequestModel<List<String>> model = new RequestModel<>();
            model.id = String.valueOf(IDGeneraterUtils.getId());
            model.method = METHOD_GET_DESIRED_PROPERTY;
            model.params = properties;
            model.version = "1.0";
            request.payloadObj = model.toString();
            ALog.d(TAG, "getDesiredProperty: payloadObj=" + request.payloadObj);
            ConnectSDK.getInstance().send(request, listener);
        } else {
            ALog.w(TAG, "getDesiredProperty failed, baseInfo Empty.");
            if(listener != null) {
                AError error = new AError();
                error.setMsg("BaseInfoEmpty.");
                listener.onFailure(null, error);
            }
        }
    }
}