Tous les produits
Search
Centre de documentation

IoT Platform:Spécifier une valeur de propriété souhaitée pour contrôler l'état d'une ampoule

Dernière mise à jour :Aug 21, 2026

IoT Platform permet de définir une valeur souhaitée pour une propriété d'appareil. Vous pouvez ainsi mettre en cache cette valeur dans IoT Platform et contrôler l'appareil à distance. Cette rubrique explique comment spécifier une valeur souhaitée pour une propriété d'appareil dans la console IoT Platform afin de contrôler l'état d'une ampoule.

Informations générales

Une fois l'ampoule connectée à IoT Platform, assurez-vous que l'appareil reste en ligne pour contrôler son état. Dans la console IoT Platform, l'ampoule peut se trouver dans l'état On (1) ou Off (0). Toutefois, dans des scénarios réels, l'ampoule peut perdre sa connexion.

Vous pouvez spécifier une valeur souhaitée pour l'ampoule et la stocker dans IoT Platform. Lorsque l'appareil se reconnecte, il lit la valeur de propriété souhaitée stockée dans IoT Platform et met à jour sa propre valeur de propriété. La valeur mise à jour est ensuite transmise à IoT Platform et affichée sous l'onglet Status de la console IoT Platform.

Créer un produit et ajouter un appareil

  1. Connectez-vous à la console IoT Platform.

  2. Sur la page Overview, localisez l'instance à gérer et cliquez sur son ID ou son nom.

  3. Dans le volet de navigation de gauche, choisissez Devices > Products. Sur la page Products, cliquez sur Create Product pour créer un produit correspondant à une ampoule.

    Définissez

    Node Type

    sur

    Directly Connected Device

    ,

    Connection Method

    sur

    Wi-Fi

    et

    Data Format

    sur

    ICA Standard Data Format (Alink JSON)

    .

  4. Une fois le produit créé, cliquez sur Define TSL Model pour ajouter un modèle Thing Specification Language (TSL) au produit, puis publiez-le. Pour plus d'informations, consultez Ajouter un modèle TSL pour un seul produit.

    Dans cet exemple, ajoutez une propriété nommée

    Work Status (LightStatus)

    . Le type de données de cette propriété est

    bool (Boolean)

    , où

    0

    correspond à Off et

    1

    à On.

  5. Dans le volet de navigation de gauche, choisissez Devices > Devices, puis cliquez sur Add Device pour ajouter l'appareil Lamp au produit.

    Après la création de l'appareil, récupérez son certificat, qui comprend le ProductKey, le DeviceName et le DeviceSecret.

    Dans la liste des appareils, localisez l'appareil Lamp et cliquez sur View pour accéder à la page Device Details. Sous l'onglet Running Status, vous constaterez que la valeur de propriété et la valeur souhaitée de l'appareil sont toutes deux vides. Initialement, la version de la propriété souhaitée est 0.

Définir et interroger les valeurs de propriété souhaitées

Appelez des opérations d'API pour définir et interroger les dernières valeurs de propriété souhaitées d'un appareil.

Les exemples de cette rubrique utilisent le SDK Java (pour le développement côté cloud). Pour plus d'informations, consultez Opérations d'API.

  • Appelez l'opération SetDeviceDesiredProperty pour définir une valeur de propriété souhaitée.

    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());
    }
  • Utilisez l'opération QueryDeviceDesiredProperty pour consulter les valeurs de propriété souhaitées de l'appareil.

    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());
    }

Pour plus d'informations sur la configuration des paramètres dans le code, consultez le Guide d'utilisation du SDK Java.

Une fois la valeur de propriété souhaitée définie dans IoT Platform, elle apparaît dans l'état d'exécution de l'appareil. Sur la page Device Details, cliquez sur TSL Data > Running Status. La valeur souhaitée de la propriété s'affiche alors comme 1 (On).

Développement côté appareil

