Updated on 2024-11-04 GMT+08:00

JavaScript Script-based Development

The IoT platform can encode and decode JavaScript scripts. Based on the script files you submit, the IoT platform can convert between binary and JSON formats as well as between different JSON formats. This topic uses a smoke detector as an example to describe how to develop a JavaScript codec that supports device property reporting and command delivery, and describes the format conversion requirements and debugging method of the codec.

  • JavaScript syntax rules must comply with ECMAScript 5.1 specifications.
  • The codec script supports only let and const of ECMAScript 6. Other expressions, such as the arrow function, are not supported.
  • The size of a JavaScript script cannot exceed 1 MB.
  • After the JavaScript script is deployed on a product, the JavaScript script parses upstream and downstream data of all devices under the product. When you develop a JavaScript codec, take all upstream and downstream scenarios into consideration.
  • The JSON upstream data obtained after being decoded by the JavaScript codec must meet the format requirements of the platform. For details about the format requirements, see Data Decoding Format Definition.
  • For the JSON format definition of downstream commands, see Data Encoding Format Definition. If the JavaScript codec is used for encoding, the JSON format of the platform must be converted into the corresponding binary code stream or another JSON format.
  • You can select the auto save option in the upper right corner of the script text box to let the system automatically save the scripts every 10 seconds.

Example for a Smoke Detector

Scenario

A smoke detector provides the following functions:

  • Reporting smoke alarms (fire severity) and temperature
  • Receiving and running remote control commands, which can be used to enable the alarm function remotely. For example, the smoke detector can report the temperature on the fire scene and remotely trigger a smoke alarm for evacuation.
  • The smoke detector has weak capabilities and cannot report data in JSON format defined by the device interface, but reporting simple binary data.

Product Model Definition

Define the product model on the product details page of the smoke detector.
  • level: indicates the fire severity.
  • temperature: indicates the temperature at the fire scene.
  • SET_ALARM: indicates whether to enable or disable the alarm function. The value 0 indicates that the alarm function is disabled, and the value 1 indicates that the alarm function is enabled.
    Figure 1 Model definition - smokedetector

