LORIOT Integration
The LORIOT integration connects ThingsBoard to a LORIOT LoRaWAN Network Server over HTTP. LORIOT pushes uplink messages from your LoRaWAN devices to a ThingsBoard HTTP endpoint; the uplink converter decodes each message and stores the result as device telemetry and attributes on the platform. In the reverse direction, ThingsBoard encodes Rule Engine messages via the downlink converter and delivers them to devices through the LORIOT REST API.
Prerequisites
Section titled “Prerequisites”Before creating the integration, ensure:
- You have access to ThingsBoard Cloud with integration functionality enabled for your tenant.
- You have permissions to create integrations and data converters.
- You have a LORIOT account with at least one registered application. If you do not have an account yet, follow the Register a LORIOT Account step below.
LORIOT Account Setup
Section titled “LORIOT Account Setup”Register a LORIOT Account
Section titled “Register a LORIOT Account”- Go to the LORIOT website and choose a service package (e.g. Community Public Network Server).
- Pick your preferred region and country, then complete the registration and log in.
Locate Server and Application ID
Section titled “Locate Server and Application ID”You will need the server name and Application ID when configuring the integration connection settings and downlink output.
- Server — the subdomain in your LORIOT dashboard URL, for example
eu1fromeu1.loriot.io. - Application ID — listed on the Applications page next to your application name.
Create LORIOT Uplink Data Converter
Section titled “Create LORIOT Uplink Data Converter”The uplink converter receives each LORIOT uplink message, decodes the LoRaWAN payload, and returns a structured object that ThingsBoard uses to create or update a device and store its telemetry and attributes.
If your device is in the built-in catalog, use the Library tab instead of writing a decoder — see Converters library for over 100 ready-made decoders.
For the full decoder function reference — all input parameters and output fields — see Uplink data converter.
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
In the Add data converter dialog:
- Converter type — leave Uplink (selected by default).
- Integration type — in the search field, enter
Loriotand select Loriot from the list. - Name — enter a converter name, for example
Loriot Uplink Converter. - Configure main decoding parameters:
- Device name — the default value
Device $euinames each ThingsBoard device using the EUI from the LORIOT uplink message (e.g.Device BE7A000000000552). On the first uplink ThingsBoard creates the device; on subsequent uplinks it updates the existing one. Change this pattern if you prefer a different naming scheme. - The default decoder is pre-filled. Leave it unchanged for this guide.
By default the editor opens in TBEL; use the TBEL / JS toggle (upper right) to switch languages.
/*** Decodes the incoming payload and returns a structured object containing telemetry data and attributes.** @param {byte[]} input - The raw payload received as an array of bytes.* @returns {Object} output - The structured output with decoded telemetry and attributes.*/function decodePayload(input) {// Initialize the output object with empty attributes and telemetry for clarity.var result = { attributes: {}, telemetry: {}};// Decode serial number (SN) from the first 4 bytes of the payload.// Press '?' icon in the top right corner to learn more about built in helper functions and capabilities.result.attributes.sn = parseBytesToInt(input, 0, 4);// Extract the timestamp from metadata (represented in milliseconds).var timestamp = metadata.ts; // ts from the incoming message.// Initialize an object to store decoded key/value telemetry data.var values = {};// Decode battery level from the 5th byte of the payload.values.battery = parseBytesToInt(input, 4, 1);// Decode temperature from the 6th and 7th bytes of the payload (divided by 100).values.temperature = parseBytesToInt(input, 5, 2) / 100.0;// Decode saturation from the 8th byte of the payload.values.saturation = parseBytesToInt(input, 7, 1);// Combine the timestamp with values and add it to the telemetry.result.telemetry = {ts: timestamp,values: values};// Return the fully constructed output object.return result;// Same logic, less code:// return {// attributes: {// sn: parseBytesToInt(input, 0, 4)// },// telemetry: {// ts: metadata.ts,// values: {// battery: parseBytesToInt(input, 4, 1),// temperature: parseBytesToInt(input, 5, 2) / 100.0,// saturation: parseBytesToInt(input, 7, 1)// }// }// };}var result = decodePayload(payload);// Uncomment this code block to overwrite values set in the main configuration window. Useful if you extract device/asset/customer/group names from the payload;// result.type = 'DEVICE'; // Entity type allows you to choose type of created entity. Can be 'DEVICE' or 'ASSET'.// result.name = 'Temperature Sensor'; // Device or asset name (the value must be unique)// result.profile = 'IndustrialSensorProfile'; // Device or asset profile name.// result.customer = 'MyCustomer'; // If customer is not null - created entity will be assigned to customer with such name.// result.group = 'SensorsGroup'; // If group is not null - created entity will be added to the entity group with such name.// Return the final result object.return result;/*** Decodes the incoming payload and returns a structured object containing telemetry data and attributes.** @param {number[]} input - The raw payload received as an array of bytes.* @returns {Object} output - The structured output with decoded telemetry and attributes.*/function decodePayload(input) {// Initialize the output object with empty attributes and telemetry for clarity.var result = { attributes: {}, telemetry: {}};// Decode serial number (SN) from the first 4 bytes of the payload.// Press '?' icon in the top right corner to learn more about built in helper functions and capabilities.result.attributes.sn = parseBytesToInt(input, 0, 4);// Extract the timestamp from metadata (represented in milliseconds).var timestamp = metadata.ts; // ts from the incoming message.// Initialize an object to store decoded key/value telemetry data.var values = {};// Decode battery level from the 5th byte of the payload.values.battery = parseBytesToInt(input, 4, 1);// Decode temperature from the 6th and 7th bytes of the payload (divided by 100).values.temperature = parseBytesToInt(input, 5, 2) / 100.0;// Decode saturation from the 8th byte of the payload.values.saturation = parseBytesToInt(input, 7, 1);// Combine the timestamp with values and add it to the telemetry.result.telemetry = {ts: timestamp,values: values};// Return the fully constructed output object.return result;// Same logic, less code:// return {// attributes: {// sn: parseBytesToInt(input, 0, 4)// },// telemetry: {// ts: metadata.ts,// values: {// battery: parseBytesToInt(input, 4, 1),// temperature: parseBytesToInt(input, 5, 2) / 100.0,// saturation: parseBytesToInt(input, 7, 1)// }// }// };}var result = decodePayload(payload);// Uncomment this code block to overwrite values set in the main configuration window. Useful if you extract device/asset/customer/group names from the payload;// result.type = 'DEVICE'; // Entity type allows you to choose type of created entity. Can be 'DEVICE' or 'ASSET'.// result.name = 'Temperature Sensor'; // Device or asset name (the value must be unique)// result.profile = 'IndustrialSensorProfile'; // Device or asset profile name.// result.customer = 'MyCustomer'; // If customer is not null - created entity will be assigned to customer with such name.// result.group = 'SensorsGroup'; // If group is not null - created entity will be added to the entity group with such name.// Return the final result object.return result;/*** Parse a slice of bytes from an array into an integer (big-endian).** @param {number[]} input - The array of bytes.* @param {number} offset - The starting index.* @param {number} length - The number of bytes to convert.* @returns {number} - The resulting integer.*/function parseBytesToInt(input, offset, length) {var result = 0;for (var i = offset; i < offset + length; i++) {result = (result << 8) | (input[i] & 0xFF);}return result;} - Device name — the default value
Review advanced decoding parameters — pre-populated for LORIOT; leave defaults unless your setup differs.
The default telemetry keys extracted from LORIOT messages include:
data,fCnt,rssi,snr.The default attribute keys include:
eui,fPort,dr,freq.- Click Add.
What the Converter Receives
ThingsBoard passes two variables to the decoder function:
| Variable | Type | Description |
|---|---|---|
payload | byte array | The raw LoRaWAN payload bytes from the LORIOT data field. |
metadata | object | Key-value map populated from the LORIOT uplink HTTP message. |
Key metadata fields available in the decoder:
| Field | Description |
|---|---|
metadata.ts | Uplink timestamp in milliseconds, parsed from the LORIOT ts field; falls back to server time if the field is absent or unparseable. |
metadata.EUI | Device EUI, e.g. BE7A000000000552 — used as the device identifier by the default Device $eui naming template. |
metadata.port | LoRaWAN frame port (fPort). |
metadata.rssi | Received signal strength indicator (dBm). |
metadata.snr | Signal-to-noise ratio (dB). |
metadata.dr | Data rate string, e.g. SF12 BW125 4/5. |
metadata.freq | Transmission frequency in Hz. |
metadata.fcnt | Frame counter. |
metadata.cmd | LORIOT message command type — typically rx for uplinks. |
Example: Binary Payload Decoded
The decoder assumes a fixed binary payload structure. It reads byte ranges using parseBytesToInt(input, offset, length) and produces:
| Bytes | Field | Output type | Expression | Notes |
|---|---|---|---|---|
| 0–3 | sn | attribute | parseBytesToInt(input, 0, 4) | Device serial number |
| 4 | battery | telemetry | parseBytesToInt(input, 4, 1) | Battery level |
| 5–6 | temperature | telemetry | parseBytesToInt(input, 5, 2) / 100.0 | Raw value ÷ 100 |
| 7 | saturation | telemetry | parseBytesToInt(input, 7, 1) | Saturation level |
Example payload (hex):
00BC614E5F092950Example output:
{ "attributes": { "sn": 12345678 }, "telemetry": { "ts": 1690000000000, "values": { "battery": 95, "temperature": 23.45, "saturation": 80 } }}Adapting the Converter
- Different device name — change the Device name pattern in Main decoding configuration (e.g. replace
Device $euiwith a fixed string or a field extracted from the payload). - Different byte layout — adjust the offset and length in each
parseBytesToInt()call to match your payload structure. - Different field names — rename
battery,temperature, orsaturation; add or remove fields as needed. - Additional attributes — add more keys to
result.attributes(e.g.result.attributes.firmwareVersion = parseBytesToInt(input, 8, 2)).
Create LORIOT Integration
Section titled “Create LORIOT Integration”- Go to Integrations center ⇾ Integrations and click + Add integration.
- Basic settings:
- Select Loriot as the integration type.
- Enter a Name for the integration, or keep the default
Loriot integration. - Enable integration and Allow create devices or assets are enabled by default — leave them enabled.
- Click Next.
- Uplink data converter:
- Click Select existing and choose the Loriot Uplink Converter created in the previous step.
- Alternatively, click Create new to define the decoder inline, or use Library to load a vendor-provided preset.
- Click Next.
- Downlink data converter:
- Click Skip — the downlink converter is only needed for sending commands to devices and can be added later.
- Connection:
- Copy the HTTP endpoint URL — you will need it when configuring LORIOT.
- Click Add to create the integration.
After the integration is created, copy the HTTP endpoint URL from the integration details panel — you will need it in the next step to configure LORIOT to push uplinks to ThingsBoard.
Connection Settings
Section titled “Connection Settings”Base URL
The base address of the ThingsBoard server, used to construct the HTTP endpoint URL below. For ThingsBoard Cloud this is pre-filled automatically.
HTTP Endpoint URL
Auto-generated webhook endpoint for this integration. LORIOT sends uplink messages to this URL as HTTP POST requests. Copy it before closing the wizard — you will need it in the next step.
Create Loriot Application Output / Send Downlink
These two toggles share a common settings group. Enabling either one reveals the following shared fields:
| Parameter | Description |
|---|---|
| Server | LORIOT server subdomain — e.g. eu1. See Finding server and application ID. |
| Domain | LORIOT domain — default is loriot.io. |
| Application ID | Your LORIOT application ID. |
Create Loriot Application output — when enabled, ThingsBoard automatically registers itself as an HTTP Push output in your LORIOT application via the LORIOT API, so no manual webhook configuration is needed. Enabling this additionally reveals:
| Parameter | Description |
|---|---|
| Credentials type | Authentication method for the LORIOT API. Basic — enter your LORIOT account Email and Password. Security token — enter a Token generated in your LORIOT account. |
Send downlink — when enabled, ThingsBoard can send commands to LORIOT devices via the LORIOT API. Enabling this additionally reveals:
| Parameter | Description |
|---|---|
| Downlink URL | Auto-populated as https://{server}.loriot.io/1/rest. Override only if your LORIOT setup uses a non-standard endpoint. |
| Application Access Token | LORIOT API token used to authenticate downlink requests. Generate this in the Access Tokens section of your LORIOT application. |
Enable Security (Headers Filter)
When enabled, ThingsBoard validates an HTTP header on every incoming uplink request and rejects requests that do not carry the expected header/value pair. Click Add to define one or more Header / Value pairs.
Execute Remotely
When enabled, ThingsBoard generates an Integration key and Integration secret. Use these credentials to run the integration as a separate remote process — useful when the integration must reach services not accessible from the ThingsBoard server.
Advanced Settings
| Parameter | Description |
|---|---|
| Replace response status from ‘No Content’ to ‘OK’ | When enabled, ThingsBoard responds with HTTP 200 instead of 204. Enable if LORIOT treats a 204 response as an error. |
| Description | Optional text description for this integration. |
| Metadata | Key-value pairs injected into every uplink message as integrationMetadata in converter scripts. |
Configure LORIOT to forward uplinks
Section titled “Configure LORIOT to forward uplinks”To receive uplinks, ThingsBoard must be registered as an HTTP output in your LORIOT application. Choose one of the two methods below — both result in the same data flow.
Manually create an HTTP Push output in the LORIOT UI. No LORIOT credentials are stored in ThingsBoard.
- In the LORIOT UI, go to Applications and open your application.
- In the left sidebar, click Output.
- Click + Add new output.
- Select HTTP Push as the output type.
- Paste the HTTP endpoint URL copied from the integration Connection step into the Target URL for POSTs field.
- Click Add Output.
ThingsBoard connects to the LORIOT API with your credentials and registers itself as an HTTP Push output automatically.
- Go to Integrations center ⇾ Integrations, open the Loriot integration, and click the edit (pencil) icon.
- Enable Create Loriot Application output.
- Enter the Server and Application ID — see Finding server and application ID below.
- Set Credentials type to Basic and enter your LORIOT account email and password.
- Click Apply changes.
Finding server and application ID
Section titled “Finding server and application ID”- Server: The subdomain in your LORIOT dashboard URL — e.g.
eu1fromeu1.loriot.io. - Application ID: Listed in the Applications page next to your application name.
Enable security (optional)
Section titled “Enable security (optional)”To reject requests that don’t include specific HTTP headers, enable Enable security (Headers filter) in the integration settings.
- Open the Loriot integration, click the edit (pencil) icon, and enable Enable security (Headers filter).
- Click Add and enter a Header name and Value (e.g.
authorization/secret). - Click Apply changes.
- In the LORIOT HTTP Push output configuration, enter the same values in Custom header name and Custom header value, then click Accept.
Test uplink
Section titled “Test uplink”When a device sends an uplink message via LORIOT, ThingsBoard automatically creates the device and stores its telemetry. If you do not have a physical device sending data, you can emulate a device message by sending an HTTP request directly to the ThingsBoard endpoint using curl — bypassing LORIOT entirely. This is useful to verify that the integration and uplink converter are configured correctly before connecting real hardware. To send a test uplink, you need the HTTP endpoint URL from the integration details.
Go to Integrations center ⇾ Integrations, open the Loriot integration, and copy the HTTP endpoint URL.
Replace $HTTP_ENDPOINT_URL with the copied URL and run:
Without security:
curl -v -X POST \ -H "Content-Type: application/json" \ -d '{"EUI":"BE7A000000000552","data":"00BC614E5F092950","port":1,"cmd":"rx","dr":"SF12 BW125 4/5","snr":1.2,"ack":"false","freq":868500000,"fcnt":1,"rssi":-130,"ts":1613745998000}' \ "$HTTP_ENDPOINT_URL"With security:
curl -v -X POST \ -H "Content-Type: application/json" \ -H "$HEADER:$VALUE" \ -d '{"EUI":"BE7A000000000552","data":"00BC614E5F092950","port":1,"cmd":"rx","dr":"SF12 BW125 4/5","snr":1.2,"ack":"false","freq":868500000,"fcnt":1,"rssi":-130,"ts":1613745998000}' \ "$HTTP_ENDPOINT_URL"Once an uplink is received, a new device named Device BE7A000000000552 (matching the EUI field from the payload) appears in Entities ⇾ Devices:
Inspect event logs
Section titled “Inspect event logs”Go to Integrations center ⇾ Data converters, click the Loriot uplink converter, and open the Events tab — In shows the raw incoming payload bytes, Out shows the decoded result, Metadata shows all LORIOT message fields passed alongside the payload:
Configure and test downlink
Section titled “Configure and test downlink”The downlink converter encodes ThingsBoard Rule Engine messages into LORIOT-compatible payloads. For the full encoder function reference, see Downlink data converter.
The encoder result must include two metadata fields required by the LORIOT API:
EUI— the device EUI (see below)port— the LoRaWAN port (1–223)
To find the device EUI, go to the Devices section of your LORIOT application and open the device.
Add a downlink converter
Section titled “Add a downlink converter”- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
- Enter a name:
Loriot Downlink Converter, and set Type to Downlink. - Paste the encoder function below and click Add.
// Encode downlink data from incoming Rule Engine message// msg - JSON message payload// msgType - message type, e.g. 'ATTRIBUTES_UPDATED'// metadata - key-value pairs with additional message datavar result = { // downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "TEXT", // downlink data data: msg.firmware, // metadata must include EUI and port metadata: { "EUI": metadata.deviceName, "port": 1 }};return result;// Encode downlink data from incoming Rule Engine message// msg - JSON message payload// msgType - message type, e.g. 'ATTRIBUTES_UPDATED'// metadata - key-value pairs with additional message datavar result = { // downlink data content type: JSON, TEXT or BINARY (base64 format) contentType: "TEXT", // downlink data data: msg.firmware, // metadata must include EUI and port metadata: { "EUI": metadata.deviceName, "port": 1 }};return result;After creating the converter, open the Loriot integration, click the edit icon, select Loriot Downlink Converter in the Downlink data converter field, and click Apply changes.
Enable sending downlinks
Section titled “Enable sending downlinks”To send messages from ThingsBoard to LORIOT devices, enable Send downlink in the integration settings and provide the LORIOT API credentials.
- Open the Loriot integration and click the edit icon.
- Enable Send downlink and fill in the required fields:
- Server — the LORIOT server subdomain (e.g.
us1); see Finding server and application ID. - Application ID — the Application ID from your LORIOT project.
- Downlink URL — auto-populated from Server/Application ID (e.g.
https://us1.loriot.io/1/rest); override if your setup uses a custom endpoint. - Application Access Token — generate this in the Access Tokens section of your LORIOT application and paste it here.
- Server — the LORIOT server subdomain (e.g.
- Click Apply changes.
Configure the rule chain
Section titled “Configure the rule chain”To trigger a downlink when a shared attribute changes, add an Integration Downlink node to the Root Rule Chain:
- Open Rule Chains ⇾ Root Rule Chain and click the edit icon.
- Add an Integration Downlink action node and connect it to the Message Type Switch node via the Attributes Updated relation.
- Save the rule chain.
Trigger and verify a downlink
Section titled “Trigger and verify a downlink”- Go to Entities ⇾ Devices and open the device (e.g.
Device BE7A000000000552). - Open the Attributes tab, switch to Shared attributes, and click +.
- Enter key
firmwareand a value (e.g.01052020.v1.1), then click Add. - Click the edit icon next to the attribute, change the value (e.g. to
01052020.v1.2), and click Update.
Go to Integrations center ⇾ Data converters, click the Loriot Downlink Converter, and open the Events tab — In shows the incoming attribute update, Out shows the encoded payload sent to LORIOT:
To confirm the message reached LORIOT, open the device in the LORIOT UI, go to LoRaWAN Parameters, and check the Downlink Queue at the bottom of the page.
See also
Section titled “See also”Was this helpful?