All Products
Search
Document Center

IoT Platform:Develop TSL models

Last Updated:Aug 22, 2023

The Thing Specification Language (TSL) model is a data model that IoT Platform defines for products. You can configure Link SDK for Android for devices to submit properties and events, and to receive commands from IoT Platform for setting properties and calling services.

Background information

Usage notes

Important

The onSuccess function that is returned in the callback of the TSL-related operations indicates that the message is successfully sent from the device, but not that the task in the message is successfully executed. Therefore, we recommend that you do not use the onSuccess function as a dependency for your business logic.

  • IThing is the TSL model object that is returned by using the getDeviceThing() function in Link SDK for Android. For more information about IThing, see Interface IThing.

  • By default, the TSL model feature is disabled in Link SDK for Android. If you want to enable the feature, see Step 5 of the sample code in the "Unique-certificate-per-device verification" section of the Verify and connect a device topic.

  • If you need to process downstream requests based on responses of TSL-related operations, see the onNotify function of IConnectNotifyListener in the InitManager.java class of the demo.

  • For information about the code, see the TSLActivity.java class in the demo.

Devices submit property data to IoT Platform

  • Submit property data:

    // The device submits data.
    Map<String, ValueWrapper> reportData = new HashMap<>();
    // identifier is a unique property identifier that is defined by IoT Platform. valueWrapper is the property value.
    // ValueWrapper valueWrapper = new ValueWrapper.BooleanValueWrapper(1);   // In this example, the Boolean value is set to 1.
    // reportData.put(identifier, valueWrapper);  // An example for reference. For more information, see the demo. 
    LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {
     @Override
    public void onSuccess(String alinkId, Object o) {
            // The message is sent by the device.
            // The alinkId parameter specifies the ID of the message.
    }
    public void onError(String alinkId, AError aError) {
            // The property data failed to be submitted.    
            // The alinkId parameter specifies the ID of the message.
    }
    });
     
    Note
    • In version 1.7.3.1 and later, the alinkId parameter in the thingPropertyPost callback function indicates the ID of the upstream message.

    • If you want to check whether IoT Platform receives the properties from the device, you can subscribe to the /sys/${productKey}/${deviceName}/thing/event/property/post_reply topic and take note of the onNotify function of the IConnectNotifyListener class. For more information, see InitManager.java in the demo. The onNotify function returns the ID of the message in the alinkId parameter. If the ID of the upstream message is the same as the ID of the downstream message, the downstream message is processed by IoT Platform.

  • Obtain property data:

    The device can obtain the property data that is cached in the device. However, the device cannot obtain property data from IoT Platform in real time.

    // Use identifier to obtain the property value of the TSL model. The property value is in the default module.
    String identifier = "******";
    LinkKit.getInstance().getDeviceThing().getPropertyValue(identifier);
    // Obtain a list of properties in the default module.
    LinkKit.getInstance().getDeviceThing().getProperties()

Devices submit events to IoT Platform

HashMap<String, ValueWrapper> hashMap = new HashMap<>();
// Modify the code based on your business requirements.
// hashMap.put("ErrorCode", new ValueWrapper.IntValueWrapper(0));
OutputParams params = new OutputParams(hashMap);
LinkKit.getInstance().getDeviceThing().thingEventPost(identifier, params, new IPublishResourceListener() {
 @Override
public void onSuccess(String alinkId, Object o) {
        // The message is sent by the device.
        // The alinkId parameter specifies the ID of the message.
}
public void onError(String alinkId, AError aError) {
        // The event failed to be submitted.
        // The alinkId parameter specifies the ID of the message.
}
});
Note
  • In version 1.2.3 and later, the alinkId parameter in the thingPropertyPost callback function indicates the ID of the upstream message.

  • If you want to check whether IoT Platform receives the events from the device, you can subscribe to the /sys/${productKey}/${deviceName}/thing/event/${tsl.event.identifier}/post_reply topic and take note of the onNotify function of the IConnectNotifyListener class. For more information, see InitManager.java in the demo. The onNotify function returns the ID of the message in the alinkId parameter. If the ID of the upstream message is the same as the ID of the downstream message, the downstream message is processed by IoT Platform.

Obtain a list of events in the default module.