Developing a Codec

  1. On the smoke detector details page, click the Codec Development tab and click Edit Script.

    Figure 2 Developing a codec - Script-based development

  2. Compile a script to convert binary data into JSON data. The script must implement the following methods:

    • Decode: Converts the binary data reported by a device into the JSON format defined in the product model. For details about the JSON format requirements, see Data Decoding Format Definition.
    • Encode: Converts JSON data into binary data supported by a device when the platform sends downstream data to the device. For details about the JSON format requirements, see Data Encoding Format Definition.
    The following is an example of JavaScript implemented for the current smoke detector:
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    // Upstream message types
    var MSG_TYPE_PROPERTIES_REPORT = 'properties_report'; // Device property reporting
    var MSG_TYPE_COMMAND_RSP = 'command_response'; // Command response
    var MSG_TYPE_PROPERTIES_SET_RSP = 'properties_set_response'; // Property setting response
    var MSG_TYPE_PROPERTIES_GET_RSP = 'properties_get_response'; // Property query response
    var MSG_TYPE_MESSAGE_UP = 'message_up'; // Device message reporting
    // Downstream message types
    var MSG_TYPE_COMMANDS = 'commands'; // Command delivery
    var MSG_TYPE_PROPERTIES_SET = 'properties_set'; // Property setting request
    var MSG_TYPE_PROPERTIES_GET = 'properties_get'; // Property query request
    var MSG_TYPE_MESSAGE_DOWN = 'messages'; // Platform message delivery
    // Mapping between topics and upstream message types
    var TOPIC_REG_EXP = {
        'properties_report': new RegExp('\\$oc/devices/(\\S+)/sys/properties/report'),
        'properties_set_response': new RegExp('\\$oc/devices/(\\S+)/sys/properties/set/response/request_id=(\\S+)'),
        'properties_get_response': new RegExp('\\$oc/devices/(\\S+)/sys/properties/get/response/request_id=(\\S+)'),
        'command_response': new RegExp('\\$oc/devices/(\\S+)/sys/commands/response/request_id=(\\S+)'),
        'message_up': new RegExp('\\$oc/devices/(\\S+)/sys/messages/up')
    };
    /*
    Example: When a smoke detector reports properties and returns a command response, it uses binary code streams. The JavaScript script will decode the binary code streams into JSON data that complies with the product model definition.
    Input parameters:
      payload:[0x00, 0x50, 0x00, 0x5a]
      topic:$oc/devices/cf40f3c4-7152-41c6-a201-a2333122054a/sys/properties/report
    Output:
      {"msg_type":"properties_report","services":[{"service_id":"smokerdector","properties":{"level":80,"temperature":90}}]}
    Input parameters:
      payload: [0x02, 0x00, 0x00, 0x01]
      topic: $oc/devices/cf40f3c4-7152-41c6-a201-a2333122054a/sys/commands/response/request_id=bf40f0c4-4022-41c6-a201-c5133122054a
    Output:
      {"msg_type":"command_response","result_code":0,"command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":"1"}}
    */
    function decode(payload, topic) {
        var jsonObj = {};
        var msgType = '';
       // Parse the message type based on the topic parameter, if available.
        if (null != topic) {
            msgType = topicParse(topic);
        }
        // Perform the AND operation on the payload by using 0xFF to obtain the corresponding complementary code.
        var uint8Array = new Uint8Array(payload.length);
        for (var i = 0; i < payload.length; i++) {
            uint8Array[i] = payload[i] & 0xff;
        }
        var dataView = new DataView(uint8Array.buffer, 0);
        // Convert binary data into the format used for property reporting.
        if (msgType == MSG_TYPE_PROPERTIES_REPORT) {
            // Set the value of serviceId, which corresponds to smokerdector in the product model.
            var serviceId = 'smokerdector';
            // Obtain the level value from the code stream.
            var level = dataView.getInt16(0);
            // Obtain the temperature value from the code stream.
            var temperature  = dataView.getInt16(2);
            // Convert the code stream into the JSON format used for property reporting.
            jsonObj = {"msg_type":"properties_report","services":[{"service_id":serviceId,"properties":{"level":level,"temperature":temperature}}]};
        }else if (msgType == MSG_TYPE_COMMAND_RSP) { // Convert binary data into the format used by a command response.
            // Set the value of serviceId, which corresponds to smokerdector in the product model.
            var serviceId = 'smokerdector';
            var command = dataView.getInt8(0); // Obtain the command name ID from the binary code stream.
            var command_name = '';
            if (2 == command) {
                command_name = 'SET_ALARM';
            }
            var result_code  = dataView.getInt16(1); // Obtain the command execution result from the binary code stream.
            var value = dataView.getInt8(3); // Obtain the returned value of the command execution result from the binary code stream.
           // Convert data into the JSON format used by the command response.
            jsonObj = {"msg_type":"command_response","result_code":result_code,"command_name":command_name,"service_id":serviceId,"paras":{"value":value}};
        }
        // Convert data into a string in JSON format.
        return JSON.stringify(jsonObj);
    }
    /*
    Sample data: When a command is delivered, data in JSON format on IoTDA is encoded into a binary code stream using the encode method of JavaScript.
    Input parameters ->
        {"msg_type":"commands","command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":1}}
    Output ->
        [0x01,0x00, 0x00, 0x01]
    */
    function encode(json) {
        // Convert data to a JSON object.
        var jsonObj = JSON.parse(json);
       // Obtain the message type.
        var msgType = jsonObj.msg_type;
        var payload = [];
       // Convert data in JSON format to binary data.
        if (msgType == MSG_TYPE_COMMANDS) //Command delivery
        {
            payload = payload.concat(buffer_uint8(1)); // Identify command delivery.
            if (jsonObj.command_name == 'SET_ALARM') {
                payload = payload.concat(buffer_uint8(0)); // Command name
            }
            var paras_value = jsonObj.paras.value;
            payload = payload.concat(buffer_int16(paras_value)); // Set the command property value.
        }
       // Return the encoded binary data.
        return payload;
    }
    // Parse the message type based on the topic name.
    function topicParse(topic) {
        for(var type in TOPIC_REG_EXP){
            var pattern = TOPIC_REG_EXP[type];
            if (pattern.test(topic)) {
                return type;
            }
        }
        return '';
    }
    // Convert an 8-bit unsigned integer into a byte array.
    function buffer_uint8(value) {
        var uint8Array = new Uint8Array(1);
        var dataView = new DataView(uint8Array.buffer);
        dataView.setUint8(0, value);
        return [].slice.call(uint8Array);
    }
    // Convert a 16-bit unsigned integer into a byte array.
    function buffer_int16(value) {
        var uint8Array = new Uint8Array(2);
        var dataView = new DataView(uint8Array.buffer);
        dataView.setInt16(0, value);
        return [].slice.call(uint8Array);
    }
    // Convert a 32-bit unsigned integer into a byte array.
    function buffer_int32(value) {
        var uint8Array = new Uint8Array(4);
        var dataView = new DataView(uint8Array.buffer);
        dataView.setInt32(0, value);
        return [].slice.call(uint8Array);
    }
    

  3. Debug the script online. After the script is edited, select the simulation type and enter the simulation data to debug the script online.

    1. Use the simulation device to convert binary code streams into JSON data when reporting property data.
      • Select the topic used by device property reporting: $oc/devices/{device_id}/sys/properties/report.
      • Select Decode for Simulation Type, enter the following simulated device data, and click Debug.
        0050005a
      • The script codec engine converts binary code streams into the JSON format based on input parameters and the decode method in the submitted JavaScript script, and displays the debugging result in the text box.
        Figure 3 Script-based development - Debugging and decoding
      • Check whether the debugging result meets the expectation. If the debugging result does not meet the expectation, modify the code and perform debugging again.
    2. Convert a command delivered by an application into binary code streams that can be identified by the device.
      • Select Encode for Simulation Type, enter the command delivery format to be simulated, and click Debug.
        1
        2
        3
        4
        5
        6
        7
        8
        9
        {
        	"msg_type": "commands",
        	"request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
        	"command_name": "SET_ALARM",
        	"service_id": "smokerdector",
        	"paras": {
        		"value": "1"
        	}
        }
        
      • The script codec engine converts JSON data into the binary code streams based on input parameters and the encode method in the submitted JavaScript script, and displays the debugging result in the text box.
        Figure 4 Script-based development - Debugging and coding
      • Check whether the debugging result meets the expectation. If the debugging result does not meet the expectation, modify the code and perform debugging again.

  4. Deploy the script. After confirming that the script can be correctly encoded and decoded, click Deploy to submit the script to the IoT platform so that the IoT platform can invoke the script when data is sent and received.

    Figure 5 Script-based development - Deployment

  5. Use a physical device for online debugging. Before using the script, use a real device to communicate with the IoT platform to verify that the IoT platform can invoke the script and parse upstream and downstream data.

