ThingPark Integration
The Actility ThingPark integration connects ThingsBoard to the ThingPark LoRaWAN network server. ThingPark pushes uplink messages from LoRaWAN devices to a ThingsBoard HTTP endpoint, where an uplink converter decodes them into device telemetry and attributes for real-time monitoring and visualization on dashboards. In the reverse direction, ThingsBoard encodes Rule Engine messages via a downlink converter and delivers them to devices through Actility.
Register a ThingPark account
Section titled “Register a ThingPark account”- Go to the ThingPark website and sign up for an account, or log in to your existing ThingPark Wireless OSS instance.
- Review the ThingPark documentation to familiarize yourself with the platform.
Register your device in ThingPark
Section titled “Register your device in ThingPark”- Log in to your ThingPark Wireless OSS instance and create an application (e.g. My Sensors).
- Add a new device to the application. Enter the DevEUI and AppEUI from the device label or documentation. Select the appropriate device profile.
- The DevEUI becomes the device name in ThingsBoard automatically after the first uplink.
Verify device connectivity
Section titled “Verify device connectivity”- Open the ThingPark Wireless Logger and confirm your device is transmitting uplinks.
- Note the DevEUI — you will see this value as the device name in ThingsBoard after integration.
ThingsBoard integration setup
Section titled “ThingsBoard integration setup”Create an uplink converter
Section titled “Create an uplink converter”The uplink converter decodes the incoming ThingPark message and maps it to the ThingsBoard data model. For the full decoder function reference, see Uplink data converter.
From ThingsBoard 4.0, you can map message fields to attributes or telemetry directly in the UI — no scripting needed for structured JSON payloads. For binary payloads, add a decoder script in the same wizard.
If your device is in the built-in catalog, use the Library tab — see Library for a built-in catalog of ready-to-use decoder functions for over 100 devices.
- Go to Integrations center ⇾ Data converters.
- Click + Add data converter ⇾ Create new converter.
- Set Converter type to Uplink (default).
- Select Integration type: ThingPark.
- Enter a converter name:
ThingPark Uplink Converter. - In Main decoding configuration:
- Set the device name pattern — e.g.
Device $eui— or leave the default. - Paste the decoder function below if your device sends binary payloads.
- Set the device name pattern — e.g.
Review Advanced decoding parameters — pre-populated for ThingPark with keys like
fCnt,rssi,snr,channel,decoded,fPort, andspreadingFactor. Adjust if needed; see Advanced decoding parameters.- Click Add.
/** * 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: {}};
// Extract the timestamp from metadata (represented in milliseconds). var timestamp = metadata.ts; // ts is the timestamp parsed from the incoming message's time, or returns the current time if it cannot be parsed.
if (metadata.payloadFormat == 'JSON') { // payloadFormat is 'JSON' when ThingPark sends a pre-decoded JSON payload // (DevEUI_uplink contains a "payload" object). // All fields from the decoded payload object are put directly into telemetry. var decoded = decodeToJson(input); result.telemetry = { ts: timestamp, values: decoded}; return result;}
// payloadFormat is 'BINARY' when raw hex payload is received (payload_hex field).
// 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);
// Combine the timestamp with decoded values and add it to the telemetry. result.telemetry = { ts: timestamp, values: { // Decode battery level from the 5th byte of the payload. battery: parseBytesToInt(input, 4, 1), // Decode temperature from the 6th and 7th bytes of the payload (divided by 100). temperature: parseBytesToInt(input, 5, 2) / 100.0, // Decode saturation from the 8th byte of the payload. saturation: parseBytesToInt(input, 7, 1)}};
// Return the fully constructed output object. return result; // Same logic, less code: // return { // attributes: { // sn: parseBytesToInt(input, 0, 4) // }, // telemetry: { // ts: convertDateToTimestamp(metadata.time), // 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: {}};
// Extract the timestamp from metadata (represented in milliseconds). var timestamp = metadata.ts; // ts is the timestamp parsed from the incoming message's time, or returns the current time if it cannot be parsed.
if (metadata.payloadFormat == 'JSON') { // payloadFormat is 'JSON' when ThingPark sends a pre-decoded JSON payload // (DevEUI_uplink contains a "payload" object instead of raw "payload_hex"). // All fields from the decoded payload object are put directly into telemetry. var decoded = decodeToJson(input); result.telemetry = { ts: timestamp, values: decoded}; return result;}
// payloadFormat is 'BINARY' when raw hex payload is received (payload_hex field).
// 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);
// 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: convertDateToTimestamp(metadata.time), // 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;
/** * Converts a byte array to a string and parses it as JSON. * * @param {number[]} payload - The array of bytes. * @returns {Object} - The parsed JSON object. */ function decodeToJson(payload) { return JSON.parse(String.fromCharCode.apply(String, payload));}
/** * 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;}Create the integration
Section titled “Create the integration”- Go to Integrations center ⇾ Integrations and click + Add integration.
- Basic settings:
- Set Integration type to ThingPark.
- Enter a name, e.g.
ThingPark integration. - Enable integration and Allow create devices or assets are on by default.
- Click Next.
- Uplink data converter:
- Click Select existing and choose the previously created ThingPark Uplink Converter.
- Click Next.
- Downlink data converter:
- Click Skip — only needed for sending commands to devices; can be added later.
- Connection:
- Copy the HTTP endpoint URL — paste this into your ThingPark application as the destination routing address so Actility forwards uplinks to ThingsBoard.
- Click Add.
Connection settings
Section titled “Connection settings”Base URL — the base address of the ThingsBoard server used to construct the HTTP endpoint URL. For ThingsBoard Cloud, this is https://thingsboard.cloud.
HTTP endpoint URL — the auto-generated webhook address for this integration. Paste this URL into your ThingPark application server routing profile as the destination so Actility forwards device uplink messages to ThingsBoard.
Enable security (Headers filter) — restrict incoming requests to those carrying a specific HTTP header and value. Click Add to define one or more Header / Value pairs. Requests missing a listed header or carrying an incorrect value are rejected.
Execute remotely — route integration processing to a remote integration instance running inside your private network, rather than on the ThingsBoard server.
Visualize data with dashboards
Section titled “Visualize data with dashboards”Once devices send uplinks through the ThingPark integration, their telemetry appears under Entities ⇾ Devices in ThingsBoard. Use Dashboards to build real-time visualizations: add widgets for temperature, battery level, GPS location, and any other fields decoded by your uplink converter. Dashboards support time-series charts, maps, gauges, and tables, and can be shared with customers or embedded in external applications.
Example
Section titled “Example”The Abeeway Trackers with Actility ThingPark guide demonstrates a complete end-to-end setup: registering Abeeway Micro and Industrial Trackers in ThingPark, creating uplink and downlink converters, building the integration, and visualizing GPS, battery, and temperature telemetry on a ThingsBoard dashboard.