The device can obtain the events that are cached in the device. However, the device cannot obtain events from IoT Platform in real time.

LinkKit.getInstance().getDeviceThing().getEvents()

IoT Platform sends property data and service data to devices

  • Query device services. For more information, see Class Service<T>.

  • Obtain a list of services. The services are in the default module.

    LinkKit.getInstance().getDeviceThing().getServices()
  • You can call device services in an asynchronous or synchronous manner. The device uses the setServiceHandler function to configure a service listener and receive data from IoT Platform, such as setting device properties and obtaining property values.

    Asynchronous invocation

    Procedure

    callType="async"
    • Asynchronous service calls. Register a service calling listener. If IoT Platform calls a service in asynchronous mode, the downstream request is pushed to the listener.

    • The onProcess function is used to receive the service call in the downstream request. The first parameter indicates the identifier of the service. You can process the request based on the identifier.

      For more information about identifiers of services, see Add a TSL feature.

    • When the device receives a request from IoT Platform, the device performs the required operation, and then returns a property change notification to IoT Platform.

    Sample code

    // You can register a listener for the service based on your business requirements.
    LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
    // The handler of the service calling request.
    private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
        @Override
        public void onProcess(String identify, Object result, ITResResponseCallback itResResponseCallback) {
    	// The device receives the asynchronous service calling request from IoT Platform. The identify parameter indicates the unique identifier of the corresponding device property or service, and the result parameter indicates service calling data that is sent from IoT Platform.
    	// iotResResponseCallback is called to send a response to IoT Platform after the device processes the service calling request. For more information, see the demo.
    	try {
    	    if (SERVICE_SET.equals(identify)) { // Call the set service in an asynchronous manner.
    		// Configure the device property based on your business requirements.
    		// Submit the configured device property to IoT Platform.
    		// Check whether the property settings are configured based on the response. In this example, a success message is returned.
    		boolean isSetPropertySuccess = true;
    		if (isSetPropertySuccess){
    		    if (result instanceof InputParams) {
    			Map<String, ValueWrapper> data = (Map<String, ValueWrapper>) ((InputParams) result).getData();
    			// Indicates that the data is received.
    			itResResponseCallback.onComplete(identify, null, null);
    		    } else {
    			itResResponseCallback.onComplete(identify, null, null);
    		    }
    		} else {
    		    AError error = new AError();
    		    error.setCode(100);
    		    error.setMsg("setPropertyFailed.");
    		    itResResponseCallback.onComplete(identify, new ErrorInfo(error), null);
    		}
    	    } else if (SERVICE_GET.equals(identify)){ // Call the get service in an asynchronous manner.
    		// If the default values are initialized and passed in during the initialization, the TSL model directly returns the values that are cached in the IoT Platform console.
    	    } else { // Call a custom service.
    		// The device operation varies based on the service.
    		OutputParams outputParams = new OutputParams();
    		// outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
    		itResResponseCallback.onComplete(identify,null, outputParams);
    	    }
    	} catch (Exception e) {
    	    e.printStackTrace();
    	}
        }
        @Override
        public void onSuccess(Object o, OutputParams outputParams) {
    	// The service is registered. tag: the tag that you specify, which is not used in this demo. outputParams: the type of the data returned when the asynchronous callback is successful.
        }
     }

    Synchronous invocation

    Procedure

    callType="sync"
    • A synchronous service call is a revert-RPC (RRPC).

    • You can register a listener to listen to downstream data. When IoT Platform calls a service, the onNotify function can receive the downstream request.

    • When the device receives a request from IoT Platform, the device performs the required operation, and then sends a response that contains the result to IoT Platform.

    Note

    The current SDK version supports custom RRPCs. A synchronous service call uses a custom RRPC channel to send the downstream request.

    Sample code

    // You can register a listener for the service based on your business requirements.
    LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);
    // The handler of the service calling request.
    private ITResRequestHandler mCommonHandler = new ITResRequestHandler() {
        @Override
        public void onProcess(String identify, Object result, ITResResponseCallback itResResponseCallback) {
    	// The device receives the asynchronous service calling request from IoT Platform. The identify parameter indicates the unique identifier of the corresponding device property or service, and the result parameter indicates service calling data that is sent from IoT Platform.
    	// iotResResponseCallback is called to send a response to IoT Platform after the device processes the service calling request. For more information, see the demo.
    	try {
    	    if (SERVICE_SET.equals(identify)) { // Call the set service in an asynchronous manner.
    		// Configure the device property based on your business requirements.
    		// Submit the configured device property to IoT Platform.
    		// Check whether the property settings are configured based on the response. In this example, a success message is returned.
    		boolean isSetPropertySuccess = true;
    		if (isSetPropertySuccess){
    		    if (result instanceof InputParams) {
    			Map<String, ValueWrapper> data = (Map<String, ValueWrapper>) ((InputParams) result).getData();
    			// Indicates that the data is received.
    			itResResponseCallback.onComplete(identify, null, null);
    		    } else {
    			itResResponseCallback.onComplete(identify, null, null);
    		    }
    		} else {
    		    AError error = new AError();
    		    error.setCode(100);
    		    error.setMsg("setPropertyFailed.");
    		    itResResponseCallback.onComplete(identify, new ErrorInfo(error), null);
    		}
    	    } else if (SERVICE_GET.equals(identify)){ // Call the get service in an asynchronous manner.
    		// If the default values are initialized and passed in during the initialization, the TSL model directly returns the values that are cached in the IoT Platform console.
    	    } else { // Call a custom service.
    		// The device operation varies based on the service.
    		OutputParams outputParams = new OutputParams();
    		// outputParams.put("op", new ValueWrapper.IntValueWrapper(20));
    		itResResponseCallback.onComplete(identify,null, outputParams);
    	    }
    	} catch (Exception e) {
    	    e.printStackTrace();
    	}
        }
        @Override
        public void onSuccess(Object o, OutputParams outputParams) {
    	// The service is registered. tag: the tag that you specify, which is not used in this demo. outputParams: the type of the data returned when the asynchronous callback is successful.
        }
     }