JavaScript Codec Template

The following is an example of the JavaScript codec template. Developers need to implement the corresponding API based on the template provided by the platform.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* When a device reports data to the IoT platform, the IoT platform calls this API to decode the raw data of the device into JSON data that complies with the product model definition.
* The API name and input parameters have been defined. You only need to implement the API.
* @param byte[] payload    Original code stream reported by the device
* @param string topic      Topic to which an MQTT device reports data. This parameter is not carried when a non-MQTT device reports data.
* @return string json      JSON character string that complies with the product model definition
 */
function decode(payload, topic) {
    var jsonObj = {};
    return JSON.stringify(jsonObj);
}

/**
* When the IoT platform delivers a command, it calls this API to encode the JSON data defined in the product model into the original code stream of the device.
* The API name and input parameter format have been defined. You only need to implement the API.
* @param string json      JSON character string that complies with the product model definition
* @return byte[] payload   Original code stream after being encoded
 */
function encode(json) {
    var payload = [];
    return payload;
}

JavaScript Codec Example for MQTT Device Access

The following is an example of JavaScript codec of MQTT devices. You can convert the binary format to the JSON format in the corresponding scenario based on the example.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Upstream message types
var MSG_TYPE_PROPERTIES_REPORT = 'properties_report'; // Device property reporting
var MSG_TYPE_COMMAND_RSP = 'command_response'; // Command response
The var MSG_TYPE_PROPERTIES_SET_RSP = 'properties_set_response'; // Property setting response
var MSG_TYPE_PROPERTIES_GET_RSP = 'properties_get_response'; // Property query response
var MSG_TYPE_MESSAGE_UP = 'message_up'; // Device message reporting
// Downstream message types
var MSG_TYPE_COMMANDS = 'commands'; // Command delivery
var MSG_TYPE_PROPERTIES_SET = 'properties_set'; // Property setting request
var MSG_TYPE_PROPERTIES_GET = 'properties_get'; // Property query request
var MSG_TYPE_MESSAGE_DOWN = 'messages'; // Platform message delivery
// Mapping between topics and upstream message types
var TOPIC_REG_EXP = {
    'properties_report': new RegExp('\\$oc/devices/(\\S+)/sys/properties/report'),
    'properties_set_response': new RegExp('\\$oc/devices/(\\S+)/sys/properties/set/response/request_id=(\\S+)'),
    'properties_get_response': new RegExp('\\$oc/devices/(\\S+)/sys/properties/get/response/request_id=(\\S+)'),
    'command_response': new RegExp('\\$oc/devices/(\\S+)/sys/commands/response/request_id=(\\S+)'),
    'message_up': new RegExp('\\$oc/devices/(\\S+)/sys/messages/up')
};
/*
Example: When a smoke detector reports properties and returns a command response, it uses binary code streams. The JavaScript script will decode the binary code streams into JSON data that complies with the product model definition.
Input parameters:
  payload:[0x00, 0x50, 0x00, 0x5a]
  topic:$oc/devices/cf40f3c4-7152-41c6-a201-a2333122054a/sys/properties/report
Output:
  {"msg_type":"properties_report","services":[{"service_id":"smokerdector","properties":{"level":80,"temperature":90}}]}
Input parameters:
  payload: [0x02, 0x00, 0x00, 0x01]
  topic: $oc/devices/cf40f3c4-7152-41c6-a201-a2333122054a/sys/commands/response/request_id=bf40f0c4-4022-41c6-a201-c5133122054a
Output:
  {"msg_type":"command_response","result_code":0,"command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":"1"}}
*/
function decode(payload, topic) {
    var jsonObj = {};
    var msgType = '';
   // Parse the message type based on the topic parameter, if available.
    if (null != topic) {
        msgType = topicParse(topic);
    }
    // Perform the AND operation on the payload by using 0xFF to obtain the corresponding complementary code.
    var uint8Array = new Uint8Array(payload.length);
    for (var i = 0; i < payload.length; i++) {
        uint8Array[i] = payload[i] & 0xff;
    }
    var dataView = new DataView(uint8Array.buffer, 0);
    // Convert binary data into the format used for property reporting.
    if (msgType == MSG_TYPE_PROPERTIES_REPORT) {
        // Set the value of serviceId, which corresponds to smokerdector in the product model.
        var serviceId = 'smokerdector';
        // Obtain the level value from the code stream.
        var level = dataView.getInt16(0);
        // Obtain the temperature value from the code stream.
        var temperature = dataView.getInt16(2);
        // Convert the code stream into the JSON format used for property reporting.
        jsonObj = {
            "msg_type": "properties_report",
            "services": [{"service_id": serviceId, "properties": {"level": level, "temperature": temperature}}]
        };
    } else if (msgType == MSG_TYPE_COMMAND_RSP) { // Convert binary data into the format used by a command response.
        // Set the value of serviceId, which corresponds to smokerdector in the product model.
        var serviceId = 'smokerdector';
        var command = dataView.getInt8(0); // Obtain the command name ID from the binary code stream.
        var command_name = '';
        if (2 == command) {
            command_name = 'SET_ALARM';
        }
        var result_code  = dataView.getInt16(1); // Obtain the command execution result from the binary code stream.
        var value = dataView.getInt8(3); // Obtain the returned value of the command execution result from the binary code stream.
       // Convert data to the JSON format used by the command response.
        jsonObj = {
            "msg_type": "command_response",
            "result_code": result_code,
            "command_name": command_name,
            "service_id": serviceId,
            "paras": {"value": value}
        };
    } else if (msgType == MSG_TYPE_PROPERTIES_SET_RSP) {
       // Convert data to the JSON format used by the property setting response.
        //jsonObj = {"msg_type":"properties_set_response","result_code":0,"result_desc":"success"};
    } else if (msgType == MSG_TYPE_PROPERTIES_GET_RSP) {
       // Convert data to the JSON format used by the property query response.
        //jsonObj = {"msg_type":"properties_get_response","services":[{"service_id":"analog","properties":{"PhV_phsA":"1","PhV_phsB":"2"}}]};
    } else if (msgType == MSG_TYPE_MESSAGE_UP) {
        // Convert the code stream to the JSON format used by message reporting.
        //jsonObj = {"msg_type":"message_up","content":"hello"};
    }
    // Convert data to a character string in JSON format.
    return JSON.stringify(jsonObj);
}
/*
Sample data: When a command is delivered, JSON data on the IoT platform is encoded into binary code streams using the encode method of JavaScript.
Input parameters ->
    {"msg_type":"commands","command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":1}}
Output ->
    [0x01,0x00, 0x00, 0x01]
*/
function encode(json) {
    // Convert data to a JSON object.
    var jsonObj = JSON.parse(json);
   // Obtain the message type.
    var msgType = jsonObj.msg_type;
    var payload = [];
   // Convert data in JSON format to binary data.
    if (msgType == MSG_TYPE_COMMANDS) { // Command delivery
       // Command delivery format example: {"msg_type":"commands","command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":1}}
        // Convert the format used by command delivery to a binary code stream.
        payload = payload.concat(buffer_uint8(1)); // Identify command delivery.
        if (jsonObj.command_name == 'SET_ALARM') {
            payload = payload.concat(buffer_uint8(0)); // Command name.
        }
        var paras_value = jsonObj.paras.value;
        payload = payload.concat(buffer_int16(paras_value)); // Set the command property value.
    } else if (msgType == MSG_TYPE_PROPERTIES_SET) {
        // Property setting format example: {"msg_type":"properties_set","services":[{"service_id":"Temperature","properties":{"value":57}}]}
       // Convert the JSON format to the corresponding binary code streams if the property setting scenario is involved.
    } else if (msgType == MSG_TYPE_PROPERTIES_GET) {
        // Property query format example: {"msg_type":"properties_get","service_id":"Temperature"}
       // Convert the JSON format to the corresponding binary code streams if the property query scenario is involved.
    } else if (msgType == MSG_TYPE_MESSAGE_DOWN) {
       // Message delivery format example: {"msg_type":"messages","content":"hello"}
       // Convert the JSON format to the corresponding binary code streams if the message delivery scenario is involved.
    }
   // Return the encoded binary data.
    return payload;
}
// Parse the message type based on the topic name.
function topicParse(topic) {
    for (var type in TOPIC_REG_EXP) {
        var pattern = TOPIC_REG_EXP[type];
        if (pattern.test(topic)) {
            return type;
        }
    }
    return '';
}
// Convert an 8-bit unsigned integer into a byte array.
function buffer_uint8(value) {
    var uint8Array = new Uint8Array(1);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setUint8(0, value);
    return [].slice.call(uint8Array);
}

