← Back to Harvestree
Harvestree v5 LoRaWAN documentation

Downlink commands

Build FPort 4 frames, read FPort 2 ACKs, and look up writable parameter IDs.

Remote read/write of device settings over LoRaWAN after field deployment. First commissioning (ports, calibration, join keys) stays in Toolbox / USB.

Encoder

MOIZ does not ship a public downlink encoder here. Contact MOIZ for a tailored encoder (SOW). This page is enough to hand-build and verify frames.

1 · Transport

PathFPortWire layout
Network → device4[CMD:1][PAYLOAD…]
Device → network (ACK)2[CMD:1][STATUS:1][DATA…]
Measurements1Not used for command ACK

Class A: send the downlink queued for the next uplink’s RX window; the device answers later with an FPort 2 ACK.

2 · Commands

Only these CMD bytes are accepted on FPort 4. Anything else (including USB-only codes) → STATUS 0xEE.

CMDNameDownlink payloadACK DATA on success
0x03GET_VERSIONempty5 B version
0x04RESETempty, or 2 B delaynone
0x06GET_HW_VERSIONempty1 B
0x10GET_PARAMbatch of param IDsbatch of values
0x11SET_PARAMbatch of ID + valueusually none

3 · Build a frame

Hex below is the application payload on FPort 4 (then the matching FPort 2 ACK). Spaces are for readability only.

GET_VERSION — 0x03

No payload: send the command byte alone.

Bytes
Downlink FPort 403
ACK FPort 203 AA [TYPE][YEAR][V_MSB][V_LSB][PATCH]

TYPE = 0 (application). Example ACK: 03 AA 00 1A 0B 00 00 → app, year 0x1A, version fields, patch.

GET_HW_VERSION — 0x06

Bytes
Downlink06
ACK06 AA [HW] — one hardware-version byte

RESET — 0x04

Optional delay: uint16 LE, seconds, 0…300. Empty payload or 00 00 = reset right after the ACK is queued.

IntentDownlinkACK
Immediate0404 AA
Delay 60 s04 3C 0004 AA
Delay > 300 s—04 BF

GET_PARAM / SET_PARAM

See §5 · GET / SET batch. Encoding rules used everywhere:

4 · Errors

ACK layout: [CMD][STATUS][DATA…]. STATUS ≠ 0xAA means failure. For many param errors, DATA is the failing ID (2 B BE).

STATUSMeaningTypical cause
0xAASuccess—
0xBBInvalid payload sizeEmpty/truncated where bytes were required
0xBCInvalid value sizeSET LEN 0 or > 4, or length mismatch
0xBDInvalid batch sizeCOUNT 0 or > 6
0xBEInvalid structureTrailing bytes / truncated SET block
0xBFInvalid argumente.g. RESET delay > 300
0xEEUnknown commandWrong CMD or USB-only command
0xEFInvalid / forbidden PARAM_IDNetwork, port type SET, cert block…
0xF4Flash errorNVM commit failed
0xF5Config / validation / read-onlyOut of range or read-only field
0xF0–0xF3, 0xF6–0xF8Reserved / rare on field pathNot ready, busy, CRC, timeout, protected, auth
Examples

11 AA — SET OK · 11 EF 00 06 — SET of port type forbidden · 11 BE … — trailing garbage after SET batch.

5 · GET_PARAM & SET_PARAM (batch)

One command = one batch. First payload byte = COUNT (1…6). Need more than six IDs → several downlinks.

GET_PARAM 0x10SET_PARAM 0x11
Downlink[COUNT] {[ID:2]} × COUNT[COUNT] {[ID:2][LEN:1][VALUE:LEN]} × COUNT
LimitsEach ID = 2 BEach VALUE ≤ 4 B; no bytes after the last item
Success ACK10 AA [COUNT′] {[ID][LEN][VALUE]} × COUNT′11 AA (usually empty DATA)
Failure modelForbidden IDs skipped. ≥1 success → 0xAA with subset. None → 0xEFAll-or-nothing: one bad item rejects the whole batch; nothing committed

Worked batch — mode + period

SET MONITORING (0x0001=0) and period 1000 s (0x0002):

11 02 00 01 01 00  00 02 04 E8 03 00 00
│  │  └─ ID 0001, LEN 1, value 00
│  └──── COUNT = 2
└─────── SET_PARAM
                 └─ ID 0002, LEN 4, value E8 03 00 00 (= 1000 LE)

ACK: 11 AA

GET the same two IDs:

10 02 00 01 00 02
│  │  └─ ID 0001
│  └──── COUNT = 2
└─────── GET_PARAM
            └─ ID 0002

ACK (example): 10 AA 02 00 01 01 00 00 02 04 E8 03 00 00

6 · Parameter tables

