Skip to content
Stand with Ukraine flag

ChirpStack Integration

ChirpStack is an open-source LoRaWAN Network Server. After integrating it with ThingsBoard Edge, device data is processed and visualized locally at the edge — enabling low-latency insights and offline operation.

  • ThingsBoard Edge Professional Edition, up and running.
  • ChirpStack Network Server installed via Docker Compose or Ubuntu.
  • A LoRaWAN device connected to ChirpStack. See Connect a device in the ChirpStack docs.

Create converter and integration templates

Section titled “Create converter and integration templates”

Integration templates are created on the Cloud (ThingsBoard PE server) — log in as Tenant administrator.

  1. Go to Edge management > Integration templates and click Add. Select ChirpStack as the type and enter an integration name.

  2. Click Next.

The uplink converter decodes incoming ChirpStack payloads into ThingsBoard telemetry and attributes.

  1. Select the Create new tab. Enter a converter name.

  2. In the Main decoding configuration block, select the Entity type (Device or Asset) and enter the entity name.

  3. Paste the decoder script into the function payloadDecoder field. For Edge version 3.9 and older:

    var data = decodeToJson(payload);
    var deviceName = data.deviceInfo.deviceName;
    var deviceType = data.deviceInfo.deviceProfileName;
    var groupName = 'IAQ devices';
    function decodePayload(input) {
    var output = { attributes:{}, telemetry: {} };
    output.telemetry.HEX_bytes = bytesToHex(input);
    if (input.length > 0) {
    for (var i = 0; i < input.length; ) {
    var channel_id = input[i++];
    if (i < input.length) {
    var channel_type = input[i++];
    if (channel_id === 0x01 && channel_type === 0x75) {
    output.telemetry.battery = input[i];
    i += 1;
    } else if (channel_id === 0x03 && channel_type === 0x00) {
    output.telemetry.pir = input[i] === 0 ? "normal" : "trigger";
    i += 1;
    } else if (channel_id === 0x04 && channel_type === 0x00) {
    output.telemetry.daylight = input[i] === 0 ? "dark" : "light";
    i += 1;
    }
    }
    }
    }
    return output;
    }
    var telemetry = {};
    var attributes = {};
    var dateString = data.time;
    var timestamp = -1;
    if (dateString != null) {
    timestamp = new Date(dateString).getTime();
    if (timestamp == -1) {
    var secondsSeparatorIndex = dateString.lastIndexOf('.') + 1;
    var millisecondsEndIndex = dateString.lastIndexOf('+');
    if (millisecondsEndIndex == -1) { millisecondsEndIndex = dateString.lastIndexOf('Z'); }
    if (millisecondsEndIndex == -1) { millisecondsEndIndex = dateString.lastIndexOf('-'); }
    if (millisecondsEndIndex == -1) {
    if (dateString.length >= secondsSeparatorIndex + 3) {
    dateString = dateString.substring(0, secondsSeparatorIndex + 3);
    }
    } else {
    dateString = dateString.substring(0, secondsSeparatorIndex + 3) +
    dateString.substring(millisecondsEndIndex, dateString.length);
    }
    timestamp = new Date(dateString).getTime();
    }
    }
    if (timestamp == -1) { timestamp = Date.now(); }
    attributes.deduplicationId = data.deduplicationId;
    var excludeFromAttributesList = ["deviceName", "rxInfo", "confirmed", "data",
    "deduplicationId", "time", "adr", "dr", "fCnt"];
    var excludeFromTelemetryList = ["data", "deviceInfo", "txInfo", "devAddr",
    "adr", "time", "fPort", "region_common_name", "region_config_id", "deduplicationId"];
    var telemetryData = toFlatMap(data, excludeFromTelemetryList, false);
    var attributesData = toFlatMap(data, excludeFromAttributesList, false);
    var customDecoding = decodePayload(base64ToBytes(data.data));
    if (customDecoding.?telemetry.size() > 0) { telemetry.putAll(customDecoding.telemetry); }
    if (customDecoding.?attributes.size() > 0) { attributes.putAll(customDecoding.attributes); }
    telemetry.putAll(telemetryData);
    attributes.putAll(attributesData);
    var result = {
    deviceName: deviceName,
    deviceType: deviceType,
    groupName: groupName,
    attributes: attributes,
    telemetry: { ts: timestamp, values: telemetry }
    };
    return result;
  4. Starting with Edge version 4.0, you can alternatively select the Library tab, choose a Vendor, and select the appropriate device Model from the drop-down menus — or use the default script provided in the converter.

  5. In the Advanced decoding parameters block, optionally configure Device profile, Device label, Customer name, and Device group name (all support $-pattern placeholders). Set Attributes and Telemetry keys, and configure Update only keys list to save values only when they change.

  6. Click Next.

Configuring a downlink converter is optional. To skip it, select the Skip tab and click Skip.

