Skip to main content
Version: v4.6

Normalization script

Create a normalization script to take raw IoT data and output the data in the data structure for readings on the platform.

Output data structure#

Your normalization script must transform the raw IoT data to the following format:

{  "readings": [    {      // IoT reading data goes here​      "_ts": "",      "_tsMetadata": {        "_sourceId": ""      }    }  ]}
PropertyTypeDescriptionRequired
"readings"Array of ObjectsContains an array of reading objects, which also contain a timestamp and metadata.Required
"_ts"StringA timestamp you createRequired
"_tsMetadata"ObjectCreate an object that contains a "_sourceId" property.Required
"_sourceId"StringContains the source id of the sensor that takes the reading.Required

Input and output data examples#

Raw IoT input data#

{  "type": "text",  "messageId": "ID:activemq-39563-1689584032552-5:4:-1:1:1",  "correlationId": null,  "destination": {    "type": "queue",    "name": "Consumer.<ANY_STRING>.VirtualTopic.lnt_RfmbfrED"  },  "replyTo": null,  "priority": 4,  "expiration": 0,  "timestamp": 1689584797284,  "redelivered": false,  "properties": {    "ActiveMQ.MQTT.QoS": {      "type": "integer",      "boolean": null,      "byte": null,      "short": null,      "integer": 0,      "long": null,      "float": null,      "double": null,      "string": null    }  },  "payloadText": "{\"from\":\"BLE\",\"mac\":\"30:ae:7b:e1:f5:28\",\"to\":\"GATEWAY\",\"time\":1689584797,\"deviceCode\":\"01012354-ad7d-4a0a-91db-a08435b7c9e3\", \"type\":\"reportAttribute\",\"data\":{\"value\":{\"device_list\":[{\"data\":\"0201061AFF5B07050305730073005E27D80085018E04AA023A079B0C000011079ECADC240EE5A9E093F3A3B50100406E09094869626F75414952\",\"modelstr\":\"HibouAIRe\",\"scan_rssi\":-51,\"Board_id\":\"5d9f693f-6f95-4ea5-a610-5fe7bf061f40\",\"ble_addr\":\"E8:E5:ED:BE:5E:D9\",\"addr_type\":1,\"scan_time\":1684043612,\"CO2\":0,\"HibouType\":\"PM\",\"dev_name\":\"HibouAIR\",\"ALS\":115,\"PM1.0\":\"68.200\",\"PM2.5\":\"185.000\",\"Pressure\":\"1007.800\",\"PM10\":\"322.700\",\"Temperature\":\"21.600\",\"Humidity\":\"38.900\",\"VOC\":1166,\"connectable\":1}]},\"attribute\":\"mod.device_list\",\"mac\":\"30:ae:7b:e1:f5:28\"},\"count\":1,\"name\":\"kafka-telemetry-1_sXrwGTdXah_timeseries\",\"id\":\"1-1\",\"csv\":\"execution7.csv\"}"}

Normalized data output#

{  "readings": [    {      "data": "0201061AFF5B07050305730073005E27D80085018E04AA023A079B0C000011079ECADC240EE5A9E093F3A3B50100406E09094869626F75414952",      "modelstr": "HibouAIRe",      "scan_rssi": -51,      "Board_id": "5d9f693f-6f95-4ea5-a610-5fe7bf061f40",      "ble_addr": "E8:E5:ED:BE:5E:D9",      "addr_type": 1,      "scan_time": 1684043612,      "CO2": 0,      "HibouType": "PM",      "dev_name": "HibouAIR",      "ALS": 115,      "PM1.0": "68.200",      "PM2.5": "185.000",      "Pressure": "1007.800",      "PM10": "322.700",      "Temperature": "21.600",      "Humidity": "38.900",      "VOC": 1166,      "connectable": 1,      "_ts": "2023-05-14T05:53:32.000Z",      "_tsMetadata": {        "_sourceId": "5d9f693f-6f95-4ea5-a610-5fe7bf061f40"      }    }  ]}

Creating a normalization script#

The following procedure creates the script that transforms the raw IoT input data to the normalized output in the previous example:

Important: Only use the var keyword to create variables, do not use const or let.

Important: Do not use console logging functions in your script.

Note: You can use arrow functions.

To skip to the final script, see Script example.

  1. Create a functions object to contain your constructReadings and normalize methods.

    var functions = {
    }
  2. In the functions object, create a normalize method that takes a string message as its parameter.

    ...  normalize: function(strMessage) {
      }
  3. In the normalize method, parse the string message parameter.

      ...    var message = JSON.parse(strMessage);    var payloadText = message.payloadText;    var payload = JSON.parse(payloadText);    var data = payload.data.value.device_list;
  4. Create a readings array to push normalized readings to.

        ...    var readings = [];
  5. Construct a readings object for each device using a constructReadings method you define later, then push the object to the readings array.

        ...    data.forEach(d => {        var readingsObj = {...d, ...this.constructReadings(d.Board_id, d.scan_time)};        readings.push(readingsObj)    });
  6. Declare a constructReadings method that takes the reading's source id and timestamp as parameters.

    ...  constructReadings: (sourceId, ts) => {
      }
  7. In the constructReadings method, create a new Date object based on the timestamp parameter multiplied by 1000.

      ...    var date = new Date(ts*1000);
    
  8. In the constructReadings function, construct a readings object with "_ts", "_tsMetadata", and "_tsMetadata._sourceId" properties, then return that object.

      ...    var readingsObj = {      "_ts": date.toISOString(),      "_tsMetadata":{        "_sourceId":sourceId      }    };    return readingsObj;
    

Script example#


var functions = {  normalize: function(strMessage){    var message = JSON.parse(strMessage);    var payloadText=message.payloadText;    var payload = JSON.parse(payloadText);    if (typeof payload === 'string') {         payload = JSON.parse(payload);    }    var data = payload.data.value.device_list;    
    var readings = [];      data.forEach(d => {        var readingsObj = {...d, ...this.constructReadings(d.Board_id, d.scan_time)};        readings.push(readingsObj)    });
    var result = {readings};    return JSON.stringify(result);  },  constructReadings: (sourceId, ts) => {    var date = new Date(ts*1000);    var readingsObj = {      "_ts": date.toISOString(),      "_tsMetadata":{          "_sourceId":sourceId      }    };    return readingsObj;  }}

Normalization script invocation#


let s = {"type":"text","messageId":"ID:activemq-39563-1689584032552-5:4:-1:1:1","correlationId":null,"destination":{"type":"queue","name":"Consumer.<ANY_STRING>.VirtualTopic.lnt_RfmbfrED"},"replyTo":null,"priority":4,"expiration":0,"timestamp":1689584797284,"redelivered":false,"properties":{"ActiveMQ.MQTT.QoS":{"type":"integer","boolean":null,"byte":null,"short":null,"integer":0,"long":null,"float":null,"double":null,"string":null}},"payloadText":"{\"from\":\"BLE\",\"mac\":\"30:ae:7b:e1:f5:28\",\"to\":\"GATEWAY\",\"time\":1689584797,\"deviceCode\":\"01012354-ad7d-4a0a-91db-a08435b7c9e3\",\"type\":\"reportAttribute\",\"data\":{\"value\":{\"device_list\":[{\"data\":\"0201061AFF5B07050305730073005E27D80085018E04AA023A079B0C000011079ECADC240EE5A9E093F3A3B50100406E09094869626F75414952\",\"modelstr\":\"HibouAIRe\",\"scan_rssi\":-51,\"Board_id\":\"5d9f693f-6f95-4ea5-a610-5fe7bf061f40\",\"ble_addr\":\"E8:E5:ED:BE:5E:D9\",\"addr_type\":1,\"scan_time\":1684043612,\"CO2\":0,\"HibouType\":\"PM\",\"dev_name\":\"HibouAIR\",\"ALS\":115,\"PM1.0\":\"68.200\",\"PM2.5\":\"185.000\",\"Pressure\":\"1007.800\",\"PM10\":\"322.700\",\"Temperature\":\"21.600\",\"Humidity\":\"38.900\",\"VOC\":1166,\"connectable\":1}]},\"attribute\":\"mod.device_list\",\"mac\":\"30:ae:7b:e1:f5:28\"},\"count\":1,\"name\":\"kafka-telemetry-1_sXrwGTdXah_timeseries\",\"id\":\"1-1\",\"csv\":\"execution7.csv\"}","payloadMap":null,"payloadBytes":null};
let res = functions.normalize(JSON.stringify(s));console.log(res);