UDP Integration
UDP Integration allows you to stream data from devices using the UDP protocol to ThingsBoard and convert device payloads to the ThingsBoard format.
Prerequisites
Section titled “Prerequisites”This tutorial uses:
- A ThingsBoard Professional Edition instance running locally.
- UDP Integration running as a remote integration connected to the ThingsBoard instance.
- The
echocommand to produce a line of text, piped tonetcat(nc) to send it over UDP.
The example sensor device SN-001 publishes temperature and humidity readings to UDP Integration on port 11560.
Four payload formats are demonstrated. Select the one that matches your device:
SN-001,default,temperature,25.7,humidity,69{ "deviceName": "SN-001", "deviceType": "default", "temperature": 25.7, "humidity": 69}The binary payload is 19 bytes:
\x53\x4e\x2d\x30\x30\x31\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x36\x39Byte layout:
- Bytes 0–5 (
\x53\x4e\x2d\x30\x30\x31) — device name:SN-001. - Bytes 6–12 (
\x64\x65\x66\x61\x75\x6c\x74) — device type:default. - Bytes 13–16 (
\x32\x35\x2e\x37) — temperature:25.7. - Bytes 17–18 (
\x36\x39) — humidity:69.
534e2d30303164656661756c7432352e373639This is the hex-encoded form of the binary payload above, converted to bytes using xxd -r -p before sending.
ThingsBoard integration setup
Section titled “ThingsBoard integration setup”Create an uplink converter
Section titled “Create an uplink converter”UDP uses a generic uplink converter. The decoder function receives the raw UDP datagram as a payload byte array. It must return an object with at least deviceName and deviceType. Optionally, it can include telemetry (time-series measurements) and attributes (device properties) as flat key-value maps.
Unlike HTTP or MQTT integrations, UDP provides no transport-level metadata — device identity must come entirely from the payload itself.
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter and select Create new converter.
- Set Converter type to Uplink (default).
- Select Integration type: UDP.
- Enter a name, e.g.
UDP Uplink Converter. - Select TBEL (recommended) or JavaScript.
- Clear the default script and paste the decoder function below.
Select the tab matching your payload type:
/** Decoder **/
// decode payload to stringvar 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 datavar result = { deviceName: payloadArray[0], deviceType: payloadArray[1], telemetry: telemetryPayload, attributes: {}};
/** Helper functions 'decodeToString' and 'decodeToJson' are already built-in **/
return result;/** Decoder **/
// decode payload to stringvar 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 datavar result = { deviceName: payloadArray[0], deviceType: payloadArray[1], telemetry: telemetryPayload, attributes: {}};
/** Helper functions **/
function decodeToString(payload) { return String.fromCharCode.apply(String, payload);}
return result;The decoder expects a comma-separated string where position 0 is the device name, position 1 is the device type, and positions 2–N are alternating telemetry key/value pairs: deviceName,deviceType,key1,value1,key2,value2,...
To adapt this converter to your device:
- Change the separator by replacing
split(',')with your delimiter (e.g.split(';')orsplit('|')). - If the device name or type is at a different position, adjust the
payloadArray[0]/payloadArray[1]index. - If telemetry keys are fixed rather than embedded in the payload, replace the loop with explicit assignments:
telemetryPayload['temperature'] = parseFloat(payloadArray[2]);. - To report device properties instead of measurements, move fields from the
telemetrymap to theattributesmap.
/** Decoder **/
// decode payload to JSONvar data = decodeToJson(payload);
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;/** Decoder **/
// decode payload to JSONvar data = decodeToJson(payload);
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) { var str = decodeToString(payload); var data = JSON.parse(str); return data;}
return result;The decoder parses the payload as a JSON object and maps fields directly to deviceName, deviceType, and telemetry keys.
To adapt this converter to your device:
- Replace
data.deviceName/data.deviceTypewith the actual field names your device sends (e.g.data.id,data.model). - Add or remove telemetry fields to match your sensor output:
pressure: data.pressure, co2: data.co2. - Move fields to
attributesif they represent device properties rather than time-series data (e.g.firmware: data.fw).
/** Decoder **/
// decode payload to stringvar payloadStr = decodeToString(payload);
var deviceName = payloadStr.substring(0, 6);var deviceType = payloadStr.substring(6, 13);
// Result object with device/asset attributes/telemetry datavar 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;/** Decoder **/
// decode payload to stringvar payloadStr = decodeToString(payload);
var deviceName = payloadStr.substring(0, 6);var deviceType = payloadStr.substring(6, 13);
// Result object with device/asset attributes/telemetry datavar 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) { var str = decodeToString(payload); var data = JSON.parse(str); return data;}
return result;The decoder converts the raw bytes to a string and reads device identity and sensor values from fixed byte offsets. This approach is typical for compact, bandwidth-constrained binary protocols.
To adapt this converter to your device:
- Adjust the
substring(start, end)offsets to match your device’s byte layout. - For integer fields stored as raw bytes (not ASCII digits), use
parseBytesToInt(payload, offset, length, bigEndian)instead ofparseFloat(payloadStr.substring(...)). For example:temperature: parseBytesToInt(payload, 13, 2, true) / 100.0. - If the device name or type is fixed rather than embedded in the payload, replace the
substringcalls with string literals. - Add more telemetry fields by reading additional byte ranges and adding them to the
telemetrymap.
/** Decoder **/
// decode payload to JSONvar data = decodeToJson(payload).reports[0].value;
// Result object with device telemetry datavar 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 stringfunction hexToString(hex) { return bytesToString(hexToBytes(hex));}
return result;/** Decoder **/
// decode payload to JSONvar data = decodeToJson(payload).reports[0].value;
// Result object with device telemetry datavar 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 stringfunction 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) { var str = decodeToString(payload); var data = JSON.parse(str); return data;}
return result;The decoder interprets the payload as a JSON envelope, extracts a hex-encoded data string from reports[0].value, and converts each hex substring back to its ASCII representation to read device identity and sensor values.
To adapt this converter to your device:
- Adjust the
substring(start, end)offsets to match your device’s hex-encoded field layout (each ASCII character encodes to 2 hex digits, so a 6-character name occupies 12 hex characters). - For numeric fields not represented as ASCII digits, use
parseInt(hexToString(data.substring(start, end)), 16)to decode a raw integer. - If your device sends a flat hex string rather than a JSON envelope, replace
decodeToJson(payload).reports[0].valuewithdecodeToString(payload)and adjust offsets accordingly.
- Optionally, click Test decoder function to validate.
- Click Add.
Create the integration
Section titled “Create the integration”- Go to Integrations center ⇾ Integrations and click + Add integration.
- Basic settings:
- Set Integration type to UDP.
- Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Select existing — choose the UDP Uplink Converter created above.
- Click Next.
- Downlink data converter:
- Click Skip — the downlink converter can be added later.
- Connection settings:
- Port —
11560by default; change if needed. - Copy the Integration key and Integration secret — required when configuring the remote UDP Integration service.
- Select your payload type and configure the handler — see Connection settings below.
- Port —
- Click Add to save the integration.
Connection settings
Section titled “Connection settings”Handler configuration
The handler determines how the integration interprets the incoming UDP datagram. Select the handler matching your payload format:
| Parameter | Value | Description |
|---|---|---|
| Charset Name | UTF-8 | Encoding used to convert the datagram bytes to a string. |
| Parameter | Value | Description |
|---|---|---|
| Max Frame Length (in bytes) | 128 | Maximum byte length of an incoming UDP datagram. |
Port
| Parameter | Default | Description |
|---|---|---|
| Port | 11560 | UDP port the integration listens on for incoming datagrams. |
Integration key and secret
Generated automatically — Execute remotely is always enabled for UDP Integration. Required when starting the remote UDP Integration service — copy both values before closing the wizard.
Network settings
| Parameter | Description |
|---|---|
| Enable broadcast | Accepts UDP packets sent to the broadcast address. Enabled by default. |
Downlink cache
| Parameter | Description |
|---|---|
| Cache Size | Maximum number of downlink messages stored per UDP client. |
| Cache time to live in minutes | How long queued downlink messages are retained before being discarded. |
Install and run the remote UDP integration
Section titled “Install and run the remote UDP integration”Refer to the remote integration guide to install and start the UDP Integration service.
Use the Integration key and Integration secret from the integration’s Connection settings when configuring the service.
Test uplink
Section titled “Test uplink”Once the UDP integration is active, the UDP server starts and waits for device data.
Select your payload type:
echo -e 'SN-001,default,temperature,25.7,humidity,69' | nc -w5 -u 127.0.0.1 11560
echo -e -n '{"deviceName": "SN-001", "deviceType": "default", "temperature": 25.7, "humidity": 69}' | nc -w5 -u 127.0.0.1 11560
echo -e -n '\x53\x4e\x2d\x30\x30\x31\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x36\x39' | nc -w5 -u 127.0.0.1 11560
echo -e -n '534e2d30303164656661756c7432352e373639' | xxd -r -p | nc -w5 -u 127.0.0.1 11560
Go to Entities ⇾ Devices. Device SN-001 is auto-created on the first uplink. Open it and confirm the Latest Telemetry tab shows temperature = 25.7 and humidity = 69.
Configure and test downlink
Section titled “Configure and test downlink”To send messages from ThingsBoard back to a device, add a downlink converter to the integration and configure a rule chain.
Add a downlink converter
Section titled “Add a downlink converter”The downlink converter encodes outgoing ThingsBoard messages into the format expected by the device.
The encoder used in this tutorial:
// Result object with encoded downlink payloadvar result = {
// downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "JSON",
// downlink data data: JSON.stringify(msg),
// Optional metadata object presented in key/value format metadata: {}
};
return result;// Result object with encoded downlink payloadvar result = {
// downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "JSON",
// downlink data data: JSON.stringify(msg),
// Optional metadata object presented in key/value format metadata: {}
};
return result;To assign the downlink converter to the integration:
- Go to Integrations center ⇾ Integrations, open the UDP integration, and click the edit (pencil) icon.
- In the Downlink data converter field, enter a name and click Create new converter.
- Paste the encoder script and click Add.
- Click Apply changes.
Configure the Root Rule Chain
Section titled “Configure the Root Rule Chain”- Go to Rule chains and open the Root Rule Chain.
- Find the Integration Downlink node, drag it onto the canvas, name it
UDP Downlink, select the UDP integration, and click Add. - Connect the Message Type Switch node to the Integration Downlink node using both Attributes Updated and Post Attributes relation types and click Apply changes.
Test the downlink
Section titled “Test the downlink”- Go to Entities ⇾ Devices, open device SN-001, and click the Attributes tab.
- Switch to Shared attributes and click +.
- Enter an attribute key and value (e.g. key:
firmware, value:v1.1) and click Add.
To receive the downlink response, keep the connection open with -w10 and send an uplink:
echo -e 'SN-001,default,temperature,25.7,humidity,69' | nc -w10 -u 127.0.0.1 11560