Before configuring the connection in ThingsBoard, create an Application server API Token in the ChirpStack UI.

  1. Open the ChirpStack UI at http://chirpstack-server-ip:8080 and log in. Default credentials: username admin, password admin.

  2. Go to Tenant > API Keys and click Add API Key. Enter a name and click Submit. Copy the generated API key.

  3. Back in ThingsBoard, fill in the Connection block:

    FieldValue
    Base URLURL of your ThingsBoard Edge: http://edge-ip:edge-port
    HTTP endpoint URLCopy this value — you will need it when configuring the ChirpStack application
    Application server URLChirpStack REST API address: http://chirpstack-server-ip:8090
    Application server API TokenPaste the API token from ChirpStack
  4. Click Add.

Log in to the ChirpStack UI at http://chirpstack-server-ip:8080 to configure the application integration.

  1. Go to Tenant > Device Profiles and click Add device profile.

  2. On the General tab, fill in the required fields:

    FieldDescription
    NameDevice profile name
    RegionLoRaWAN regional parameters
    MAC VersionLoRaWAN MAC version the device uses
    Regional parameters revisionParameter set version for your region
    ADR AlgorithmAdaptive Data Rate logic
    Expect uplink interval (secs)Expected interval between uplink messages
  3. Click Submit.

  1. Go to Tenant > Applications and click Add application. Enter an application name and click Submit.

  2. Select the Integrations tab. Find HTTP in the list and click +.

  3. Paste the HTTP endpoint URL from the ThingsBoard Connection step and click Submit.

  1. Select the Devices tab and click Add device.

  2. On the Device tab, fill in the required fields:

    FieldDescription
    NameDevice name
    Device EUI (EUI64)Unique 64-bit identifier assigned to the LoRaWAN device
    Byte orderByte order used to represent the DevEUI (MSB or LSB)
    Device profileSelect the device profile created above
  3. Click Submit.

In a testing environment, you can skip adding a gateway — the device itself sends data through the gateway. To add a gateway:

  1. Go to Tenant > Gateways and click Add gateway.

  2. Enter the gateway name, gateway ID, and the statistics interval (in seconds).

  1. Go to Edge management > Instances and click Manage edge integrations.

  2. Click Assign to edge, select the ChirpStack integration from the drop-down, and click Assign.

  3. Log in to your ThingsBoard Edge instance and confirm the integration appears under Integration center > Integrations.

In production, devices send uplink messages automatically. For testing, you can use the ChirpStack Device Simulator or send an HTTP message directly to the ChirpStack Application Server:

Terminal window
curl -v -X POST -d '{
"deduplicationId": "7658d04d-7f1c-4eb6-900b-d948f3061a9d",
"time": "2025-06-13T12:44:52.653+00:00",
"deviceInfo": {
"tenantId": "6e073e9a-6b4f-4747-b22c-7507568debfb",
"tenantName": "ChirpStack",
"applicationId": "c3f2c4aa-07c8-4d6c-8a86-7ea2d4a31dca",
"applicationName": "Sample Application",
"deviceProfileId": "d8ee6c09-414c-4b2e-888a-8e8f86e3187a",
"deviceProfileName": "Default device profile",
"deviceName": "chirp device",
"devEui": "24e124538b223213",
"deviceClassEnabled": "CLASS_A",
"tags": {}
},
"devAddr": "01a44c4c",
"adr": true,
"dr": 5,
"fCnt": 153,
"fPort": 84,
"confirmed": false,
"data": "AXU9AwABBAAB",
"rxInfo": [{
"gatewayId": "e4e124dadef64eee",
"uplinkId": 25127,
"gwTime": "2025-06-13T12:44:52.653481+00:00",
"nsTime": "2025-06-13T12:44:52.670509207+00:00",
"timeSinceGpsEpoch": "1433853910.653s",
"rssi": -68,
"snr": 13.2,
"channel": 4,
"location": {},
"context": "Hw9+zQ==",
"crcStatus": "CRC_OK"
}],
"txInfo": {
"frequency": 867300000,
"modulation": {
"lora": {
"bandwidth": 125000,
"spreadingFactor": 7,
"codeRate": "CR_4_5"
}
}
},
"regionConfigId": "eu868"
}' $YOUR_HTTP_ENDPOINT_URL -H "Content-Type:application/json"

Replace the following placeholders with your actual values:

PlaceholderDescription
deduplicationIdAny valid UUID v4 (for testing)
tenantIdYour ChirpStack tenant ID
applicationIdChirpStack Application ID
applicationNameChirpStack Application name
deviceProfileIdChirpStack device profile ID
deviceProfileNameChirpStack device profile name
devEuiDevice EUI from the ChirpStack device
gatewayIdChirpStack gateway ID
$YOUR_HTTP_ENDPOINT_URLHTTP endpoint URL from the ThingsBoard integration

After the message is sent, a new device is created in ThingsBoard Edge. To view its telemetry:

  1. Go to Entities > Devices, click the device, and select the Latest telemetry tab.

  2. Go to Integration center > Integrations, click the ChirpStack integration, and select the Events tab to view the received uplink message.

  3. To inspect how the uplink converter processed the message, go to Integration center > Data converters, open the uplink converter, and select the Events tab.