Stand with Ukraine flag
Try it now Pricing
Cloud
Community Edition Professional Edition Cloud Edge PE Edge IoT Gateway License Server Trendz Analytics Mobile Application PE Mobile Application MQTT Broker
Documentation > Integrations > UDP
Getting Started
Devices Library Guides API FAQ
On this page

UDP Integration

Doc info icon
ThingsBoard PE Feature

Only Professional Edition supports Platform Integrations feature.
Use ThingsBoard Cloud or install your own platform instance.

Overview

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

Please note UDP Integration can be started only as Remote Integration. It could be started on the same machine, where TB instance is running, or you can start in on another machine, that has access over the network to the TB instance.

Please review the integration diagram to learn more.

image

UDP Integration Configuration

Prerequisites

In this tutorial, we will use:

  • ThingsBoard Professional Edition instance — thingsboard.cloud;

  • UDP Integration, running externally and connected to the cloud ThingsBoard PE 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;

Let’s assume that we have a sensor which is sending current temperature and humidity readings. Our sensor device SN-001 publishes it’s temperature and humidity readings to UDP Integration on 11560 port to the machine where UDP Integration is running.

For demo purposes we assume that our device is smart enough to send data in 4 different payload types:

  • Text - in this case payload is:
1
SN-001,default,temperature,25.7,humidity,69
  • JSON - in this case payload is:
1
2
3
4
5
6
7
{
  "deviceName": "SN-001",
  "deviceType": "default",
  "temperature": 25.7,
  "humidity": 69
}

  • Binary - in this case, the payload looks like this (in HEX string):
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.
  • Hex - 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.

You can select payload type based on your device capabilities and business cases.

Doc info icon

Please note
On the machine, where UDP Integration is running, port 11560 must be opened for incoming connections - nc utility must be able to connect to UDP socket. In case you are running it locally, it should be fine without any additional changes.

Before setting up an UDP integration, you need to create an Uplink Converter that is a script for parsing and transforming the data received by UDP integration to format that ThingsBoard 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.

To create an Uplink Converter go to Data Converters section and Click Add new data converter —> Create new converter. Name it “UDP Uplink Converter” and select type Uplink. Use debug mode for now.

Doc info icon

NOTE
Although the Debug mode is very useful for development and troubleshooting, leaving it enabled in production mode may tremendously increase the disk space, used by the database, because all the debugging data is stored there. It is highly recommended to turn the Debug mode off when done debugging.

Choose device payload type to for decoder configuration:

  • Text payload

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 & paste the following script to the Decoder function section:

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;

image

Now copy & paste the following script to the Decoder function section:

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;

image

  • JSON payload

Now copy & paste the following script to the Decoder function section:

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;

image

Now copy & paste the following script to the Decoder function section:

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;

image

  • Binary payload

Now copy & paste the following script to the Decoder function section:

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;

image

Now copy & paste the following script to the Decoder function section:

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;

image

  • Hex payload

Now copy & paste the following script to the Decoder function section:

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;

image

Now copy & paste the following script to the Decoder function section:

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;

image

UDP Integration Setup

  • Go to Integrations section and click Add new integration button. Name it UDP Integration, select type UDP;

image

  • Add recently created UDP Uplink Converter;

image

  • For now, leave the “Downlink Data Converter” field blank.

image

As you mentioned Execute remotely 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 other options by default, but there is brief description of them:

  • Enable broadcast - integration will accepts broadcast address packets - a flag indicating that integration will accept UDP packets that were sent to broadcast address;
  • Size of the buffer for inbound socket - the size in KBytes of the socket data receive buffer;

Choose device payload type for Handler Configuration

Please select Handler Type as TEXT

image

To parse 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;

Please select Handler Type as JSON

image

Please select Handler Type as BINARY

image

Please select Handler Type as HEX

image

Click Add to save the 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.

Please use Integration key and Integration secret from the above section for your UDP Integration configuration.

Once ThingsBoard 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 Device Groups -> All you should find a SN-001 device provisioned by the Integration. Click on the device, go 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

Create Downlink Converter in Data converters. To see events - enable Debug.

Now you have to add a converter to the integration, optionally configure Cache Size and Cache time to live in minutes (able just for UDP Downlink).

Doc info icon

Cache size and Time to live - features, that helps to avoid memory leak when we are storing connections.
Cache time to live - time to storage messages.
Cache size - maximum size of messages for UDP client.

image


When integration configured and ready to use, we need to go to Rule Chains, choose ‘Root Rule Chain’ and here create rule node Integration Downlink. Input here some name, choose which integration you need to use and tap Add.

image

After this steps, we need to tap on a right grey circle of rule node message type switch and drag this circle to left side of ‘Integration Downlink’, here lets choose Attribute Update, tap ‘Add’ and save Rule node. That’s it!

image

To test downlink, create some shared attribute on your device and send some Uplink message on this device. And you will see Downlink message.

image

image

Also, you can set for Uplink command option -q, for example 120 seconds. This option setting how long you will wait for a response. If time of connection is over - you will receive this message on next Uplink. See next example:

image

image

Doc info icon

Note
When you use UDP integration, and your connection established for a long time, you will receive just one Downlink message. All other will be saved on server side and will be sent on next Uplink.

Next steps