TCP Integration
TCP Integration streams data from devices over the TCP transport protocol into ThingsBoard and converts device payloads to the ThingsBoard format. TCP Integration always runs as a remote integration — it can run on the same machine as your ThingsBoard instance or on a separate machine with network access to it.
Prerequisites
Section titled “Prerequisites”This tutorial uses:
- A ThingsBoard Professional Edition instance running locally.
- TCP Integration running as a remote integration connected to the ThingsBoard instance. Port 10560 must be open for incoming connections on the machine running TCP Integration.
- The
echocommand piped tonetcat(nc) to send data over TCP.
The example device SN-002 publishes temperature and humidity readings to the TCP Integration on port 10560.
Three payload formats are demonstrated — select the one that matches your device:
SN-002,default,temperature,25.7\nSN-002,default,humidity,69[ { "deviceName": "SN-002", "deviceType": "default", "temperature": 25.7, "humidity": 69 }]The binary payload is 25 bytes:
\x30\x30\x30\x30\x11\x53\x4e\x2d\x30\x30\x32\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x00\x00\x00Byte layout:
- Bytes 0–3 (
\x30\x30\x30\x30) — dummy prefix bytes, skipped. - Byte 4 (
\x11= decimal 17) — payload length: 17 bytes starting at byte 5. - Bytes 5–10 (
\x53\x4e\x2d\x30\x30\x32) — device name:SN-002. - Bytes 11–17 (
\x64\x65\x66\x61\x75\x6c\x74) — device type:default. - Bytes 18–21 (
\x32\x35\x2e\x37) — temperature:25.7. - Bytes 22–24 (
\x00\x00\x00) — dummy trailing bytes, ignored.
ThingsBoard integration setup
Section titled “ThingsBoard integration setup”Create an uplink converter
Section titled “Create an uplink converter”TCP uses a generic uplink converter. The uplink converter receives the raw TCP message bytes as a payload byte array — already framed and stripped by the handler configured in the connection settings. 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.
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
- Set Converter type to Uplink (default).
- Select Integration type: TCP.
- Enter a converter name:
TCP Uplink Converter. - Paste the decoder function from the tab 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, "").split(',');
var telemetryKey = payloadArray[2];var telemetryValue = payloadArray[3];
var telemetryPayload = {};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 handler delivers one logical record per decoder invocation (split by the configured message separator). The decoder expects a comma-separated string: position 0 is the device name, position 1 is the device type, followed by alternating telemetry key/value pairs.
To adapt this converter to your device:
- Change the separator by replacing
split(',')with your delimiter (e.g.split(';')). - 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 extract attributes instead of telemetry, 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)) }};
/** 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)) }};
/** 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 handler strips the framing bytes (dummy prefix and length field) before passing the payload to the decoder. The decoder then reads device identity and sensor values from fixed byte offsets of the remaining data.
To adapt this converter to your device:
- Adjust the
substring(start, end)offsets to match your device’s byte layout after framing bytes are stripped. - Update the Number of first bytes to strip in the handler settings to match the number of framing bytes your protocol uses.
- 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. - Add more telemetry fields by reading additional byte ranges and adding them to the
telemetrymap.
- Optionally, click Test payload decoder 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 TCP.
- Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Select existing — choose the TCP Uplink Converter created above.
- Click Next.
- Downlink data converter:
- Click Skip — the downlink converter can be added later.
- Connection settings:
- Port —
10560by default; change if needed. - Copy the Integration key and Integration secret — required when configuring the remote TCP Integration service.
- Select your payload type and configure the frame handler — see Handler configuration below.
- Port —
- Click Add to save the integration.
Connection settings
Section titled “Connection settings”Handler configuration
The frame handler controls how TCP reads the incoming byte stream and extracts individual messages. Select the handler matching your payload format:
| Parameter | Value | Description |
|---|---|---|
| Max Frame Length | 128 | Maximum length of a decoded frame. |
| Strip Delimiter | enabled | Drops the newline delimiter from the decoded payload. |
| Message Separator | System Line Separator | Newline (\n) used as the message delimiter. |
Configure to match the sample binary payload:
| Parameter | Value | Description |
|---|---|---|
| Max Frame Length | 128 | Maximum length of a decoded frame. |
| Length Field Offset | 4 | Byte index of the length field (\x30\x30\x30\x30\x11\x53…). |
| Length Field Length | 1 | The length field occupies 1 byte. |
| Length Adjustment | 0 | No compensation needed; the length field value (17) is already correct. |
| Number of first bytes to strip | 5 | Skip the 4 dummy bytes + 1 length byte to reach the data (\x30\x30\x30\x30\x11\x53\x4e\x2d…). |
| Byte Order | Little Endian | Byte order used when reading the length field. |
Port
| Parameter | Default | Description |
|---|---|---|
| Port | 10560 | TCP port the integration listens on for incoming device connections. |
Integration key and secret
Generated automatically when Execute remotely is enabled. Required when starting the remote TCP Integration service — copy both values before closing the wizard.
Socket options
| Parameter | Description |
|---|---|
| Max number of pending connects | Maximum backlog queue length for incoming connections. |
| Size of the buffer for inbound socket | Receive buffer size in KB. |
| Size of the buffer for outbound socket | Send buffer size in KB. |
| Enable keep-alive messages | Sends periodic probes to detect and drop stale connections. |
| Disable Nagle’s buffering algorithm | Sends data immediately without waiting to fill a buffer. |
Downlink cache
| Parameter | Description |
|---|---|
| Cache Size | Maximum number of downlink messages stored per TCP client. |
| Cache time to live in minutes | How long queued downlink messages are retained before being discarded. |
Install and run the remote TCP Integration
Section titled “Install and run the remote TCP Integration”Follow the remote integration guide to install and start the TCP Integration service. Use the Integration key and Integration secret from the connection settings step above.
Test uplink
Section titled “Test uplink”Once the TCP integration is active, the TCP server starts and listens for device connections.
Select your payload type:
Send a single message:
echo -e 'SN-002,default,temperature,25.7' | nc -q0 127.0.0.1 10560
Multiple messages (newline-delimited):
echo -e 'SN-002,default,temperature,25.7\nSN-002,default,humidity,69' | nc -q1 -w1 127.0.0.1 10560
To receive a downlink response, keep the connection open:
echo -e 'SN-002,default,temperature,25.7' | nc 127.0.0.1 10560
Multiple messages with open connection:
echo -e 'SN-002,default,temperature,25.7\nSN-002,default,humidity,69' | nc -w60 127.0.0.1 10560
Send a message:
echo -e -n '{"deviceName": "SN-002", "deviceType": "default", "temperature": 25.7, "humidity": 69}' | nc -q1 -w1 127.0.0.1 10560
To receive a downlink response, keep the connection open:
echo -e -n '{"deviceName": "SN-002", "deviceType": "default", "temperature": 25.7, "humidity": 69}' | nc -w60 127.0.0.1 10560
Send a message:
echo -e -n '\x30\x30\x30\x30\x11\x53\x4e\x2d\x30\x30\x32\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x00\x00\x00' | nc -q1 -w1 127.0.0.1 10560
To receive a downlink response, keep the connection open:
echo -e -n '\x30\x30\x30\x30\x11\x53\x4e\x2d\x30\x30\x32\x64\x65\x66\x61\x75\x6c\x74\x32\x35\x2e\x37\x00\x00\x00' | nc -w60 127.0.0.1 10560
Go to Entities ⇾ Devices. Device SN-002 is auto-created on the first uplink. Open the Latest Telemetry tab to confirm temperature = 25.7.
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 to forward attribute changes to it.
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:
/** Encoder **/
var data = {};
data.tempFreq = msg.temperatureUploadFrequency;data.humFreq = msg.humidityUploadFrequency;data.devSerialNumber = metadata['ss_serialNumber'];
var result = { contentType: "JSON", data: JSON.stringify(msg), metadata: { topic: metadata['deviceType'] + '/' + metadata['deviceName'] + '/upload' }};
return result;/** Encoder **/
var data = {};
data.tempFreq = msg.temperatureUploadFrequency;data.humFreq = msg.humidityUploadFrequency;data.devSerialNumber = metadata['ss_serialNumber'];
var result = { contentType: "JSON", data: JSON.stringify(msg), metadata: { topic: metadata['deviceType'] + '/' + metadata['deviceName'] + '/upload' }};
return result;- Go to Integrations center ⇾ Integrations, open the TCP 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
TCP integration downlink, select the TCP integration, and click Add. - Connect the Message Type Switch node to the Integration Downlink node using the Attributes Updated relation type and click Apply changes.
Test the downlink
Section titled “Test the downlink”- Go to Entities ⇾ Devices, open device SN-002, 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 -w60 and send an uplink:
echo -e -n '{"deviceName": "SN-002", "deviceType": "default", "temperature": 25.7, "humidity": 69}' | nc -w60 127.0.0.1 10560To verify the downlink, go to Integrations center ⇾ Data converters, open the downlink converter, and check the Events tab. The In block shows the incoming message from the rule chain; the Out block shows the encoded payload sent to the device. When the TCP connection stays open for an extended time, only one downlink message is delivered immediately — subsequent messages are queued and sent on the next uplink.