In some IoT scenarios, devices that have limited resources or low specifications cannot use Thing Specification Language (TSL) models in the JSON format to communicate with IoT Platform. To resolve the issue, you can pass through raw data from devices to IoT Platform. IoT Platform converts raw device data to Alink JSON data by using data parsing scripts that you submit. Then, you can perform subsequent operations on the converted data.

Background information

The following figure shows how data flows between devices and enterprise servers.

iot

In this example, a device that collects environmental data is used.

Connect a device to IoT Platform

  1. Log on to the IoT Platform console.
  2. In the left-side navigation pane, choose Devices > Products. On the Products page, click Create Product to create a product.
    Set the Data Type parameter to Custom. For other parameters, use the default values.
  3. After the product is created, click Define TSL to add TSL features. Then, publish the TSL model.
    This article provides a sample TSL model that you can import. For more information about how to import a TSL model, see Batch add TSL features.
  4. In the left-side navigation pane, click Devices. Then, click Add Device to create a device under the product.
    After the device is added, obtain the certificate information of the device. The certificate information includes ProductKey, DeviceName, and DeviceSecret.
  5. Develop a device and perform a test.
    Use Link SDK to simulate a device and submit Alink JSON data to IoT Platform. In this example, Link SDK for Node.js is used.

    For more information, see Link SDK.

    Sample code:

    const mqtt = require('aliyun-iot-mqtt');
    // 1. Specify the device certificate information.
    var options = {
        productKey:
    "g4yf***",
        deviceName:
        "Esensor",
        deviceSecret: "e14f81***",
        host:
        "iot-***.mqtt.iothub.aliyuncs.com"
    };
    // 1. Establish a connection.
    const client = mqtt.getAliyunIotMqttClient(options);
    // 2.
        Listen to commands from IoT Platform.
    client.subscribe(`/${options.productKey}/${options.deviceName}/user/get`)
    client.on('message', function(topic, message) {
        console.log("topic " + topic)
        console.log("message " + message)
    })
    setInterval(function() {
        // 3. Submit environmental data.
        client.publish(`/sys/${options.productKey}/${options.deviceName}/thing/event/property/post`, getPostData(), { qos: 0 });
    }, 5 * 1000);
    
    function getPostData() {
        const payloadJson = {
            id:
        Date.now(),
            version: "1.0",
            params:
    {
                PM25:
    Math.floor((Math.random() * 1000)),
                temperature: Math.floor((Math.random() * 60) - 10),
                humidity:
    Math.floor((Math.random() * 100)),
                co2:
    Math.floor((Math.random() * 10000)),
                hcho: Math.floor((Math.random() * 5)),
                lightLux:
    Math.floor((Math.random() * 10000))
            },
            method:
    "thing.event.property.post"
    
        }
        console.log("payloadJson " + JSON.stringify(payloadJson))
        return JSON.stringify(payloadJson);
    }
    After the device is connected to IoT Platform, you can view the device status on the Devices page. The device status is Online.

    Click View in the Actions column. Then, click TSL Data. In this example, the data type of the product is set to Custom. Therefore, the submitted TSL data is not displayed on the Status tab.

    Choose Maintenance > Device Log > Cloud run log. You can select Device-to-cloud Messages to view the submitted TSL data. The data is displayed in the hexadecimal format.

    In this example, the following data is displayed: 0xaa1fc800003710ff0005d76b15001c013400ad04ffff0400ffff18003000ff2e.

Write a data parsing script