L'ampoule peut obtenir les valeurs de propriété souhaitées dans les scénarios suivants :

  • Lorsque l'ampoule passe de l'état hors ligne à en ligne, l'appareil demande la valeur de propriété souhaitée mise en cache dans IoT Platform.

  • Si l'ampoule est déjà en ligne, l'appareil reçoit la valeur de propriété souhaitée envoyée par IoT Platform en temps réel.

Pour plus d'informations sur le développement côté appareil, consultez Utiliser un SDK côté appareil pour connecter un appareil.

Cette rubrique fournit une démo complète côté appareil . Pour le code complet, reportez-vous à l'Annexe : Code de démo côté appareil.

  1. Renseignez les informations relatives au certificat de l'appareil, à la région et à l'endpoint 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";
    Remarque
    • Pour plus d'informations sur le certificat de l'appareil, consultez la section Créer un produit et un appareil de cette rubrique.

    • Le paramètre regionId correspond à l'ID de la région où votre instance est déployée. Vous trouverez cette région dans le coin supérieur gauche de la console IoT Platform. Pour obtenir la liste des ID de région, consultez Régions prises en charge.

    • Le paramètre channelHost spécifie l'endpoint MQTT. Pour savoir comment obtenir un endpoint, consultez Afficher et configurer les endpoints d'instance.

  2. Ajoutez les méthodes suivantes pour modifier l'état physique de l'ampoule et signaler le nouvel état au cloud.

    /**
     * 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. Lorsque l'ampoule est en ligne et qu'une valeur de propriété souhaitée est définie dans IoT Platform, cette valeur est envoyée à l'appareil. L'appareil traite alors le message et modifie son état.

    Dans le code ci-dessous, la méthode connectNotifyListener est appelée pour traiter le message. Pour plus d'informations sur le protocole Alink, consultez Signalement des propriétés par l'appareil.

    À la réception des données descendantes asynchrones, mCommonHandler est invoqué, ce qui déclenche à son tour handlePropertySet pour mettre à jour les propriétés physiques de l'appareil.

    /**
     * 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 vous définissez une valeur de propriété souhaitée dans IoT Platform alors que l'ampoule est hors ligne, IoT Platform stocke cette valeur dans le cloud.

    Dès que l'ampoule revient en ligne, elle récupère activement la valeur souhaitée, puis appelle handlePropertySet pour mettre à jour son état physique.

    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);
            }
        }
    }

Vérifier le résultat de la migration

Exécutez l'exemple de code selon les scénarios suivants pour vérifier l'état en ligne ou hors ligne de l'ampoule. Modifiez la valeur de propriété de l'appareil en spécifiant une valeur souhaitée dans IoT Platform.

  • Lorsque l'appareil est en ligne, toute modification de l'état de l'ampoule depuis le cloud déclenche une réponse en temps réel. Sur la page Device Details, accédez à TSL Data > Running Status. La valeur de la propriété Work Status est 1 (On), et la valeur souhaitée est également 1 (On).

  • Si l'appareil est hors ligne et que vous modifiez l'état de l'ampoule depuis le cloud, la valeur souhaitée diffère de la dernière valeur signalée par l'appareil. Sous l'onglet TSL Data > Running Status de la page Device Details, la valeur actuelle de la propriété Work Status est 1 (On), tandis que la valeur souhaitée est 0 (Off).

  • Une fois l'appareil reconnecté, il récupère la valeur de propriété souhaitée et synchronise son état. Sous l'onglet TSL Data > Running Status, vous pouvez constater que les valeurs souhaitée et actuelle de la propriété Work Status sont toutes deux 0 (Off). Cela confirme que la propriété de l'appareil s'est bien synchronisée avec la valeur souhaitée provenant du cloud.

Annexe : Exemple de code pour configurer un appareil

L'exemple de code suivant fournit une démo complète côté appareil permettant de contrôler une ampoule à l'aide de valeurs de propriété souhaitées. Cette démo couvre l'initialisation de l'appareil, la récupération des propriétés souhaitées, la gestion des changements de propriété et l'enregistrement des services.

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);
            }
        }
    }
}