IT / Data integration

Application data contract

JSON output, frame types, decoder installation, and versioning.

← Home

Decoder and firmware family

MOIZ publishes the official payload decoder harvestree_decoder.js for ChirpStack (v3/v4) and The Things Network. Download it from the payload decoding documentation and install it on your LNS as the FPort 1 application codec. MOIZ updates the decoder with firmware releases — align it with the firmware family deployed in the field (see Release notes).

Entry points:

  • ChirpStack v4: decodeUplink(input)
  • ChirpStack v3: Decode(fPort, bytes)
  • The Things Network: Decoder(bytes, port)

Common JSON fields (all frames)

KeyDescription
serial_number24-bit device serial from payload
boardTemperatureBoard temp (°C)
baseTemperatureBaseplate Pt1000 temp (°C)
storageVoltageStorage voltage (mV)
thermogenVoltageThermogenerator voltage (mV)
statusFrame type (lower 2 bits of the status nibble): 0 keepalive, 1 normal, 2 alarm — unchanged; alarm sources are separate fields below
alarm_source_port1 if a port alarm is active; 0 otherwise. Present on every frame; meaningful when status = 2
alarm_source_system1 if a system alarm is active (HVT / HEAT / MOVE); 0 otherwise. Present on every frame; meaningful when status = 2

Frame types and ingestion rules

statusMeaningIngestion
0KeepaliveHealth metrics only; no port measurement keys
1Normal measurementHealth + dynamic port keys (pt_1, vib_2_rms_lf, …)
2AlarmHealth + port keys + check alarm_source_port / alarm_source_system (one or both may be 1)

Dynamic measurement keys

Port measurements use keys {family}_{port} or {family}_{port}_{suffix}. The decoder derives keys from port configuration bytes in the uplink header (wire bytes 1–4). Byte 0 is reserved (0xFF) and is not included in decoded JSON. Numeric values are already in engineering units (°C, mV, mm/s, …) — see Unit mapping in Data model. Full binary layout: Payload decoding.

Example decoded payloads

Keepalive

{
  "serial_number": 23104,
  "boardTemperature": 16,
  "baseTemperature": 45,
  "storageVoltage": 3600,
  "thermogenVoltage": 52,
  "status": 0,
  "alarm_source_port": 0,
  "alarm_source_system": 0
}

PT1000 on port 1

{
  "serial_number": 23118,
  "boardTemperature": 23,
  "baseTemperature": 30,
  "storageVoltage": 3600,
  "thermogenVoltage": 49,
  "status": 1,
  "alarm_source_port": 0,
  "alarm_source_system": 0,
  "pt_1": 25.0
}

Weather on port 2 (multiple keys per port)

{
  "serial_number": 23118,
  "boardTemperature": 22,
  "baseTemperature": 28,
  "storageVoltage": 3580,
  "thermogenVoltage": 48,
  "status": 1,
  "alarm_source_port": 0,
  "alarm_source_system": 0,
  "weatherA_2_temp": 21.4,
  "weatherA_2_humidity": 58.2,
  "weatherA_2_frost": 0
}

Alarm (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
}

Only needed if your platform sends configuration downlinks. The reference codec decodes FPort 1 only — parse ACKs in your integration service.

OffsetFieldDescription
0CMDEcho of the downlink command byte
1STATUS0xAA = success; full status table in LoRaWAN remote configuration
2+DATAOptional; present for successful GET_PARAM

Versioning

Align the LNS codec and deployed firmware using Release notes. Firmware version can be read over USB (Toolbox) or via downlink GET_VERSION — see LoRaWAN remote configuration if you use downlink.