Todos los productos
Search
Centro de documentos

IoT Platform:Especificar un valor de propiedad deseado para controlar el estado de un foco

Última actualización: Sep 05, 2026

IoT Platform le permite especificar un valor deseado para la propiedad de un dispositivo. De esta manera, puede almacenar dicho valor en la caché de IoT Platform y controlar el dispositivo de forma remota mediante ese valor. En este tema se describe cómo especificar un valor deseado para la propiedad de un dispositivo en la consola de IoT Platform con el fin de controlar el estado de un foco.

Contexto

Una vez que el foco se conecta a IoT Platform, asegúrese de que el dispositivo permanezca en línea para poder controlar su estado. El foco en la consola de IoT Platform puede estar en el estado On (1) u Off (0). Sin embargo, en escenarios reales es posible que el foco no logre mantenerse en línea.

Puede especificar un valor deseado para el foco y almacenarlo en IoT Platform. Cuando el dispositivo vuelve a conectarse, lee el valor de propiedad deseado almacenado en IoT Platform y actualiza su propiedad. Después, el valor actualizado se envía a IoT Platform y se muestra en la pestaña Status de la consola de IoT Platform.

Crear un producto y agregar un dispositivo

  1. Inicie sesión en la consola de IoT Platform.

  2. En la página Overview, busque la instancia que desea gestionar y haga clic en su ID o nombre.

  3. En el panel de navegación izquierdo, elija Devices > Products. En la página Products, haga clic en Create Product para crear un producto de tipo foco.

    Establezca

    Node Type

    en

    Directly Connected Device

    ,

    Connection Method

    en

    Wi-Fi

    y

    Data Format

    en

    ICA Standard Data Format (Alink JSON)

    .

  4. Una vez creado el producto, haga clic en Define TSL Model para agregarle un modelo Thing Specification Language (TSL) y, a continuación, publíquelo. Para obtener más información, consulte Add a TSL model for a single product.

    En este ejemplo, agregue una propiedad llamada

    Work Status (LightStatus)

    . El tipo de datos de esta propiedad es

    bool (Boolean)

    , donde

    0

    representa Off y

    1

    representa On.

  5. En el panel de navegación izquierdo, elija Devices > Devices y haga clic en Add Device para agregar el dispositivo Lamp al producto.

    Después de crear el dispositivo, obtenga su certificado, el cual incluye ProductKey, DeviceName y DeviceSecret.

    En la lista de dispositivos, busque el dispositivo Lamp y haga clic en View para ir a la página Device Details. En la pestaña Running Status, observará que tanto el valor de la propiedad como el valor deseado están vacíos. Inicialmente, la versión de la propiedad deseada es 0.

Establecer y consultar valores de propiedad deseados

Puede llamar a operaciones de API para establecer y consultar los valores de propiedad deseados más recientes de un dispositivo.

Los ejemplos de este tema utilizan Java SDK (for cloud-side development). Para obtener más información, consulte API operations.

  • Llame a la operación SetDeviceDesiredProperty para establecer un valor de propiedad deseado.

    DefaultProfile profile = DefaultProfile.getProfile(
            "<RegionId>",          // The region ID.
            "<accessKey>",     // The AccessKey ID of your Alibaba Cloud account.
            "<accessSecret>"); // The AccessKey secret of your 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 property identifier and the desired value to set.
    request.setItems("{\"LightStatus\": 1}");
    request.setVersions("{\"LightStatus\": 0}");
    // Send the request and handle the response or exceptions.
    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());
    }
  • Llame a la operación QueryDeviceDesiredProperty para consultar los valores de propiedad deseados del dispositivo.

    DefaultProfile profile = DefaultProfile.getProfile(
            "<RegionId>",          // The region ID.
            "<accessKey>",      // The AccessKey ID of your Alibaba Cloud account.
            "<accessSecret>"); // The AccessKey secret of your Alibaba Cloud account.
    IAcsClient client = new DefaultAcsClient(profile);
    // Create an API request and set the parameters.
    QueryDeviceDesiredPropertyRequest request = new QueryDeviceDesiredPropertyRequest();
    request.setIotInstanceId("iot-06****");
    request.setProductKey("g4r****");
    request.setDeviceName("Lamp");
    // A list of property identifiers to query. If this parameter is omitted, the desired values of all writable properties are queried.
    List<String> identifierList = new ArrayList<String>();
    identifierList.add("LightStatus");
    request.setIdentifiers(identifierList);
    // Send the request and handle the response or exceptions.
    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());
    }

Para obtener más información sobre cómo configurar los parámetros en el código, consulte Java SDK usage guide.

Después de establecer el valor de propiedad deseado en IoT Platform, este aparece en el estado de ejecución del dispositivo. En la página Device Details, haga clic en TSL Data > Running Status. Ahí podrá ver que el valor deseado de la propiedad se muestra como 1 (On).

