IoT Hub
IoT Hub Documentation
Documentation > Integrations > UDP
Getting Started
Devices Library Guides API FAQ
On this page

UDP Integration

UDP Integration allows to stream data from devices which use a UDP protocol to IoT Hub and converts payloads of these devices into the IoT Hub format.

Please review the integration diagram to learn more.

image

Prerequisites

In this tutorial, we will use:

  • The instance of the iothub.magenta.at installed locally;
  • UDP integration, running externally and connected to the IoT Hub instance;

  • echo command which intended to display a line of text, and will redirect it’s output to netcat (nc) utility;
  • netcat (nc) utility to establish UDP connections, receive data from there and transfer them;

Suppose we have a sensor sending current temperature and humidity readings. Sensor SN-001 sends data to UDP integration on port 11560 of the machine where the UDP integration is running.

For demo purposes we assume that our device is smart enough to send data in 4 different payload types. You can select payload type based on your device capabilities and business cases:

In this case, the payload looks like this:

1
SN-001,default,temperature,25.7,humidity,69

In this case, the payload looks like this:

1
2
3
4
5
6
{
  "deviceName": "SN-001",
  "deviceType": "default",
  "temperature": 25.7,
  "humidity": 69
}

In this case, the payload looks like this:

1
\x53\x4e\x2d\x30\x30\x31\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x36\x39

Here is the description of the bytes in this payload:

  • 0-5 bytes - \x53\x4e\x2d\x30\x30\x31 - device name. If we convert it to text - SN-001;
  • 6-12 bytes - \x64\x65\x66\x61\x75\x6c\x74 - device type. If we convert it to text - default;
  • 13-16 bytes - \x32\x35\x2e\x37 - temperature telemetry. If we convert it to text - 25.7;
  • 17-18 bytes - \x36\x39 - humidity telemetry. If we convert it to text - 69.

In this case payload is hexadecimal string:

1
534e2d30303164656661756c7432352e373639

Here is the description of the bytes in this payload:

  • 0-5 bytes - 534e2d303031 - device name. If we convert it to text - SN-001;
  • 6-12 byte - 64656661756c74 - device type. If we convert it to text - default;
  • 13-16 byte - 32352e37 - temperature telemetry. If we convert it to text: - 25.7;
  • 17-18 byte - 3639 - humidity telemetry. If we convert it to text: - 69.

Add UDP integration

1. Basic settings.

Go to the “Integrations” page of the “Integrations center” section. Click “plus” button to start adding new integration. Select type “UDP” integration and click “Next”;

image


2. Uplink data converter.

An uplink converter that is a script for parsing and transforming the data received by UDP integration to format that IoT Hub uses. deviceName and deviceType are required, while attributes and telemetry are optional. attributes and telemetry are flat key-value objects. Nested objects are not supported.

Choose device payload type to for decoder configuration:

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Now copy the following TBEL script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/** Decoder **/

// decode payload to string
var strArray = decodeToString(payload);
var payloadArray = strArray.replaceAll("\"", "").replaceAll("\\\\n", "").split(',');

var telemetryPayload = {};
for (var i = 2; i < payloadArray.length; i = i + 2) {
    var telemetryKey = payloadArray[i];
    var telemetryValue = parseFloat(payloadArray[i + 1]);
    telemetryPayload[telemetryKey] = telemetryValue;
}

// Result object with device attributes/telemetry data
var result = {
    deviceName: payloadArray[0],
    deviceType: payloadArray[1],
    telemetry: telemetryPayload,
    attributes: {}
};

/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/

return result;


If you want to use the JavaScript decoder function, use this script:

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
/** Decoder **/