TSL modules

Usage notes

  • TSL modules are supported by iot-device-manager 1.7.5.2 and later.

  • In the default module of a TSL model, the identifier of a property, an event, or a service is not prefixed. For example, the identifier of a property named lightSwitch is lightSwitch.

  • In a custom module of a TSL model, the identifier of a property, an event, or a service is prefixed with the name of the module. For example, the identifier of a property named lightSwitch in a module named myBlock is myBlock:lightSwitch.

Submit property data of TSL modules to IoT Platform

The following sample code provides an example on how a property named lightSwitch in a module named myBlock is submitted.

Map<String, ValueWrapper> reportData  = new HashMap<>();
// identifier is the unique property identifier that is defined by IoT Platform. valueWrapper is the property value.
String identifier = "myBlock:lightSwitch";
// reportData.put(identifier, valueWrapper);  // An example for reference. For more information, see the demo.
LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() {
    @Override
    public void onSuccess(String resID, Object o) {
        // The property data is successfully submitted.
    }

    @Override
    public void onError(String resId, AError aError) {
        // The property data failed to be submitted.
    }
});

Submit events of TSL modules to IoT Platform

The following sample code provides an example on how an event named OnDetect in a module named map is submitted.

 HashMap<String, ValueWrapper> hashMap = new HashMap<>();
hashMap.put("StoreID", new ValueWrapper.StringValueWrapper("1"));
OutputParams params = new OutputParams(hashMap);
LinkKit.getInstance().getDeviceThing().thingEventPost("map:OnDetect", params, new IPublishResourceListener() {
    @Override
        public void onSuccess(String resId, Object o) { // The event is successfully submitted.
    }

    @Override
        public void onError(String resId, AError aError) { // The event failed to be submitted.
     }
 });

Register services of TSL modules

The callback of a service in a custom module can be listened to only if the service is registered in the SDK. The following sample code provides an example on how a service named VehDtcService in a module named map is registered.

thing.setServiceHandler("map:VehDtcService", resRequestHandler);

resRequestHandler indicates the handler of the TSL model that processes requests. For more information, see the TSLActivity.java class in the demo.

IoT Platform sends requests to devices

  • You can use the maintenance features of IoT Platform to control devices and send data to devices. For more information, see Online debugging.

  • You can use API operations in the OpenAPI Portal to send requests from IoT Platform to devices. For more information, see IoT Platform API reference.