In the IoT Platform console, you can edit, submit, and debug data parsing scripts.

  1. Log on to the IoT Platform console.In the left-side navigation pane, choose Devices > Products.
  2. On the Products page, find the product that you want to configure and click View in the Actions column.
  3. On the Product Details page, click the Data Parsing tab.
  4. On the Data Parsing tab, write a data parsing script in the Edit Script section.

    Edit the script based on the communication protocol that is used by the device. The following table shows the message body structure of the device.

    Byte Description Remarks
    12 Low byte of a PM2.5 value Returns a PM2.5 value. Valid values: 0 to 999 ug/m3.
    13 High byte of a PM2.5 value
    14 Low byte of a temperature value × 10 Returns a temperature value. Valid values: -10°C to 50°C.
    15 High byte of a temperature value × 10
    16 Low byte of a humidity value Returns a humidity value. Valid values: 0 to 99%.
    17 High byte of a humidity value
    18 Low byte of a carbon dioxide value Returns a carbon dioxide value. Valid values: 0 to 9999 mg/m3.
    19 High byte of a carbon dioxide value
    22 Low byte of a formaldehyde value × 100 Returns a formaldehyde value. Valid values: 0 to 9.99.
    23 High byte of a formaldehyde value × 100
    28 Low byte of an illuminance value Returns an illuminance value, in lux.
    29 High byte of an illuminance value

    In this example, the device only submits environmental data. Therefore, you only need to configure the rawDataToProtocol() function to parse upstream data. You do not need to configure the protocolToRawData() function.

    The following code shows a sample script:

    var PROPERTY_REPORT_METHOD = 'thing.event.property.post';
    
    // Parse upstream data in a custom format to Alink JSON data.
    function rawDataToProtocol(bytes) {
    
        var uint8Array = new Uint8Array(bytes.length);
        for (var i = 0; i < bytes.length; i++) {
            uint8Array[i] = bytes[i] & 0xff;
        }
    
        var dataView = new DataView(uint8Array.buffer, 0);
    
        var jsonMap = new Object();
    
            // The method that is used to submit properties.
            jsonMap['method'] = PROPERTY_REPORT_METHOD;
            // The version number of the protocol. Set the value to 1.0.
            jsonMap['version'] = '1.0';
            // The ID of the request.
            jsonMap['id'] = new Date().getTime();
            var params = {};
            // The number 12 or 13 indicates a PM2.5 value.
            params['PM25'] = (dataView.getUint8(13)*256+dataView.getUint8(12));
            // The number 14 or 15 indicates a temperature value.
            params['temperature'] = (dataView.getUint8(15)*256+dataView.getUint8(14))/10;
            // The number 16 or 17 indicates a humidity value.
            params['humidity'] = (dataView.getUint8(17)*256+dataView.getUint8(16));
            // The number 18 or 19 indicates a carbon dioxide value.
            params['co2'] = (dataView.getUint8(19)*256+dataView.getUint8(18));
            // The number 22 or 23 indicates a formaldehyde value.
            params['hcho'] = (dataView.getUint8(23)*256+dataView.getUint8(22))/100;
            // The number 28 or 29 indicates an illuminance value.
            params['lightLux'] = (dataView.getUint8(29)*256+dataView.getUint8(28));
    
            jsonMap['params'] = params;
    
        return jsonMap;
    }
    // Parse downstream Alink JSON data to the data in a custom format.
    function protocolToRawData(json) {
        var payloadArray = [1];// This device only submits data and cannot receive downstream commands.
        return payloadArray;
    }
    
    // Parse topic data in a custom format to Alink JSON data.
    function transformPayload(topic, rawData) {
        var jsonObj = {}
        return jsonObj;
    } 
  5. Test data parsing.
    1. Select Upstreamed Device Data in the Simulation Type field.
    2. On the Input Simulation tab, enter test data in the text box.
      You can use the hexadecimal data that is submitted by the device as the test data. To view the hexadecimal data, go to the Device Log page. Example: 0xaa1fc800003710ff0005d76b15001c013400ad04ffff0400ffff18003000ff2e.
    3. Click Run.

      The following figure shows the result on the Parsing Results tab.

      Parsing Results tab
  6. After you confirm that test data can be parsed by the script, click Submit to submit the script to IoT Platform.

After you submit the script, you can use the device SDK to debug the script. You can submit data. Then, IoT Platform uses the script to parse the data. To view the parsed data, go to the Device Details page. Choose TSL Data > Status.

View data in IoT Platform

Example of upstream TSL data