// decode payload to string
var strArray = decodeToString(payload);
var payloadArray = strArray.replace(/\"/g, "").replace(/\s/g, "").replace(/\\n/g, "").split(',');

var telemetryPayload = {};
for (var i = 2; i < payloadArray.length; i = i + 2) {
    var telemetryKey = payloadArray[i];
    var telemetryValue = parseFloat(payloadArray[i + 1]);
    telemetryPayload[telemetryKey] = telemetryValue;
}

// Result object with device attributes/telemetry data
var result = {
    deviceName: payloadArray[0],
    deviceType: payloadArray[1],
    telemetry: telemetryPayload,
    attributes: {}
  };

/** Helper functions **/

function decodeToString(payload) {
   return String.fromCharCode.apply(String, payload);
}

return result;


Paste the copied script to the decoder function section. Then, click “Next”;

image

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Now copy the following TBEL script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/** Decoder **/

// decode payload to JSON
var data = decodeToJson(payload);

// Result object with device/asset attributes/telemetry data

var deviceName = data.deviceName;
var deviceType = data.deviceType;
var result = {
    deviceName: deviceName,
    deviceType: deviceType,
    attributes: {},
    telemetry: {
        temperature: data.temperature,
        humidity: data.humidity
    }
};

/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/

return result;


If you want to use the JavaScript decoder function, use this script:

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
/** Decoder **/

// decode payload to JSON
var data = decodeToJson(payload);

// Result object with device/asset attributes/telemetry data

var deviceName = data.deviceName;
var deviceType = data.deviceType;
var result = {
    deviceName: deviceName,
    deviceType: deviceType,
    attributes: {},
    telemetry: {
        temperature: data.temperature,
        humidity: data.humidity
   }
};

/** Helper functions **/

function decodeToString(payload) {
   return String.fromCharCode.apply(String, payload);
}

function decodeToJson(payload) {
   // covert payload to string.
   var str = decodeToString(payload);

   // parse string to JSON
   var data = JSON.parse(str);
   return data;
}

return result;


Paste the copied script to the decoder function section. Then, click “Next”;

image

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Now copy the following TBEL script:

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
/** Decoder **/

// decode payload to string
var payloadStr = decodeToString(payload);

// decode payload to JSON
// var data = decodeToJson(payload);

var deviceName = payloadStr.substring(0,6);
var deviceType = payloadStr.substring(6,13);

// Result object with device/asset attributes/telemetry data
var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   attributes: {},
   telemetry: {
       temperature: parseFloat(payloadStr.substring(13,17)),
       humidity: parseFloat(payloadStr.substring(17,19))
   }
};

/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/

return result;


If you want to use the JavaScript decoder function, use this script:

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
/** Decoder **/

// decode payload to string
var payloadStr = decodeToString(payload);

// decode payload to JSON
// var data = decodeToJson(payload);

var deviceName = payloadStr.substring(0,6);
var deviceType = payloadStr.substring(6,13);

// Result object with device/asset attributes/telemetry data
var result = {
   deviceName: deviceName,
   deviceType: deviceType,
   attributes: {},
   telemetry: {
       temperature: parseFloat(payloadStr.substring(13,17)),
       humidity: parseFloat(payloadStr.substring(17,19))
   }
};

/** Helper functions **/

function decodeToString(payload) {
   return String.fromCharCode.apply(String, payload);
}

function decodeToJson(payload) {
   // covert payload to string.
   var str = decodeToString(payload);

   // parse string to JSON
   var data = JSON.parse(str);
   return data;
}

return result;


Paste the copied script to the decoder function section. Then, click “Next”;

image

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

Now copy the following TBEL script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/** Decoder **/

// decode payload to JSON
var data = decodeToJson(payload).reports[0].value;

// Result object with device telemetry data
var result = {
    deviceName: hexToString(data.substring(0, 12)),
    deviceType: hexToString(data.substring(12, 26)),
    telemetry: {
        temperature: parseFloat(hexToString(data.substring(26, 34))),
        humidity: parseFloat(hexToString(data.substring(34, 38))),
    }
};

/** Helper functions **/

// Hexadecimal string to string
function hexToString(hex) {
    return bytesToString(hexToBytes(hex));
}

return result;


If you want to use the JavaScript decoder function, use this script:

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
/** Decoder **/

// decode payload to JSON
var data = decodeToJson(payload).reports[0].value;

// Result object with device telemetry data
var result = {
    deviceName: hexToString(data.substring(0, 12)),
    deviceType: hexToString(data.substring(12, 26)),
    telemetry: {
        temperature: parseFloat(hexToString(data.substring(26, 34))),
        humidity: parseFloat(hexToString(data.substring(34, 38))),
    }
};

