Payload Format
Codec
A complete LoRaWAN payload codec with examples can be found in the TBD section. See also Decoder example for reference.
Overview
The payload of up and downlink messages consists of an arbitrary number of data structs (DS) of different types and lengths.
DS 1 | DS 2 | ... | DS n |
---|---|---|---|
Each data struct is a combination of a header and the actual data payload:
L | T | payload |
---|---|---|
The header consists of two fields:
Field | Description |
---|---|
L | Length of data struct, 1 byte, not including the length byte itself |
T | Data struct type, 1 byte |
Data Encoding
Signed integers use two’s complement for encoding.
Info
Unless otherwise noted, payloads will use little endian data encoding.
Uplinks
There are two different uplink payloads:
- Event message
- Regular Status Message
Note
All uplinks are sent to LoRaWAN port 15.
Event message
On every short or long button, press an event message is sent to the network. It contains the following data:
- Event and current state
- Button presses
- Button count
- temperature
- battery voltage
Button presses are considered the number of times the button has been pressed, even if it did not result in an action (press was too short or too long). Button counts are only presses, that are resulting in an action (short or long press).
Event message is either confirmed or unconfirmed depending on the actual setting.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length (0x09) | uint8 |
1 | 1 | Message type (0x02) | uint8 |
2 | 1 | Event bit 1:0: Current event bit 7: Current state (1: active, 0: idle) |
uint8 |
3 | 2 | Button presses since last reset | uint16 |
5 | 2 | Button counts since last reset | uint16 |
7 | 2 | Temperature in 1/100 °C | int16 |
9 | 1 | Battery voltage; Voltage in 1/100V - offset (170) | uint8 |
The current event is:
- 0: Short press in idle
- 1: Long press in idle
- 2: Short press in active
- 3: Long press in active
The reported current state is the button state after completion of the event.
Example
Payload 09:02:00:04:00:02:00:62:0A:94 is reporting the following values
Parameter | Value |
---|---|
Event | Event 0 (short press in idle), button in idle |
Button presses | 4 |
Button counts | 2 |
Temperature | 2658 - > 2658°C |
Battery-Voltage | 148 - > 148 + 170 = 3.18 V |
Status Message
The device sends a regular status messages at a configurable interval. The status message is always unconfirmed, regardless of the settings.
The status message consists of the following data structs.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length (0x08) | uint8 |
1 | 1 | Message type (0x01) | uint8 |
3 | 2 | Button presses since last reset | uint16 |
5 | 2 | Button counts since last reset | uint16 |
7 | 2 | Temperature in 1/100 °C | int16 |
9 | 1 | Battery voltage; Voltage in 1/100V - offset (170) | uint8 |
See also Event Massage for the difference between button presses and button counts.
Example
Payload 08:01:02:00:00:00:03:0A:95 is reporting the following values
Parameter | Value |
---|---|
Button presses | 2 |
Button counts | 0 |
Temperature | 2563 - > 25.63°C |
Battery-Voltage | 149 - > 149 + 170 = 3.19 V |
Downlinks
Downlink messages are used to change the configuration of the device. They use the same general payload format as uplinks.
Note
All downlinks must be sent on the LoRaWAN port 3!
Configuration messages are used to set an individual configuration of the device. Configuration messages can be concatenated and sent as one downlink message.
The default values for each option, and unit descriptions can be found on the Settings page.
Configuration of Text Fields
All text fields configured by downlink have to follow these conventions:
- Use only characters that can be displayed on the LCD. These are in general space, letters and digits
- Characters are ASCII encoded
- Up to 10 characters are supported
- If less than 10 characters are needed, no padding with spaces is needed
Some configuration messages are using a transition selector to identify the transition to be configured. This will select the transition to be configured:
- 0: Short transition from idle
- 1: Long transition from idle
- 2: Short transition from active
- 3: Long transition from active
- 4: Join message
Configuration
Configuration flags
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length 0x08 | uint8 |
1 | 1 | Message type 0x80 | uint8 |
2 | 1 | Flags Bit 7: Confirmed messages Bit 6: Transport mode Bit 5: Duty cycle |
uint8 |
3 | 1 | Event Mode (see below) | uint8 |
4 | 1 | Number of retransmissions | uint8 |
5 | 2 | Status message interval in minutes | uint16 |
7 | 2 | Temperature measurement interval in seconds | uint16 |
Event mode is a bit field split into:
- Bit 1..0: Short press in idle
- Bit 3..2: Long press in idle
- Bit 5..4: Short press in active
- Bit 7..6: Long press in active
Each of the bit fields can be set to
- 0: Event disabled
- 1: Event will do a transition to idle
- 2: Event will do a transition to active
- 3: Not allowed
??? example
Payload **08:80:A0:42:04:A0:05:2C:05** is setting following configuration
| Parameter | Value |
|---------------------------|--------------------------------------------------------------------|
| Flags | Confirmation: on, Transport mode: off, Duty cycle enforcing: on |
| Event mode | Short press _idle_ to _active_; long press from _active_ to _idle_ |
| Number of retransmissions | 4 |
| Status interval | 1440 minutes = 24 hours |
| Temperatureinterval | 300 seconds = 5 minutes |
Text for Transport Mode
Set text message shown in transport mode.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 1 + character count | uint8 |
1 | 1 | Message type 0x81 | uint8 |
2:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Configuration for Idle State
Set text message and display time for idle mode.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 2 + character count | uint8 |
1 | 1 | Message type 0x82 | uint8 |
2 | 1 | Display time in 100 ms | uint8 |
3:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Configuration for Active State
Set text message and display time for active mode.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 1 + character count | uint8 |
1 | 1 | Message type 0x83 | uint8 |
2 | 1 | Display time in 100 ms | uint8 |
3:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Configuration of Transitions
Set text message for a state transition.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 2 + character count | uint8 |
1 | 1 | Message type 0x84 | uint8 |
2 | 1 | Transition selector | uint8 |
3:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Text for Success
Set text message and timing for a successful state transition.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 3 + character count | uint8 |
1 | 1 | Message type 0x85 | uint8 |
2 | 1 | Display time in 100 ms | uint8 |
3 | 1 | Transition selector | uint8 |
4:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Text for Fail
Set text message for an unsuccessful state transition. Timing is configured using Text for Success message.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 2 + character count | uint8 |
1 | 1 | Message type 0x86 | uint8 |
2 | 1 | Transition selector | uint8 |
3:X | 0 to 10 | up to 10 ASCII characters | ASCII |
Configuration of Display Timings
Configure button and magnet timings. All timing values are in 100 ms unites.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 5 (or 7) | uint8 |
1 | 1 | Message type 0x87 | uint8 |
2 | 1 | Short press minimum value | uint8 |
3 | 1 | Short press maximum value | uint8 |
4 | 1 | Long press minimum value | uint8 |
5 | 1 | Long press maximum value | uint8 |
6 | 1 | Magnet activation time from transport mode | uint8 |
7 | 1 | Magnet reset time | uint8 |
Magnet timing is optional and can be omitted (both or none). Message length needs to be adjusted accordingly.
Reset
Reset the device. This will reset the device after a given delay and will set the device to transport mode.
Device reset can be used to manually rejoin the device with the network or change the network if the reset is done with delay.
Byte | Size | Description | Format |
---|---|---|---|
0 | 1 | Message length: 7 | uint8 |
1 | 1 | Message type 0xFF | uint8 |
2 | 1 | Magic number (0xF98BD419) | uint32 |
6 | 1 | Flag: If bit 6 is set, device will reset into transport mode | uint8 |
7 | 1 | Reset delay in seconds | uint8 |
Example
Payload 07:FF:19:D4:8B:F9:00:0A will reset the device after 10 seconds and rejoin the network.
It will not enable transport mode
Downlink Examples
Example
TBD Payload 08:80:A0:42:04:A0:05:2C:05 is setting following configuration
Parameter | Value |
---|---|
Flags | Confirmation: on, Transport mode: off, Duty cycle enforcing: on |
Event mode | Short press idle to active; long press from active to idle |
Number of retransmissions | 4 |
Status interval | 1440 minutes = 24 hours |
Temperatureinterval | 300 seconds = 5 minutes |
Decoder example
// Actual decoder function
function decodeUplink(msg, port) {
var decoded = {};
if (port == 15) {
var l = msg.splice(0, 1)[0];
var type = msg.splice(0, 1)[0];
switch (type) {
case 1:
// status
decoded.buttonPress = msg[0] + (msg[1] * 256);
decoded.buttonCount = msg[2] + (msg[3] * 256);
decoded.temperature = (msg[4] + (msg[5] * 256)) / 100;
decoded.vBatt = msg[6] * 0.01 + 1.7;
break;
case 2:
// event
decoded.event = msg[0];
decoded.next_state = (msg[0] & 0x80) > 0 ? 1 : 0;
decoded.button = msg[0] & 0x7F;
decoded.buttonPress = msg[1] + (msg[2] * 256);
decoded.buttonCount = msg[3] + (msg[4] * 256);
decoded.temperature = (msg[5] + (msg[6] * 256)) / 100;
decoded.vBatt = msg[7] * 0.01 + 1.7;
break;
default:
// unknown message
break;
}
}
return decoded;
}
// Hex string to array of bytes>
function decodeInputHexString(byteArray) {
var length = byteArray.length;
var hexArray = [];
for (var i = 0, j=0; i < length; i+=2,j++) {
hexArray[j] = byteArray[i]+byteArray[i+1];
//parse hex
hexArray[j] = parseInt(hexArray[j],16)
}
return hexArray;
}
// example event message
//msg = { data: "09020004000200620A94", port: 15 };
// example status message
msg = { data: "080102000000030A95", port: 15 };
// Hex string to byte array
bmsg = decodeInputHexString(msg.data);
// decode
data = decodeUplink(bmsg, msg.port);