You can establish Thing Specification Language (TSL)-based communication between devices and IoT Platform over the Alink protocol. Devices submit properties or events to IoT Platform, and IoT Platform sends commands to devices to configure properties or call services. This topic provides sample Java code to describe how to establish TSL-based communication.
Prerequisites
- IoT Platform is activated.
- A Java development environment is installed.
Create a product and a device
You must create a product and a device, and define TSL features for the product.
Download and install an SDK demo
The SDK demo includes the server-side sample code and device-side sample code.
Submit properties and events by using Link SDK
Configure Link SDK to connect to IoT Platform and submit properties and events.
The ThingTemplate file in the java/src/main/com.aliyun.iot.api.common.deviceApi directory contains the sample code.
- Specify the connection information.
Replace the values of the productKey, deviceName, and deviceSecret parameters in the sample code with the information about your device certificate. Replace the value of the url parameter with your MQTT endpoint. For more information about how to obtain an endpoint, see View the endpoint of an instance. The endpoint must include port 1883.
public static void main(String[] args) { /** * The information about the device certificate. */ String productKey = "your productKey"; String deviceName = "your deviceName"; String deviceSecret = "your deviceSecret"; /*TODO: Replace the following endpoint with the endpoint of your instance. */ String url = "iot-6d***ql.mqtt.iothub.aliyuncs.com:1883"; /** * The information about the MQTT connection. */ ThingTemplate manager = new ThingTemplate(); DeviceInfo deviceInfo = new DeviceInfo(); deviceInfo.productKey = productKey; deviceInfo.deviceName = deviceName; deviceInfo.deviceSecret = deviceSecret; /** * The Java HTTP client supports TSLv1.2. */ System.setProperty("https.protocols", "TLSv2"); manager.init(deviceInfo, url); }
- Initialize the connection parameters.
public void init(final DeviceInfo deviceInfo, String url) { LinkKitInitParams params = new LinkKitInitParams(); /** * Configure the parameters for MQTT initialization. */ IoTMqttClientConfig config = new IoTMqttClientConfig(); config.productKey = deviceInfo.productKey; config.deviceName = deviceInfo.deviceName; config.deviceSecret = deviceInfo.deviceSecret; config.channelHost = url; /** * Specify whether to receive offline messages. * The cleanSession field that corresponds to the MQTT connection. */ config.receiveOfflineMsg = false; params.mqttClientConfig = config; ALog.setLevel(LEVEL_DEBUG); ALog.i(TAG, "mqtt connetcion info=" + params); /** * Configure the initialization parameters and specify the certificate information about the device. */ params.deviceInfo = deviceInfo; /** Establish a connection. **/ 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); List<Property> properties = LinkKit.getInstance().getDeviceThing().getProperties(); ALog.i(TAG, "The device properties" + JSON.toJSONString(properties)); List<Event> getEvents = LinkKit.getInstance().getDeviceThing().getEvents(); ALog.i(TAG, "List of device events" + JSON.toJSONString(getEvents)); /* Submit properties. TODO: Make sure that the properties that you want to submit are defined in the TSL model of the product. Example: MicSwitch. Otherwise, an error message is returned. */ handlePropertySet("MicSwitch", new ValueWrapper.IntValueWrapper(1)); /* Submit events. TODO: Make sure that the events that you want to submit are defined in the TSL model of the product. Example: Offline_alarm. Otherwise, an error message is returned. */ Map<String,ValueWrapper> values = new HashMap<>(); values.put("eventValue",new ValueWrapper.IntValueWrapper(0)); OutputParams outputParams = new OutputParams(values); handleEventSet("Offline_alarm",outputParams); } }); }
Note The property and event identifiers in the code must be the same as the identifiers that are defined in the TSL model. - Configure Link SDK to submit properties.
/** * The device submits properties in the Alink JSON format. * @param identifier: the identifier of the property. * @param value: the value of the property. * @return */ private void handlePropertySet(String identifier, ValueWrapper value ) { ALog.i(TAG, "Identifier of the property=" + 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 submitted. ALog.i(TAG, "Submitted. onSuccess() called with: s = [" + s + "], o = [" + o + "]"); } public void onError(String s, AError aError) { // The property value failed to be submitted. ALog.i(TAG, "Failed to submit. onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]"); } }); }
- Configure Link SDK to submit events.
/** * The device submits events in the Alink JSON format. * @param identifier: the identifier of the event. * @param params: the parameters of the event. * @return */ private void handleEventSet(String identifyID, OutputParams params ) { ALog.i(TAG, "Identifier of the event=" + identifyID + " params=" + JSON.toJSONString(params)); LinkKit.getInstance().getDeviceThing().thingEventPost( identifyID, params, new IPublishResourceListener() { public void onSuccess(String s, Object o) { // The event is submitted. ALog.i(TAG, "Submitted. onSuccess() called with: s = [" + s + "], o = [" + o + "]"); } public void onError(String s, AError aError) { // Failed to submit the event. ALog.i(TAG, "Failed to submit. onError() called with: s = [" + s + "], aError = [" + JSON.toJSONString(aError) + "]"); } }); }
Send commands to configure properties and call services by using an IoT Platform SDK
- Initialize a client.
The IotClient file in the java/src/main/com.aliyun.iot.client directory contains the sample code.
public class IotClient { private static String accessKeyID; private static String accessKeySecret; private static String regionId; private static String domain; private static String version; public static DefaultAcsClient getClient() { DefaultAcsClient client = null; Properties prop = new Properties(); try { prop.load(Object.class.getResourceAsStream("/config.properties")); accessKeyID = prop.getProperty("user.accessKeyID"); accessKeySecret = prop.getProperty("user.accessKeySecret"); regionId = prop.getProperty("iot.regionId"); domain = prop.getProperty("iot.domain"); version = prop.getProperty("iot.version"); IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyID, accessKeySecret); DefaultProfile.addEndpoint(regionId, regionId, prop.getProperty("iot.productCode"), prop.getProperty("iot.domain")); // Initialize the client. client = new DefaultAcsClient(profile); } catch (Exception e) { LogUtil.print("Failed to initialize the client. exception:" + e.getMessage()); } return client; } public static String getRegionId() { return regionId; } public static void setRegionId(String regionId) { IotClient.regionId = regionId; } public static String getDomain() { return domain; } public static void setDomain(String domain) { IotClient.domain = domain; } public static String getVersion() { return version; } public static void setVersion(String version) { IotClient.version = version; } }
- Initialize the CommonRequest public class.
The AbstractManager file in the java/src/main/com.aliyun.iot.api.common.openApi directory encapsulates the CommonRequest public class.
public class AbstractManager { private static DefaultAcsClient client; static { client = IotClient.getClient(); } /** * Initialize the CommonRequest class. action: the name of the API operation. * domain: the endpoint. * version: the API version. */ public static CommonRequest executeTests(String action) { CommonRequest request = new CommonRequest(); request.setDomain(IotClient.getDomain()); request.setMethod(MethodType.POST); request.setVersion(IotClient.getVersion()); request.setAction(action); return request; }
- Call the API operations of IoT Platform to configure properties and call services.
The ThingManagerForPopSDk file in the java/src/main/com.aliyun.iot.api.common.openApi directory contains the sample code.
- Call the SetDeviceProperty operation to configure a device property.
public static void SetDeviceProperty(String InstanceId, String IotId, String ProductKey, String DeviceName , String Items) { SetDevicePropertyResponse response =null; SetDevicePropertyRequest request=new SetDevicePropertyRequest(); request.setDeviceName(DeviceName); request.setIotId(IotId); request.setItems(Items); request.setProductKey(ProductKey); request.setIotInstanceId(InstanceId); try { response = client.getAcsResponse(request); if (response.getSuccess() != null && response.getSuccess()) { LogUtil.print("The device property is configured."); LogUtil.print(JSON.toJSONString(response)); } else { LogUtil.print("Failed to configure the device property."); LogUtil.error(JSON.toJSONString(response)); } } catch (ClientException e) { e.printStackTrace(); LogUtil.error("Failed to configure the device property." + JSON.toJSONString(response)); } }
- Call the SetDevicesProperty operation to batch configure device properties.
/** * Batch configure device properties. * * @param ProductKey: the ProductKey of the product to which the devices whose properties you want to configure belong. * @param DeviceNames: the DeviceNames of the devices whose properties you want to configure. * @param Items: the property information that consists of multiple pairs of key-value JSON strings. This parameter is required. * * @Des: the description. */ public static void SetDevicesProperty(String InstanceId, String ProductKey, List<String> DeviceNames, String Items) { SetDevicesPropertyResponse response = new SetDevicesPropertyResponse(); SetDevicesPropertyRequest request = new SetDevicesPropertyRequest(); request.setDeviceNames(DeviceNames); request.setItems(Items); request.setProductKey(ProductKey); request.setIotInstanceId(InstanceId); try { response = client.getAcsResponse(request); if (response.getSuccess() != null && response.getSuccess()) { LogUtil.print("The properties are batch configured."); LogUtil.print(JSON.toJSONString(response)); } else { LogUtil.print("Failed to batch configure the device properties."); LogUtil.error(JSON.toJSONString(response)); } } catch (ClientException e) { e.printStackTrace(); LogUtil.error("Failed to batch configure the device properties." + JSON.toJSONString(response)); } }
- Call the InvokeThingService operation to call a device service.
/** * @param Identifier: the identifier of the service. This parameter is required. * @param Args: the input parameters that are required to start the service. This parameter is required. */ public static InvokeThingServiceResponse.Data InvokeThingService(String InstanceId, String IotId, String ProductKey, String DeviceName, String Identifier, String Args) { InvokeThingServiceResponse response =null; InvokeThingServiceRequest request = new InvokeThingServiceRequest(); request.setArgs(Args); request.setDeviceName(DeviceName); request.setIotId(IotId); request.setIdentifier(Identifier); request.setProductKey(ProductKey); request.setIotInstanceId(InstanceId); try { response = client.getAcsResponse(request); if (response.getSuccess() != null && response.getSuccess()) { LogUtil.print("The service is executed."); LogUtil.print(JSON.toJSONString(response)); } else { LogUtil.print("Failed to execute the service."); LogUtil.error(JSON.toJSONString(response)); } return response.getData(); } catch (ClientException e) { e.printStackTrace(); LogUtil.error("Failed to execute the service." + JSON.toJSONString(response)); } return null; }
Note If you want to synchronously call services, set the Invoking Method parameter to Synchronization when you define TSL models. When you develop devices, you must write the code to process synchronous service calls. - Call the InvokeThingsService operation to batch call device services.
/** * @param Identifier: the identifier of the service. This parameter is required. * @param Args: the input parameters that are required to start the service. This parameter is required. */ public static void InvokeThingsService(String InstanceId, String IotId, String ProductKey, List<String> DeviceNames, String Identifier, String Args) { InvokeThingsServiceResponse response =null; InvokeThingsServiceRequest request = new InvokeThingsServiceRequest(); request.setArgs(Args); request.setIdentifier(Identifier); request.setDeviceNames(DeviceNames); request.setProductKey(ProductKey); request.setIotInstanceId(InstanceId); try { response = client.getAcsResponse(request); if (response.getSuccess() != null && response.getSuccess()) { LogUtil.print("The services are called."); LogUtil.print(JSON.toJSONString(response)); } else { LogUtil.print("Failed to batch call the services."); LogUtil.error(JSON.toJSONString(response)); } } catch (ClientException e) { e.printStackTrace(); LogUtil.error("Failed to batch call the services." + JSON.toJSONString(response)); } }
- Call the SetDeviceProperty operation to configure a device property.
Sample request:
public static void main(String[] args) {
/** The DeviceName of the online device and the Productkey of the product to which the online device belongs. */
String deviceName = "2pxuAQB2I7wGPmqq***";
String deviceProductkey = "a1QbjI2***";
/** If you use an Enterprise Edition instance or a public instance of the new version, specify the instance ID for the InstanceId parameter. To obtain the instance ID, log on to the IoT Platform console and view the instance ID on the Overview page.
* If you use a public instance of the old version, leave the InstanceId parameter empty"".
*/
String InstanceId = "iot-***tl02";
//1. Configure a device property.
SetDeviceProperty(InstanceId, null, deviceProductkey, deviceName,"{\"hue\":0}");
//2. Batch configure device properties.
List<String> deviceNames = new ArrayList<>();
deviceNames.add(deviceName);
SetDevicesProperty(InstanceId, deviceProductkey, deviceNames, "{\"hue\":0}");
//3. Call a device service.
InvokeThingService(InstanceId, null, deviceProductkey, deviceName, "ModifyVehicleInfo", "{}");
//4. Batch call device services.
List<String> deviceNamesService = new ArrayList<>();
deviceNamesService.add(deviceName);
InvokeThingsService(null, deviceProductkey, deviceNamesService, "ModifyVehicleInfo", "{}");
}
Debug the SDKs
After you configure the Link SDK and the IoT Platform SDK, run the SDKs.
Check results:
- View local logs.
- On the Device Details page of the device, click Default Module.
- The Status tab displays the property values that the device most recently submitted.
- The Events tab displays the events that the device most recently submitted.
- The Invoke Service tab displays the records of service calls.