// Convert a 16-bit unsigned integer into a byte array.
function buffer_int16(value) {
    var uint8Array = new Uint8Array(2);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setInt16(0, value);
    return [].slice.call(uint8Array);
}
// Convert a 32-bit unsigned integer into a byte array.
function buffer_int32(value) {
    var uint8Array = new Uint8Array(4);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setInt32(0, value);
    return [].slice.call(uint8Array);
}

JavaScript Codec Example for NB-IoT Device Access

The following is an example of the JavaScript codec for NB-IoT devices. Developers can develop codecs for data reporting and command delivery of NB-IoT devices based on the example.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
// Upstream message types
var MSG_TYPE_PROPERTIES_REPORT = 'properties_report'; // Device property reporting
var MSG_TYPE_COMMAND_RSP = 'command_response'; // Command response
//Downstream message type
var MSG_TYPE_COMMANDS = 'commands'; // Command delivery
var MSG_TYPE_PROPERTIES_REPORT_REPLY = 'properties_report_reply'; // Property reporting response
// Message types
var MSG_TYPE_LIST = {
    0: MSG_TYPE_PROPERTIES_REPORT,         // In the code stream, 0 indicates device property reporting.
    1: MSG_TYPE_PROPERTIES_REPORT_REPLY, // In the code stream, 1 indicates a property reporting response.
    2: MSG_TYPE_COMMANDS,                   // In the code stream, 2 indicates platform command delivery.
    3: MSG_TYPE_COMMAND_RSP                 // In the code stream, 3 indicates a command response from the device.
};
/*
Example: When a smoke detector reports properties and returns a command response, it uses binary code streams. The JavaScript script will decode the binary code streams into JSON data that complies with the product model definition.
Input parameters:
  payload:[0x00, 0x00, 0x50, 0x00, 0x5a]
Output:
  {"msg_type":"properties_report","services":[{"service_id":"smokerdector","properties":{"level":80,"temperature":90}}]}
Input parameters:
  payload: [0x03, 0x01, 0x00, 0x00, 0x01]
Output:
  {"msg_type":"command_response","request_id":1,"result_code":0,"paras":{"value":"1"}}
*/
function decode(payload, topic) {
    var jsonObj = {};
    // Perform the AND operation on the payload by using 0xFF to obtain the corresponding complementary code.
    var uint8Array = new Uint8Array(payload.length);
    for (var i = 0; i < payload.length; i++) {
        uint8Array[i] = payload[i] & 0xff;
    }
    var dataView = new DataView(uint8Array.buffer, 0);
    // Obtain the message type from the first byte of the message code stream.
    var messageId = dataView.getInt8(0);
    // Convert binary data into the format used for property reporting.
    if (MSG_TYPE_LIST[messageId] == MSG_TYPE_PROPERTIES_REPORT) {
        // Set the value of serviceId, which corresponds to smokerdector in the product model.
        var serviceId = 'smokerdector';
        // Obtain the level value from the code stream.
        var level = dataView.getInt16(1);
        // Obtain the temperature value from the code stream.
        var temperature  = dataView.getInt16(3);
        // Convert data to the JSON format used by property reporting.
        jsonObj = {"msg_type":"properties_report","services":[{"service_id":serviceId,"properties":{"level":level,"temperature":temperature}}]};
    }else if (MSG_TYPE_LIST[messageId] == MSG_TYPE_COMMAND_RSP) { // Convert binary data to the format used by a command response.
        var requestId = dataView.getInt8(1);
        var result_code  = dataView.getInt16(2); // Obtain the command execution result from the binary code stream.
        var value = dataView.getInt8(4); // Obtain the returned value of the command execution result from the binary code stream.
       // Convert data to the JSON format used by the command response.
        jsonObj = {"msg_type":"command_response","request_id":requestId,"result_code":result_code,"paras":{"value":value}};
    }
    // Convert data to a character string in JSON format.
    return JSON.stringify(jsonObj);
}
/*
Sample data: When a command is delivered, data in JSON format on IoTDA is encoded into a binary code stream using the encode method of JavaScript.
Input parameters ->
    {"msg_type":"commands","request_id":1,"command_name":"SET_ALARM","service_id":"smokerdector","paras":{"value":1}}
Output ->
    [0x02, 0x00, 0x00, 0x00, 0x01]
Sample data: When a response is returned for property reporting, data in JSON format on the platform is encoded into a binary code stream using the encode method of JavaScript.
Input parameters ->
    {"msg_type":"properties_report_reply","request":"000050005a","result_code":0}
Output ->
    [0x01, 0x00]
*/
function encode(json) {
    // Convert data to a JSON object.
    var jsonObj = JSON.parse(json);
   // Obtain the message type.
    var msgType = jsonObj.msg_type;
    var payload = [];
   //Convert data in JSON format to binary data.
    if (msgType == MSG_TYPE_COMMANDS) { // Command delivery
        payload = payload.concat(buffer_uint8(2)); // Command delivery
        payload = payload.concat(buffer_uint8(jsonObj.request_id)); // Command ID
        if (jsonObj.command_name == 'SET_ALARM') {
            payload = payload.concat(buffer_uint8(0)); // Command name
        }
        var paras_value = jsonObj.paras.value;
        payload = payload.concat(buffer_int16(paras_value)); // Set the command property value.
    } else if (msgType == MSG_TYPE_PROPERTIES_REPORT_REPLY) { // Response for device property reporting
        payload = payload.concat(buffer_uint8(1)); // Response to property reporting
        if (0 == jsonObj.result_code) {
            payload = payload.concat(buffer_uint8(0)); // The property reporting message is successfully processed.
        }
    }
   // Return the encoded binary data.
    return payload;
}
// Convert an 8-bit unsigned integer into a byte array.
function buffer_uint8(value) {
    var uint8Array = new Uint8Array(1);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setUint8(0, value);
    return [].slice.call(uint8Array);
}
// Convert a 16-bit unsigned integer into a byte array.
function buffer_int16(value) {
    var uint8Array = new Uint8Array(2);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setInt16(0, value);
    return [].slice.call(uint8Array);
}
// Convert a 32-bit unsigned integer into a byte array.
function buffer_int32(value) {
    var uint8Array = new Uint8Array(4);
    var dataView = new DataView(uint8Array.buffer);
    dataView.setInt32(0, value);
    return [].slice.call(uint8Array);
}

