LoRaWAN®
Functions

April 18, 2024

How to Access and Decode LoRaWAN Uplink Messages with Qubitro Decoder Functions

This tutorial guides you through using Qubitro's decoder functions to effectively decode data from LoRaWAN uplink messages, enhancing your IoT applications.

Overview of Qubitro Decoder Functions

Qubitro decoder functions are designed to parse the raw data transmitted by IoT devices over the LoRaWAN network. The function has a single parameter named input, which is automatically supplied by Qubitro and includes several properties:

  • bytes: A byte array containing the raw data from the uplink message.
  • fPort: The LoRaWAN fPort used for the uplink message.
  • metadata: Metadata provided by the LoRaWAN Network Server (LNS), which can vary depending on the LNS provider.

Example: Basic Access of Properties

function decoder(input) {
  var bytes = input.bytes;  // Get the raw bytes
  var fPort = input.fPort;  // Get the port
  var metadata = input.metadata;  // Get the metadata

  return {};  // Return a JSON object
}

Decoding a Temperature Sensor Message

Let's consider a scenario where a LoRaWAN device sends temperature data encoded in the bytes array. The following example demonstrates how to decode this data.

Example Decoder Function for Temperature Data

function decoder(input) {
  const bytes = input.bytes;
  const fPort = input.fPort;

  // Assuming the temperature is sent as two bytes and needs conversion
  const temperature = ((bytes[0] << 8) + bytes[1]) / 100;

  // Constructing a JSON object to return
  const decodedData = {
    "bytes": bytes,
    "fPort": fPort,
    "temperature": temperature,
  };

  return decodedData;
}

This function extracts the temperature from the bytes array by converting the bytes into a binary number, then interpreting it as a decimal number, and finally adjusting the scale (if necessary).

Example Decoder Function for Temperature and Humidity

This example demonstrates how to decode both temperature and humidity data from a LoRaWAN uplink message that includes multiple sensor readings. It shows handling for payload length checks and byte extraction for each sensor.

function decoder(input) {
    var bytes = input.bytes;
    var fPort = input.fPort;
    var data = {};

    // Check if the payload is long enough to contain both temperature and humidity
    if (bytes.length < 4) {
        return { error: 'Payload too short' };
    }

    // Extract the last four bytes: two for temperature and two for humidity
    var temperatureBytes = bytes.slice(bytes.length - 4, bytes.length - 2);
    var humidityBytes = bytes.slice(bytes.length - 2);

    // Convert bytes to 16-bit integer values for both sensors
    var temperature = ((temperatureBytes[0] << 8) | temperatureBytes[1]) / 100.0;
    var humidity = ((humidityBytes[0] << 8) | humidityBytes[1]) / 100.0;

    // Store the decoded values in the data object
    data["temperature"] = temperature;
    data["humidity"] = humidity;

    return data;
}

This function carefully handles the extraction of sensor data, ensuring the payload contains adequate bytes before attempting to decode the values. It then decodes the bytes into temperature and humidity readings, providing precise data for further processing or alerting within IoT applications.

Accessing Metadata in Decoder Functions

Qubitro decoder functions handle data from input which not only includes bytes and fPort but also metadata containing rich details from uplink messages. This metadata often includes:

  • Network information
  • Signal quality indicators like RSSI and SNR
  • Timing and frequency details

Example: Accessing SNR and RSSI

Example Metadata Structure

{
  "cmd": "gw",
  "seqno": 12345,
  "EUI": "ABCD1234567890EF",
  "ts": 1111111111111,
  "fcnt": 6789,
  "port": 2,
  "freq": 123456789,
  "toa": 21,
  "dr": "SF8 BW125 4/5",
  "ack": true,
  "gws": [
    {
      "rssi": -40,
      "snr": 8.7,
      "ts": 1111111111111,
      "time": "2023-08-16T10:33:53.433Z",
      "gweui": "1111222233334444",
      "ant": 1,
      "lat": 45.123456,
      "lon": -1.234567
    }
  ],
  "bat": 150,
  "data": "abcdef1234567890"
}

Here’s how to write a decoder function that leverages the incoming metadata to extract specific network metrics alongside sensor data.

function decoder(input) {
    var bytes = input.bytes; // Raw sensor data bytes
    var fPort = input.fPort; // LoRaWAN port used for the uplink
    var metadata = input.metadata; // Full metadata from the uplink message
    var snr, rssi;

    // Check if metadata is present and contains gateway information
    if (metadata && metadata.gws && metadata.gws.length > 0) {
        snr = metadata.gws[0].snr; // Signal-to-noise ratio from the first gateway
        rssi = metadata.gws[0].rssi; // Received signal strength indicator from the first gateway
    }

    // Decoding sensor data and extracting additional metrics
    return {
        STATUS: bytes[0] & 0x01, // Sensor status
        BATTERY: (25 + (bytes[1] & 0x0f)) / 10, // Battery level calculation
        COUNT: (bytes[7] << 16) | (bytes[6] << 8) | bytes[5], // A count value extracted from multiple bytes
        SNR: snr, // SNR value
        RSSI: rssi // RSSI value
    };
}

This function not only decodes the temperature from the payload but also extracts SNR and RSSI, providing a comprehensive view of both the environmental condition and the transmission quality.

Conclusion

By using decoder functions in Qubitro, you can efficiently process complex data payloads from LoRaWAN uplink messages, unlocking the full potential of your IoT devices for advanced monitoring and automation tasks. These examples provide a foundation for developing robust applications capable of handling diverse environmental data.

For additional guidance and resources, refer to the Qubitro Documentation.

Couldn't find the guide you need?

Let us know what you're looking for, and we'll create the guide for you!

    Qubitro Logo

    Product

    Decision Aids

    Resources

    Company

    © 2024 Qubitro, Inc. All rights reserved