Desarrollo del lado del dispositivo

El foco puede obtener los valores de propiedad deseados en los siguientes escenarios:

  • Si el foco pasa de estar desconectado a estar en línea, solicita el valor de propiedad deseado almacenado en la caché de IoT Platform.

  • Si el foco está en línea, recibe en tiempo real el valor de propiedad deseado que IoT Platform le envía.

Para obtener más información sobre el desarrollo del lado del dispositivo, consulte Use a device-side SDK to connect a device.

Este tema proporciona una demostración completa del lado del dispositivo . Para ver el código completo, consulte Appendix: Device-side demo code.

  1. Complete la información del certificado del dispositivo, la región y el endpoint de MQTT.

    /**
    * Device certificate information.
    */
    private static String productKey = "******";
    private static String deviceName = "********";
    private static String deviceSecret = "**************";
    /**
    * MQTT connection information.
    */
    private static String regionId = "******";
    ......
    /**
    * Set MQTT initialization parameters.
    */ 
    config.channelHost = deviceInfo.productKey + ".iot-as-mqtt." + region + ".aliyuncs.com:1883";
    Nota
    • Para obtener información sobre el certificado del dispositivo, consulte la sección Create a product and a device de este tema.

    • El parámetro regionId es el identificador de la región donde se despliega su instancia. Puede encontrar la región en la esquina superior izquierda de la consola de IoT Platform. Para consultar la lista de identificadores de región, vea Supported regions.

    • El parámetro channelHost especifica el endpoint de MQTT. Para obtener más información sobre cómo conseguir un endpoint, consulte View and configure instance endpoints.

  2. Agregue los siguientes métodos para cambiar el estado físico del foco y reportar el nuevo estado a la nube.

    /**
     * This method is called when the physical device needs to handle a property change. This occurs in two scenarios:
     * Scenario 1: After connecting, the device actively fetches the latest desired property values (pull model).
     * Scenario 2: While online, the device receives desired property values pushed from the cloud through `property.set` (push model).
     * @param identifier  The property identifier.
     * @param value       The desired property value.
     * @param needReport  Specifies whether to send a status report by using `property.post`.
     *                    In Scenario 2, the handler already includes reporting, so this parameter is set to false.
     * @return
     */
    private boolean handlePropertySet(String identifier, ValueWrapper value, boolean needReport) {
        ALog.d(TAG, "Physical device handling property change = [" + identifier + "], value = [" + value + "]");
        // In a real application, you would determine whether the set operation was successful. Here, we assume success.
        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, "Reporting 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 is reported successfully.
                ALog.d(TAG, "Report successful. onSuccess() called with: s = [" + s + "], o = [" + o + "]");
            }
            public void onError(String s, AError aError) {
                // Failed to report the property.
                ALog.d(TAG, "Report failed. onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]");
            }
        });
    }
  3. Cuando el foco está en línea y se establece un valor de propiedad deseado en IoT Platform, dicho valor se envía al dispositivo. Este procesa el mensaje y cambia su estado.

    En el siguiente código, se llama a connectNotifyListener para procesar el mensaje. Para obtener más información sobre el protocolo Alink, consulte Device reports properties.

    Tras recibir los datos descendentes asíncronos, se invoca mCommonHandler, que a su vez llama a handlePropertySet para actualizar las propiedades físicas del dispositivo.

    /**
     * Register a response function for service calls and property settings.
     * When the cloud calls a device service, the device must respond to the service call.
     */
    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 asynchronous service call from cloud: " + 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 on the physical device and then report the updated value.
                    boolean isSetPropertySuccess =
                            handlePropertySet("LightStatus", data.get("LightStatus"), false);
                    if (isSetPropertySuccess) {
                        if (result instanceof InputParams) {
                            // Respond to the cloud that the data was received successfully.
                            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 {
                    // Handle other services based on specific requirements.
                    ALog.d(TAG, "Return a value based on the actual service. For an example, refer to the 'set' implementation.");
                    OutputParams outputParams = new OutputParams();
                    // outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                    itResResponseCallback.onComplete(serviceIdentifier, null, outputParams);
                }
            } catch (Exception e) {
                e.printStackTrace();
                ALog.d(TAG, "Invalid data format returned from the cloud.");
            }
        }
        public void onSuccess(Object o, OutputParams outputParams) {
            ALog.d(TAG, "onSuccess() called with: o = [" + o + "], outputParams = [" + outputParams + "]");
            ALog.d(TAG, "Service registered successfully.");
        }
        public void onFail(Object o, ErrorInfo errorInfo) {
            ALog.d(TAG, "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
            ALog.d(TAG, "Failed to register service.");
        }
    };
  4. Si establece un valor de propiedad deseado en IoT Platform mientras el foco está desconectado, la plataforma lo almacena en la nube.

    Cuando el foco se conecta, recupera activamente el valor deseado y luego llama a handlePropertySet para actualizar su estado físico.

    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();
            // Get the latest desired property value from the cloud.
            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 has been 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);
            }
        }
    }