Requirements on the JavaScript Codec Format

Data Decoding Format Definition

In the data parsing scenario, when the platform receives data from a device, it sends the binary code stream in the payload to the JavaScript script by using the decode method. The script calls the decode method to decode the data to the JSON format defined in the product model. The platform has the following requirements on the parsed JSON data:

  • Device Reporting Properties
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    {
        "msg_type": "properties_report",
        "services": [{
            "service_id": "Battery",
            "properties": {
                "batteryLevel": 57
            },
            "event_time": "20151212T121212Z"
        }]
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    Indicates the message type. The value is fixed at properties_report.

    services

    Yes

    List<ServiceProperty>

    List of device services. For details, see the ServiceProperty structure table.

    ServiceProperty structure

    Field

    Mandatory

    Type

    Description

    service_id

    Yes

    String

    Identifies a service of the device.

    properties

    Yes

    Object

    Indicates service properties, which are defined in the product model associated with the device.

    event_time

    No

    String

    Indicates the UTC time when the device reports data. The format is yyyyMMddTHHmmssZ, for example, 20161219T114920Z.

    If this parameter is not carried in the reported data or is in incorrect format, the time when the platform receives the data is used.

  • Response for device property setting
    1
    2
    3
    4
    5
    6
    {
       "msg_type": "properties_set_response",
       "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
       "result_code": 0,
       "result_desc": "success"
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    Indicates the message type. The value is fixed at properties_set_response.

    request_id

    No

    String

    Uniquely identifies a request. If this parameter is carried in a message received by a device, the parameter value must be carried in the response sent to the platform. If the decoded message does not contain this field, the value of request_id in the topic is used.

    result_code

    No

    Integer

    Indicates the command execution result. 0 indicates a successful execution, whereas other values indicate an execution failure. If this parameter is not carried, the execution is considered successful.

    result_desc

    No

    String

    Indicates the description of the response to the request for setting properties.

  • Response for device property query
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    {
    "msg_type": "properties_get_response",
    "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
        "services": [
            {
                "service_id": "analog",
                "properties": {
                    "PhV_phsA": "1",
                    "PhV_phsB": "2"
                },
                "event_time": "20190606T121212Z"
            }
        ]
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at properties_get_response.

    request_id

    No

    String

    Uniquely identifies a request. If this parameter is carried in a message received by a device, the parameter value must be carried in the response sent to the platform. If the decoded message does not contain this field, the value of request_id in the topic is used.

    services

    Yes

    List<ServiceProperty>

    List of device services. For details, see the ServiceProperty structure table.

    ServiceProperty structure

    Field

    Mandatory

    Type

    Description

    service_id

    Yes

    String

    Identifies a service of the device.

    properties

    Yes

    Object

    Indicates service properties, which are defined in the product model associated with the device.

    event_time

    No

    String

    Indicates the UTC time when the device reports data. The format is yyyyMMddTHHmmssZ, for example, 20161219T114920Z.

    If this parameter is not carried in the reported data or is in incorrect format, the time when the platform receives the data is used.

  • Response for the platform to deliver a command
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    {
      "msg_type": "command_response",
      "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
       "result_code": 0,
      "command_name": "ON_OFF",
      "service_id": "WaterMeter",
      "paras": {
        "value": "1"
      }  
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at command_response.

    request_id

    No

    String

    Uniquely identifies a request. If this parameter is carried in a message received by a device, the parameter value must be carried in the response sent to the platform. If the decoded message does not contain this field, the value of request_id in the topic is used.

    result_code

    No

    Integer

    Indicates the command execution result. 0 indicates a successful execution, whereas other values indicate an execution failure. If this parameter is not carried, the execution is considered successful.

    response_name

    No

    String

    Indicates the response name, which is defined in the product model associated with the device.

    paras

    No

    Object

    Indicates the response parameters, which are defined in the product model associated with the device.

  • Device message reporting
    1
    2
    3
    4
    {
      "msg_type": "message_up",
      "content": "hello"
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at message_up.

    content

    No

    String

    Message content.

Data Encoding Format Definition

In the data parsing scenario, when the IoT platform delivers a command, it sends the data in JSON format defined by the product model to the JavaScript script using the encode method. The script calls the encode method to encode the data in JSON format into binary code streams that can be identified by the device. During encoding, the JSON format transferred from the platform to the script is as follows:

  • Command delivery
    1
    2
    3
    4
    5
    6
    7
    8
    9
    { 
      "msg_type": "commands", 
       "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
      "command_name": "ON_OFF", 
      "service_id": "WaterMeter", 
      "paras": { 
        "value": 1
      } 
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at commands.

    request_id

    Yes

    String

    Uniquely identifies a request. The ID is delivered to the device through a topic.

    service_id

    No

    String

    Identifies a service of the device.

    command_name

    No

    String

    Indicates the device command name, which is defined in the product model associated with the device.

    paras

    No

    Object

    Indicates the command execution parameters, which are defined in the product model associated with the device.

  • Setting Device Properties
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    { 
    "msg_type": "properties_set",
    "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
        "services": [{ 
                "service_id": "Temperature", 
                "properties": { 
                    "value": 57 
                } 
            }, 
            { 
                "service_id": "Battery", 
                "properties": { 
                    "level": 80 
                } 
            } 
        ] 
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at properties_set.

    request_id

    Yes

    String

    Uniquely identifies a request. If this parameter is carried in a message received by a device, the parameter value must be carried in the response sent to the platform.

    services

    Yes

    List<ServiceProperty>

    Indicates a list of device service data.

    ServiceProperty structure

    Field

    Mandatory

    Type

    Description

    service_id

    Yes

    String

    Identifies a service of the device.

    properties

    Yes

    Object

    Indicates service properties, which are defined in the product model associated with the device.

  • Querying device properties
    1
    2
    3
    4
    5
    { 
       "msg_type": "properties_get",
       "request_id": "42aa08ea-84c1-4025-a7b2-c1f6efe547c2",
       "service_id": "Temperature" 
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at properties_get.

    request_id

    Yes

    String

    Uniquely identifies a request. The ID is delivered to the device through a topic.

    service_id

    No

    String

    Identifies a service of the device.

  • Response for property reporting (response to property reporting during NB-IoT device access)
    1
    2
    3
    4
    5
    { 
      "msg_type": "properties_report_reply",
      "request": "213355656",
      "result_code": 0
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at properties_report_reply.

    request

    No

    String

    Base64-encoded string of property reporting.

    result_code

    No

    Integer

    Execution result of property reporting.

    has_more

    No

    Boolean

    Whether a cache command exists.

  • Message delivery
    1
    2
    3
    4
    { 
      "msg_type": "messages",
      "content": "hello"
    }
    

    Field

    Mandatory

    Type

    Description

    msg_type

    Yes

    String

    The value is fixed at messages.

    content

    No

    String

    Content of command delivery.