{
  "schema": "https://iotx-tsl.oss-ap-southeast-1.aliyuncs.com/schema.json",
  "profile":
  {
    "version": "1.0",
    "productKey":
    "g4***"
  },
  "properties": [
    {
      "identifier":
    "lightLux",
      "name": "illuminance",
      "accessMode":
  "rw",
      "required": false,
      "dataType":
  {
        "type": "float",
        "specs":
    {
          "min":
      "0",
          "max": "10000",
          "unit":
      "Lux",
          "unitName": "luminous flux per unit area",
          "step":
      "0.1"
        }
      }
    },
    {
      "identifier": "PM25",
      "name":
      "PM25",
      "accessMode":
      "rw",
      "required": false,
      "dataType": {
        "type":
        "int",
        "specs": {
          "min":
        "0",
          "max": "1000",
          "unit":
          "μg/m³",
          "unitName": "micrograms per cubic meter",
          "step":
          "1"
        }
      }
    },
    {
      "identifier": "hcho",
      "name":
          "formaldehyde",
      "accessMode": "rw",
      "desc":
          "HCHOValue",
      "required": false,
      "dataType": {
        "type":
          "float",
        "specs": {
          "min":
        "0",
          "max":
      "10",
          "unit":
    "ppm",
          "unitName":
    "parts per million",
          "step":
      "0.1"
        }
      }
    },
    {
      "identifier": "co2",
      "name":
      "carbon dioxide",
      "accessMode": "rw",
      "required": false,
      "dataType":
      {
        "type": "int",
        "specs":
      {
          "min":
      "0",
          "max": "10000",
          "unit":
        "mg/m³",
          "unitName": "micrograms per cubic meter",
          "step":
        "1"
        }
      }
    },
    {
      "identifier": "humidity",
      "name":
          "humidity",
      "accessMode": "rw",
      "required": false,
      "dataType":
          {
        "type": "int",
        "specs":
          {
          "min": "0",
          "max":
          "100",
          "unit": "%",
          "unitName":
          "percentage",
          "step": "1"
        }
      }
    },
    {
      "identifier":
        "temperature",
      "name":
      "temperature",
      "accessMode":
    "rw",
      "desc":
    "motor working temperature",
      "required": false,
      "dataType":
      {
        "type": "float",
        "specs":
      {
          "min": "-10",
          "max":
      "50",
          "unit": "℃",
          "step":
      "0.1"
        }
      }
    }
  ],
  "events": [
    {
      "identifier":
      "post",
      "name":
      "post",
      "type": "info",
      "required": true,
      "desc":
        "submit properties",
      "method": "thing.event.property.post",
      "outputData":
        [
        {
          "identifier": "lightLux",
          "name":
          "illuminance",
          "dataType": {
            "type":
          "float",
            "specs": {
              "min":
          "0",
              "max": "10000",
              "unit":
          "Lux",
              "unitName": "luminous flux per unit area",
          "step":
          "0.1"
            }
          }
        },
        {
          "identifier": "PM25",
          "name":
        "PM25",
          "dataType":
      {
            "type":
    "int",
            "specs":
    {
              "min":
      "0",
              "max": "1000",
              "unit":
      "μg/m³",
              "unitName": "micrograms per cubic meter",
          "step":
      "1"
            }
          }
        },
        {
          "identifier": "hcho",
          "name":
      "formaldehyde",
          "dataType":
      {
            "type": "float",
            "specs":
        {
              "min": "0",
              "max":
        "10",
              "unit": "ppm",
              "unitName":
          "parts per million",
          "step": "0.1"
            }
          }
        },
        {
          "identifier":
          "co2",
          "name": "carbon dioxide",
          "dataType":
          {
            "type": "int",
            "specs":
          {
              "min": "0",
              "max":
          "10000",
              "unit": "mg/m³",
              "unitName":
        "micrograms per cubic meter",
          "step":
      "1"
            }
          }
        },
        {
          "identifier":
    "humidity",
          "name":
    "humidity",
          "dataType":
      {
            "type": "int",
            "specs":
      {
              "min": "0",
              "max":
      "100",
              "unit": "%",
              "unitName":
      "percentage",
          "step":
      "1"
            }
          }
        },
        {
          "identifier": "temperature",
          "name":
        "temperature",
          "dataType": {
            "type":
        "float",
            "specs": {
              "min":
          "-10",
              "max": "50",
              "unit":
          "℃",
              "step": "0.1"
            }
          }
        }
      ]
    }
  ],
  "services":
          [
    {
      "identifier": "set",
      "name":
          "set",
      "required": true,
      "callType": "async",
      "desc":
          "set properties",
      "method": "thing.service.property.set",
      "inputData":
        [
        {
          "identifier":
      "lightLux",
          "name":
    "illuminance",
          "dataType":
    {
            "type":
      "float",
            "specs": {
              "min":
      "0",
              "max": "10000",
              "unit":
      "Lux",
              "unitName": "luminous flux per unit area",
          "step":
      "0.1"
            }
          }
        },
        {
          "identifier": "PM25",
          "name":
      "PM25",
          "dataType":
      {
            "type": "int",
            "specs":
        {
              "min": "0",
              "max":
        "1000",
              "unit": "μg/m³",
              "unitName":
          "micrograms per cubic meter",
          "step": "1"
            }
          }
        },
        {
          "identifier":
          "hcho",
          "name": "formaldehyde",
          "dataType":
          {
            "type": "float",
            "specs":
          {
              "min": "0",
              "max":
        "10",
              "unit":
      "ppm",
              "unitName":
    "parts per million",
          "step":
  "0.1"
            }
          }
        },
        {
          "identifier":
  "co2",
          "name": "carbon dioxide",
          "dataType":
    {
            "type":
      "int",
            "specs": {
              "min":
      "0",
              "max": "10000",
              "unit":
      "mg/m³",
              "unitName": "micrograms per cubic meter",
          "step":
      "1"
            }
          }
        },
        {
          "identifier":
      "humidity",
          "name": "humidity",
          "dataType":
      {
            "type": "int",
            "specs":
      {
              "min": "0",
              "max":
        "100",
              "unit":
          "%",
              "unitName": "percentage",
          "step":
          "1"
            }
          }
        },
        {
          "identifier": "temperature",
          "name":
          "humidity",
          "dataType": {
            "type":
            "float",
            "specs": {
              "min":
            "-10",
              "max": "50",
              "unit":
              "℃",
              "step": "0.1"
            }
          }
        }
      ],
      "outputData":
              []
    },
    {
      "identifier": "get",
      "name":
              "get",
      "required": true,
      "callType": "async",
      "desc":
              "obtain properties",
      "method": "thing.service.property.get",
      "inputData":
              [
        "lightLux",
        "PM25",
        "hcho",
        "co2",
        "humidity",
        "temperature"
      ],
      "outputData": [
        {
          "identifier":
            "lightLux",
          "name":
          "illuminance",
          "dataType":
        {
            "type":
        "float",
            "specs":
          {
              "min": "0",
              "max":
          "10000",
              "unit": "Lux",
              "unitName":
          "luminous flux per unit area",
          "step": "0.1"
            }
          }
        },
        {
          "identifier":
            "PM25",
          "name": "PM25",
          "dataType":
            {
            "type": "int",
            "specs":
              {
              "min": "0",
              "max":
              "1000",
              "unit": "μg/m³",
              "unitName":
              "micrograms per cubic meter",
          "step": "1"
            }
          }
        },
        {
          "identifier":
              "hcho",
          "name": "formaldehyde",
          "dataType":
              {
            "type": "float",
            "specs":
            {
              "min":
          "0",
              "max":
        "10",
              "unit":
        "ppm",
              "unitName":
          "parts per million",
          "step": "0.1"
            }
          }
        },
        {
          "identifier":
          "co2",
          "name": "carbon dioxide",
          "dataType":
          {
            "type": "int",
            "specs":
            {
              "min": "0",
              "max":
            "10000",
              "unit": "mg/m³",
              "unitName":
              "micrograms per cubic meter",
          "step": "1"
            }
          }
        },
        {
          "identifier":
              "humidity",
          "name": "humidity",
          "dataType":
              {
            "type": "int",
            "specs":
              {
              "min": "0",
              "max":
              "100",
              "unit": "%",
              "unitName":
            "percentage",
          "step":
          "1"
            }
          }
        },
        {
          "identifier":
        "temperature",
          "name":
        "temperature",
          "dataType":
          {
            "type": "float",
            "specs":
          {
              "min": "-10",
              "max":
          "50",
              "unit": "℃",
              "step":
            "0.1"
            }
          }
        }
      ]
    }
  ]
}