Decoder and firmware family
MOIZ publishes the official payload decoder harvestree_decoder.js for ChirpStack (v3/v4) and The Things Network. Use it as the FPort 1 application codec — on the LNS when it hosts codecs, or in your integration service if it does not. Align it with the firmware family deployed in the field. Source → JS decoder.
- ChirpStack v4:
decodeUplink(input) - ChirpStack v3:
Decode(fPort, bytes) - The Things Network:
Decoder(bytes, port)
Common JSON fields (all frames)
| Key | Description |
|---|---|
serial_number | 24-bit device serial from payload |
boardTemperature | Board temp (°C) |
baseTemperature | Baseplate Pt1000 temp (°C) |
storageVoltage | Storage voltage (mV) |
thermogenVoltage | Thermogenerator voltage (mV) |
status | Frame type (lower 2 bits): 0 keepalive, 1 normal, 2 alarm |
alarm_source_port | 1 if a port alarm is active — only when status = 2 |
alarm_source_system | 1 if a system alarm is active (HVT / HEAT / MOVE) — only when status = 2 |
| status | Meaning | Ingestion |
|---|---|---|
| 0 | Keepalive | Health metrics only; no port measurement keys |
| 1 | Normal measurement | Health + dynamic port keys |
| 2 | Alarm | Health + port keys + alarm source flags |
Port measurements use keys {family}_{port} or {family}_{port}_{suffix}. Numeric values are already in engineering units — do not re-scale.
{
"serial_number": 123456,
"boardTemperature": 24,
"baseTemperature": 61,
"storageVoltage": 3720,
"thermogenVoltage": 180,
"status": 1,
"pt_1": 58.2,
"weatherA_2_temp": 21.5,
"weatherA_2_humidity": 47.0,
"weatherA_2_frost": 12.0
}
Keepalive example (no port keys):
{
"serial_number": 23104,
"boardTemperature": 16,
"baseTemperature": 45,
"storageVoltage": 3600,
"thermogenVoltage": 52,
"status": 0
}
Alarm example (port threshold):
{
"serial_number": 23118,
"boardTemperature": 23,
"baseTemperature": 30,
"storageVoltage": 3600,
"thermogenVoltage": 49,
"status": 2,
"alarm_source_port": 1,
"alarm_source_system": 0,
"pt_1": 85.2
}
Full key catalog → Payload & JSON.
Recommended persistence (3 layers)
Decode FPort 1 with the MOIZ reference decoder — on the LNS when available, or in your integration service. Then separate static identity, immutable receive records, and analytics-friendly metrics:
- Dedup key:
(deveui, f_cnt). - Detect port-type drift: compare uplink bytes 1–4 vs registry.
- Store server receive time and/or LNS
time(device has no absolute clock in the uplink). - When
status = 0, do not expect (or synthesize) port measurement keys.