LoRaWAN Parameters
Reference for decoding Fence Shield uplinks and sending remote configuration downlinks on your own LNS.
We're currently working on making this easy to configure from your Safora dashboard. More on that soon!
This page covers:
- Uplink payload format (FPorts 11–16)
- Downlink parameter commands (FPorts 17–19)
For device registration and connecting to the Safora platform, see LNS Registration.
A ready-made JavaScript payload codec is available under Files & Resources. Paste or import it into your LNS codec settings to easily decode uplinks and encode or decode downlinks. Most integrators only need the codec; raw hex examples below are for debugging or LNS UIs that send payloads manually.
Network basics
| Setting | Value |
|---|---|
| Activation | OTAA |
| LoRaWAN version | 1.0.3 |
| Typical region | EU868 (device may be configured for other plans at order time) |
Each uplink message type uses its own FPort. Downlink commands use FPorts 17–19.
Uplink messages
| Type | FPort | Confirmed | Description |
|---|---|---|---|
| Heartbeat (normal) | 11 | Optional | Regular status while fence is in the normal (high) state |
| Heartbeat (triggered) | 12 | Optional | Regular status while fence is in the triggered (low) state |
| Fence alert high | 13 | Yes | Fence voltage recovered above untrigger threshold |
| Fence alert low | 14 | Yes | Fence voltage dropped below trigger threshold |
| Motion detection | 15 | Yes | Motion sensor wake (no voltage readings in payload) |
| Parameter report | 16 | No | Snapshot of all configurable parameters |
Heartbeats are sent every HB_DIVISOR measurement cycles. A confirmed heartbeat is sent every CONFIRMED_HB_DIVISOR heartbeats.
Telemetry payload (FPorts 11–15)
Fence and battery messages carry a 3-byte payload:
Byte 0: fenceVoltagePos[11:4]
Byte 1: fenceVoltagePos[3:0] << 4 | batteryVoltage[11:8]
Byte 2: batteryVoltage[7:0]
Both values are 12-bit unsigned integers in millivolts (0–4095):
| Field | Meaning |
|---|---|
fenceVoltagePos | Calibrated positive fence ADC reading (mV), not scaled fence volts |
batteryVoltage | Calibrated battery voltage (mV) |
Decode with:
fenceVoltagePos_mV = (byte0 << 4) | (byte1 >> 4)
batteryVoltage_mV = ((byte1 & 0x0F) << 8) | byte2
fenceVoltage_V ≈ fenceVoltagePos_mV × 4.469
Motion (FPort 15): the payload intentionally contains no voltage measurements.
Parameter report (FPort 16)
The parameter report uses the same TLV wire format as downlink parameter updates (see Wire format). It includes all remotely configurable parameters plus the firmware version (read-only).
The firmware always builds reports in this order:
1:MEASURE_INTERVAL_DS(1 byte)2:HB_DIVISOR(1 byte)3:CONFIRMED_HB_DIVISOR(1 byte)4:FENCE_TRIGGER_VOLTAGE(2 bytes, big-endian, volts)5:FENCE_UNTRIGGER_VOLTAGE(2 bytes, big-endian, volts)6:LOW_BAT_TRIGGER_VOLTAGE(2 bytes, big-endian, mV)7:LOW_BAT_UNTRIGGER_VOLTAGE(2 bytes, big-endian, mV)8:USE_MOTION_DETECTION(1 byte, 0/1)9:FENCE_PULSE_MS(1 byte; encoded as worst-case pulse interval ms / 100)20:IMU_WOM_THRESHOLD(1 byte)24:IMU_WOM_DURATION(1 byte; typically 1–4 samples)100:FIRMWARE_VERSION(3 bytes: major, minor, patch)
Downlink commands
Downlink commands use dedicated FPorts. All multi-byte values are big-endian (MSB first).
| FPort | Purpose | Payload |
|---|---|---|
17 | Set parameters | One or more ParamID | Value TLV entries |
18 | Request parameter report | Empty (recommended) |
19 | Hard reset | 2-byte auth key 0x12 0x34 |
Notes:
- FPort
18ignores any payload bytes; send an empty payload. - FPort
17supports up to 16 parameter entries per downlink. If any entry is invalid, the whole update is rejected.
Wire format
Parameter set and parameter report payloads use TLV encoding. Value byte length is fixed per parameter ID:
+-----------+---------------+-----------+---------------+
| ParamID 1 | Value bytes 1 | ParamID 2 | Value bytes 2 | ...
+-----------+---------------+-----------+---------------+
All parameters are parsed and validated before any changes are applied. If any entry is invalid, the entire update is rejected.
Parameter IDs
Values on the wire use encoded units, not always the human unit you think of:
MEASURE_INTERVAL_DS: value × 10 s (so30= 300 s)FENCE_PULSE_MS: value × 100 ms (so40= 4000 ms)
Other fields use the units shown in the table (volts, mV, cycles, and so on).
| ID | Name | Size | Range | Units | Description |
|---|---|---|---|---|---|
1 | MEASURE_INTERVAL_DS | 1 byte | 1–180 | ×10 s | Measurement interval |
2 | HB_DIVISOR | 1 byte | 1–255 | cycles | Measurement cycles between heartbeats |
3 | CONFIRMED_HB_DIVISOR | 1 byte | 1–255 | heartbeats | Confirmed heartbeat interval |
4 | FENCE_TRIGGER_VOLTAGE | 2 bytes | 100–12000 | V | Fence low-voltage trigger (e.g. 1500 = 1.5 kV) |
5 | FENCE_UNTRIGGER_VOLTAGE | 2 bytes | 100–12000 | V | Fence recovery threshold |
6 | LOW_BAT_TRIGGER_VOLTAGE | 2 bytes | 2500–4000 | mV | Low-battery trigger |
7 | LOW_BAT_UNTRIGGER_VOLTAGE | 2 bytes | 2500–4000 | mV | Low-battery recovery |
8 | USE_MOTION_DETECTION | 1 byte | 0–1 | bool | Motion detection enable |
9 | FENCE_PULSE_MS | 1 byte | 10–255 | ×100 ms | Worst-case fence pulse interval (40 = 4000 ms) |
20 | IMU_WOM_THRESHOLD | 1 byte | 0–255 | n/a | IMU wake-on-motion threshold (higher = less sensitive) |
24 | IMU_WOM_DURATION | 1 byte | 0–255 | samples | IMU wake-on-motion duration (typically 1–4) |
100 | FIRMWARE_VERSION | 3 bytes | n/a | n/a | Read-only; included in parameter reports only |
Parameter IDs 21–23 (per-axis IMU thresholds) are reserved and currently ignored on set.
Default values
| Parameter | Default | Description |
|---|---|---|
| MEASURE_INTERVAL_DS | 6 | 60 seconds between measurements |
| HB_DIVISOR | 60 | Heartbeat every 60 measurement cycles (60 min at default interval) |
| CONFIRMED_HB_DIVISOR | 6 | Confirmed heartbeat every 6 heartbeats (6 h at default settings) |
| FENCE_TRIGGER_VOLTAGE | 1500 | 1.5 kV |
| FENCE_UNTRIGGER_VOLTAGE | 2500 | 2.5 kV |
| LOW_BAT_TRIGGER_VOLTAGE | 3000 | 3.0 V |
| LOW_BAT_UNTRIGGER_VOLTAGE | 3200 | 3.2 V |
| USE_MOTION_DETECTION | 0 | Disabled |
| FENCE_PULSE_MS | 40 | 4000 ms worst-case pulse interval |
| IMU_WOM_THRESHOLD | 90 | ~352 mg |
| IMU_WOM_DURATION | 4 | 4 samples before trigger |
When battery voltage drops below the low-battery trigger, the device automatically switches to reduced reporting intervals (30-minute measurement interval, heartbeat divisor 12).
Defaults balance battery life, alert responsiveness, and network load. Changing them (especially MEASURE_INTERVAL_DS, HB_DIVISOR, and CONFIRMED_HB_DIVISOR) trades one against the others. Custom configurations are used at your own risk. Safora can't guarantee battery life, alert timing, or performance.
Using the payload codec
Install the payload codec in your LNS, then encode downlinks with encodeDownlink. Codec field names use snake_case (see the codec file for the full list).
Encoded vs friendly units in the codec:
measure_interval_dsstill uses the wire unit (×10 s). Example:30= 300 s.fence_pulse_msuses milliseconds in the codec; it converts to/from the wire encoding for you.motion_enableduses a boolean.
Set measurement interval to 5 minutes
{
data: {
params: {
measure_interval_ds: 30 // 30 × 10 s = 300 s
}
}
}
Set interval to 60 s and heartbeat divisor to 120
{
data: {
params: {
measure_interval_ds: 6, // 60 s
hb_divisor: 120
}
}
}
Request a parameter report
{
data: {
request_report: true
}
}
Hard reset
{
data: {
reset: 0x1234
}
}
Raw hex examples
Use these if your LNS UI sends hex payloads directly, or when debugging without the codec. All multi-byte values are big-endian.
Set measurement interval to 300 s (5 min)
FPort: 17, Payload: 01 1E
01= MEASURE_INTERVAL_DS1E= 30 (encoded) = 300 s
Set interval to 60 s and heartbeat divisor to 120
FPort: 17, Payload: 01 06 02 78
Set fence trigger to 2000 V, untrigger to 3000 V
FPort: 17, Payload: 04 07 D0 05 0B B8
Request parameter report
FPort: 18, Payload: (empty)
Hard reset (clear LoRaWAN session, force new join)
FPort: 19, Payload: 12 34
Warning: the auth key must match 0x1234 or the reset is rejected. On success, the device clears its LoRaWAN session and deep-sleeps for 15 minutes before attempting to re-join.
Operational notes
- Downlink timing: queue the downlink on your LNS; the device receives it in the short receive window that opens after its next uplink. Delivery happens at the next wake/transmit cycle, not instantly.
- Persistence: parameter changes are saved to NVS flash and survive deep-sleep cycles (but not firmware reflashes).
- Immediate effect: parameters take effect on the next measurement cycle.
- Auto-report: successful parameter updates trigger a parameter report on the next wake cycle.