Comprobar el resultado de la migración

Ejecute el código de ejemplo según los siguientes escenarios para comprobar si el foco está en línea o desconectado. Puede modificar el valor de la propiedad del dispositivo al especificar un valor deseado en IoT Platform.

  • Cuando el dispositivo está en línea, cualquier cambio de estado del foco en la nube genera una respuesta en tiempo real. En la página Device Details, vaya a TSL Data > Running Status. El valor de la propiedad Work Status es 1 (On) y el valor deseado también es 1 (On).

  • Si el dispositivo está desconectado y usted modifica el estado del foco en la nube, el valor deseado será distinto del último valor reportado por el dispositivo. En la pestaña TSL Data > Running Status de la página Device Details, el valor actual de la propiedad Work Status es 1 (On), mientras que el valor deseado es 0 (Off).

  • Una vez que el dispositivo se reconecta, recupera el valor de propiedad deseado y sincroniza su estado. En la pestaña TSL Data > Running Status, verá que tanto el valor deseado como el actual de la propiedad Work Status son 0 (Off). Esto confirma que la propiedad del dispositivo se sincronizó correctamente con el valor deseado desde la nube.

Apéndice: código de ejemplo para configurar un dispositivo

El siguiente código de ejemplo proporciona una demostración completa del lado del dispositivo para controlar un foco mediante valores de propiedad deseados. La demostración abarca la inicialización del dispositivo, la recuperación de la propiedad deseada, el manejo de cambios de propiedad y el registro de servicios.

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) {
        /**
         * Device certificate information.
         */
        String productKey = "****";
        String deviceName = "Lamp";
        String deviceSecret = "****";
        /**
         * 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();
        /**
         * Set MQTT initialization parameters.
         */
        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";
        /**
         * Specifies whether to receive offline messages.
         * This corresponds to the `cleanSession` field in MQTT.
         */
        config.receiveOfflineMsg = false;
        params.mqttClientConfig = config;
        /**
         * Set initialization parameters and pass in the device certificate information.
         */
        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();
                // Get the latest desired property value from the cloud.
                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 has been 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 + "]");
                    }
                });
            }
        });
    }
    /**
     * This method is called when the physical device needs to handle a property change. This occurs in two scenarios:
     * Scenario 1: After connecting, the device actively fetches the latest desired property values (pull model).
     * Scenario 2: While online, the device receives desired property values pushed from the cloud through `property.set` (push model).
     * @param identifier  The property identifier.
     * @param value       The desired property value.
     * @param needReport  Specifies whether to send a status report by using `property.post`.
     *                    In Scenario 2, the handler already includes reporting, so this parameter is set to false.
     * @return
     */
    private boolean handlePropertySet(String identifier, ValueWrapper value, boolean needReport) {
        ALog.d(TAG, "Physical device handling property change = [" + identifier + "], value = [" + value + "]");
        // In a real application, you would determine whether the set operation was successful. Here, we assume success.
        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, "Reporting 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 is reported successfully.
                ALog.d(TAG, "Report successful. onSuccess() called with: s = [" + s + "], o = [" + o + "]");
            }
            public void onError(String s, AError aError) {
                // Failed to report the property.
                ALog.d(TAG, "Report failed. onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]");
            }
        });
    }
    /**
     * Register a response function for service calls and property settings.
     * When the cloud calls a device service, the device must respond to the service call.
     */
    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 asynchronous service call from cloud: " + 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 on the physical device and then report the updated value.
                    boolean isSetPropertySuccess =
                            handlePropertySet("LightStatus", data.get("LightStatus"), false);
                    if (isSetPropertySuccess) {
                        if (result instanceof InputParams) {
                            // Respond to the cloud that the data was received successfully.
                            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 {
                    // Handle other services based on their specific requirements.
                    ALog.d(TAG, "Return a value based on the actual service. For an example, refer to the 'set' implementation.");
                    OutputParams outputParams = new OutputParams();
                    // outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
                    itResResponseCallback.onComplete(serviceIdentifier, null, outputParams);
                }
            } catch (Exception e) {
                e.printStackTrace();
                ALog.d(TAG, "Invalid data format returned from the cloud.");
            }
        }
        public void onSuccess(Object o, OutputParams outputParams) {
            ALog.d(TAG, "onSuccess() called with: o = [" + o + "], outputParams = [" + outputParams + "]");
            ALog.d(TAG, "Service registered successfully.");
        }
        public void onFail(Object o, ErrorInfo errorInfo) {
            ALog.d(TAG, "onFail() called with: o = [" + o + "], errorInfo = [" + errorInfo + "]");
            ALog.d(TAG, "Failed to register service.");
        }
    };
    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);
            }
        }
    }
}