Field catalog for remote tuning. Build SET items with LEN = Size. Wrong size → 0xBC; out of range → often 0xF5; policy deny → 0xEF.

Application — GET + SET

IDSizeEncodingRoleField values
0x00011u8App mode0 = MONITORING · 1 = ALARM
0x00024uint32 LENormal TX period (s)20…604800 — measure / uplink cadence when calm
0x00034uint32 LEKeepalive (s)3600…2592000
0x00042uint16 LEMin operating voltage (mV)3500…4000 — join / full TX gate
0x00051u8Magnetic reset0 = off · 1 = on

GET only

IDSizeEncodingRoleNotes
0x00004uint32 LEConfig counterRead-only; increments on each successful save
0x0006…0x00091u8Port 1…4 typeRead current mode codes; cannot SET over air (0xEF)

Alarms — GET + SET

Periods & system sources

IDSizeEncodingRoleField values
0x02004uint32 LEReactivity / check period (s)20…604800 — how often to wake and look when calm
0x02014uint32 LEAlarm TX / event period (s)20…604800 — uplink cadence while an alarm episode is active
0x02021u8 bitfieldSystem alarm enablesSee bitfield below (0…7)
0x02101u8HVT alarm typeAlarm type enum (below)
0x02114float32 LEHVT low threshold0.0…1000.0
0x02124float32 LEHVT high threshold0.0…1000.0
0x02201u8HEAT alarm typeAlarm type enum
0x02214float32 LEHEAT low (°C)−40.0…200.0
0x02224float32 LEHEAT high (°C)−40.0…200.0
0x02304float32 LEMOVE threshold (mg)0.0…15000.0 — used when MOVE bit is set in 0x0202

Alarm type enum (1 byte)

Used by HVT (0x0210), HEAT (0x0220), and each port variable type (0x0250+…). No hysteresis — decision from the current corrected sample only.

ValueNameFires whenThresholds used
0NONENever (disabled)—
1HIGHvalue ≥ highhigh only
2LOWvalue ≤ lowlow only
3INRANGEmin(low,high) ≤ value ≤ max(low,high)both (order-tolerant)
4OUTRANGEvalue < min(low,high) or value > max(low,high)both

System enables — 0x0202 (1 byte)

bit  7  6  5  4  3  2  1  0
     0  0  0  0  0  M  H  V
                    │  │  └─ 1 = HVT enabled
                    │  └──── 1 = HEAT enabled
                    └─────── 1 = MOVE enabled
HexMeaning
00All system alarms off
01HVT only
02HEAT only
04MOVE only
07HVT + HEAT + MOVE

Example SET enable HEAT+MOVE: 11 01 02 02 01 06 → ID 0x0202, LEN 1, value 0x06.

Per-port alarms

Port index p = 0…3 (Port 1…4). Variable index v = 0…4 — which quantity depends on the port type (e.g. ACCT: v=0 current RMS, v=1 frequency). Thresholds are in the same engineering unit as the corrected measurement (after calibration).

IDSizeEncodingRole
0x0240 + p1u8 bitfieldPort alarm flag (enables + ASYNC edge) — see below
0x0250 + p×16 + v1u8Alarm type for that port/variable (enum 0…4)
0x02C0 + p×16 + v×24float32 LELow threshold
0x02C1 + p×16 + v×24float32 LEHigh threshold

Port 1 var 0 → type 0x0250, low 0x02C0, high 0x02C1. Port 2 var 0 → 0x0260 / 0x02D0 / 0x02D1.

Port alarm flag — 0x0240 + p (1 byte)

bit  7  6  5  4  3  2  1  0
     0  E1 E0 V4 V3 V2 V1 V0
        └─┬─┘  └─────┬─────┘
     ASYNC edge   Variable enables
     (bits 5–6)   (bits 0–4)
BitsRoleEncoding
0…4Enable alarm eval for variable vbit v = 1 → that variable is armed. Example: var0 only → 0x01; var0+var1 → 0x03
5…6ASYNC_DRYC edge (only if that port is ASYNC_DRYC)00 = none (0) · 01 = rising (0x20) · 10 = falling (0x40). Both edges (11) rejected at validation
7ReservedMust stay 0
Example intentByteSET item (Port 1, p=0)
Arm var0 thresholds only0x0102 40 01 01 inside a SET batch
Arm var0 + var10x0302 40 01 03
ASYNC rising (no sync vars)0x2002 40 01 20
ASYNC falling + var00x4102 40 01 41

Full recipe for “Port 1, var 0, HIGH above 50”: SET type 0x0250=01, high 0x02C1=float 50, flag 0x0240=01 (and leave low unused or set a dummy).

Not over air

Toolbox / USB only (do not use downlink for these): port calibration (0x1000–0x4FFF), network keys/region (0x0100–0x01FF), port types (0x0006–0x0009), cert RF block, factory reset.