/** Helper functions **/

function decodeToString(payload) {
    return String.fromCharCode.apply(String, payload);
}

// Hexadecimal string to string
function hexToString(hex) {
    var str = '';
    for (var i = 0; i < hex.length; i += 2) {
        var notNullValue = parseInt(hex.substr(i, 2), 16);
        if (notNullValue) {
            str += String.fromCharCode(notNullValue);
        }
    }
    return str;
}

function decodeToJson(payload) {
    // convert payload to string.
    var str = decodeToString(payload);

    // parse string to JSON
    var data = JSON.parse(str);
    return data;
}

return result;


Paste the copied script to the decoder function section. Then, click “Next”;

image

3. Downlink data converter.

At the step of adding a downlink converter, you can also select a previously created or create a new downlink converter. But for now, leave the “Downlink data converter” field empty. Click “Skip”;

image


4. Connection.

As we mentioned earlier, “Execute remotely” option is checked and can not be modified - UDP Integration can be only remote type.

By default, UDP Integration will use 11560 port, but you can change this to any available port in your case.

Please note down Integration key and Integration secret - we will use these values later in the configuration on the remote UDP Integration itself.

We leave the Enable broadcast - integration will accepts broadcast address packets options by default. This flag indicates that integration will accept UDP packets sent to the broadcast address.


Choose device payload type for Handler Configuration:

Please select Handler Type as TEXT.

image

To parse the payload properly, please make sure that next values are set:

  • Charset Name - incoming bytes will be converted to string using provided charset; Leave it by default for this demo - UTF-8;

Click “Add” to finish adding integration.

image

Please select Handler Type as JSON.

image

Click “Add” to finish adding integration.

image

Please select Handler Type as BINARY.

image

Click “Add” to finish adding integration.

image

Please select Handler Type as HEX.

image

Click “Add” to finish adding integration.

image

Installing and running external UDP integration

Please refer to the remote integration guide and install UDP integration service locally or on separate machine.

Use Integration key and Integration secret from the above section for your UDP integration configuration.

Once IoT Hub UDP integration has been created, the UDP server starts, and then it waits for data from the devices.

Choose device payload type to send uplink message:

Once you go to “Devices” page you should find a SN-001 device provisioned by the UDP integration. Click the device, navigate to the “Latest telemetry” tab to see the “temperature” key and its value (25.7) there and also the “humidity” key and its value (69) there as well.

image

For sending Downlink messages from IoT Hub to the device, we need to define a downlink converter.

One can use either TBEL (ThingsBoard expression language) or JavaScript to develop user defined functions. We recommend utilizing TBEL as it’s execution in ThingsBoard is much more efficient compared to JS.

To add a downlink data converter to the UDP integration, follow these steps:

  • Go to the “Integrations” page, click UDP integration to open its details, and enter integration editing mode by clicking the “pencil” icon;

  • Enter a name for the downlink data converter and click “Create new converter”;

  • Paste the script to the encoder function section, and click “Add”;

  • Apply changes.

Modify Root Rule Chain

When integration configured and ready to use, we need to go to “Rule Chains” page and configure the “Root Rule Chain” so that messages like “Attributes updated” and “Post attributes” are forwarded to the downlink data converter:

  • In the Root Rule Chain editor, find the “integration downlink” node and drag it to the rule chain;

  • Name it “UDP Downlink”, specify our “UDP integration”, and click “Add”;

  • Drag the connection from the “message type switch” node to the “UDP integration” node with “Attributes updated” and “Post attributes” labels. Save all changes;

To test downlink, create some shared attribute on your device:

  • Go to the “Devices” page. Click your device and navigate to the “Attributes” tab. Select the “Shared attributes” option, and click the “plus” icon;

  • Enter the attribute name, and its value (for example, the key name is “firmware”, value: “v1.1”) and click “Save”;

To receive a downlink message you need to set the timeout for responses -w10 (this option determines how long you will wait for a response) and send the uplink message again:

1
echo -e 'SN-001,default,temperature,25.7,humidity,69' | nc -w10 -u 127.0.0.1 11560

You should get the following response from the IoT Hub in the terminal:

image

Next steps