How to Decode Uplink Messages with Qubitro Decoder Functions
By following this guide, you can customize Qubitro decoder functions to decode various sensor payloads and extract valuable network metrics from any LNS integration.
This guide explains how to use Qubitro’s decoder functions to parse raw uplink messages received via LNS integrations—such as The Things Stack, Loriot, and others.
Although the examples here refer to decoding sensor data (like temperature or humidity), these functions work the same way for any LNS provider.
Key Concepts
Decoder Function
A custom function that Qubitro automatically invokes with an input object containing the uplink message’s raw data, the fPort, and additional metadata.
Input Properties
• bytes: A byte array representing the raw data payload.
• fPort: The port number used for the uplink message.
• metadata: Rich network details from the LNS (e.g., signal quality, gateway information), regardless of the provider.
How It Works
Qubitro supplies the decoder function with an input object that includes all necessary properties.
Your function should extract the required sensor values by converting raw bytes into human-readable data. You can also extract network metrics—like RSSI and SNR—from the metadata.
Accessing Input Properties
Create a simple decoder function that extracts the raw bytes, fPort, and metadata:
function decoder(input) {
var bytes = input.bytes; // Retrieve the raw data payload
var fPort = input.fPort; // Retrieve the fPort number
var metadata = input.metadata; // Retrieve LNS metadata
return {}; // Customize and return a JSON object as needed
}
Decoding a Temperature Sensor Message
In this example, assume that the sensor sends temperature data encoded in two bytes. The function converts these bytes into a decimal temperature value:
function decoder(input) {
const bytes = input.bytes;
const fPort = input.fPort;
// Combine two bytes into one number and adjust the scale (divide by 100)
const temperature = ((bytes[0] << 8) + bytes[1]) / 100;
return {
"bytes": bytes,
"fPort": fPort,
"temperature": temperature,
};
}
Decoding Temperature and Humidity Data
This example demonstrates handling multiple sensor readings. The function first checks if the payload is long enough and then extracts temperature and humidity from the last four bytes:
function decoder(input) {
var bytes = input.bytes;
var fPort = input.fPort;
var data = {};
// Ensure the payload contains enough data for both sensors
if (bytes.length < 4) {
return { error: 'Payload too short' };
}
// Extract bytes for temperature and humidity
var temperatureBytes = bytes.slice(bytes.length - 4, bytes.length - 2);
var humidityBytes = bytes.slice(bytes.length - 2);
// Convert the byte arrays into 16-bit integers and scale accordingly
var temperature = ((temperatureBytes[0] << 8) | temperatureBytes[1]) / 100.0;
var humidity = ((humidityBytes[0] << 8) | humidityBytes[1]) / 100.0;
data["temperature"] = temperature;
data["humidity"] = humidity;
return data;
}
Accessing Metadata for Network Metrics
Decoder functions can also extract network metrics (such as SNR and RSSI) from the metadata. This example demonstrates how to do so:
function decoder(input) {
var bytes = input.bytes; // Sensor data payload
var fPort = input.fPort; // fPort value
var metadata = input.metadata; // LNS metadata from the uplink
var snr, rssi;
// Extract network metrics if available (works with any LNS provider)
if (metadata && metadata.gws && metadata.gws.length > 0) {
snr = metadata.gws[0].snr; // SNR from the first gateway
rssi = metadata.gws[0].rssi; // RSSI from the first gateway
}
// Additionally decode sensor-specific data (example calculations)
return {
STATUS: bytes[0] & 0x01, // Sensor status
BATTERY: (25 + (bytes[1] & 0x0f)) / 10, // Battery level estimate
COUNT: (bytes[7] << 16) | (bytes[6] << 8) | bytes[5], // Count extracted from multiple bytes
SNR: snr, // Signal-to-noise ratio from metadata
RSSI: rssi // Received signal strength indicator from metadata
};
}
Last updated