Harvestree LoRaWAN Payload Decoding

How to decode Harvestree LoRaWAN application uplinks (frame layout, keys, and examples).

← Communication

This document is focused on server-side usage:

  • how to decode each field into business data,
  • what units to expose in APIs and dashboards,
  • how to handle keepalive vs measurement payloads,
  • what to do with invalid or unsupported data.
  • The manufacturer provides reference decoding examples (for example JavaScript) to accelerate integration on common LoRaWAN platforms.

Reference JavaScript decoder (ChirpStack / TTN)

harvestree_decoder.js — reference decoder for ChirpStack (v3/v4) and The Things Network. Copy it into your LoRaWAN application payload codec. MOIZ updates this file to match the latest decoding documentation.


Bytes Field Meaning Decoding
0 command_id Metadata byte (do not use for business logic) uint8
1..4 port1..4 Port measurement type codes uint8 × 4
5..7 serial_number Device serial number 24-bit little-endian
8 boardTemperature Internal board temperature °C = byte - 40
9 baseTemperature Internal base temperature °C = byte - 40
10..12 Packed power + status Battery, thermogenerator, status bit-unpack (below)
>=13 Port measurements Concatenated data for configured ports variable length

Packed fields (bytes 10..12)

  • Storage voltage (mV): bytes[10] + ((bytes[11] & 0x03) << 8) + 3300
  • Thermogenerator voltage (mV): ((bytes[11] >> 2) & 0x3F) + ((bytes[12] & 0x0F) << 6)
  • Status nibble: (bytes[12] >> 4) & 0x0F

Status interpretation

  • status & 0x03 == 0: keepalive (no measurement section expected)
  • status & 0x03 == 1: normal measurement payload
  • status & 0x03 == 2: alarm payload
  • On alarm payloads, higher bits indicate alarm source flags (port/system)

Measurement keys for APIs and dashboards

Naming: <key>_<port> or <key>_<port>_<suffix>, with <port> in 1..4 (examples below use port 1).

Reserved port codes (0x11, 0x15, 0x17) are not used in production configurations.

Temperature

Measurement JSON keys (port 1) Meaning Unit / type
PT1000 pt_1 RTD temperature °C (int16, scale 0.1)
Thermocouple type K tck_1_cjt, tck_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type J tcj_1_cjt, tcj_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type T tct_1_cjt, tct_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type N tcn_1_cjt, tcn_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type S tcs_1_cjt, tcs_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type E tce_1_cjt, tce_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type B tcb_1_cjt, tcb_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Thermocouple type R tcr_1_cjt, tcr_1_hjt Cold / hot junction °C (int16, scale 0.1) each
Digital temperature probe (ref A) dtempA_1 Probe temperature °C (int16, scale 0.1)
Infrared (ref A) irA_1 Object temperature °C (int16, scale 0.1)

Environmental

Measurement JSON keys (port 1) Meaning Unit / type
Temperature and humidity weatherA_1_temp, weatherA_1_humidity, weatherA_1_frost Air temperature, humidity, frost index °C, %RH, frost byte

Voltage

Measurement JSON keys (port 1) Meaning Unit / type
DC voltage dcv_1 Single-ended DC mV (int16, scale 0.1)
AC voltage (RMS) acv_1, acv_1_hz RMS + fundamental frequency mV RMS, Hz (int16, scale 0.1)
DC differential voltage dcdv_1 Differential DC mV (int16, scale 0.1)
AC differential voltage (RMS) acdv_1, acdv_1_hz RMS + frequency mV RMS, Hz (int16, scale 0.1)
DC differential + external amplifier dcdvEx_1 Amplified differential DC float32 (project-defined unit)
AC differential + external amplifier (RMS) acdvEx_1, acdvEx_1_hz RMS + frequency float32, Hz

Magnetic field

Measurement JSON keys (port 1) Meaning Unit / type
DC magnetic sensor dcmh_1 DC magnetic quantity float32 (project-defined unit)
AC magnetic sensor (RMS) acmh_1, acmh_1_hz RMS + frequency float32, Hz

Current

Measurement JSON keys (port 1) Meaning Unit / type
DC current (voltage difference) dccs_1 DC current from ΔU sensing float32 (project-defined unit)
AC current (voltage difference, RMS) accs_1, accs_1_hz RMS + frequency float32, Hz
DC current (magnetic sensor) dcch_1 DC current from magnetic pickup float32 (project-defined unit)
AC current (magnetic sensor, RMS) acch_1, acch_1_hz RMS + frequency float32, Hz

Industrial analog

Measurement JSON keys (port 1) Meaning Unit / type
4–20 mA loop fourtwenty_1 Loop quantity float32 (project-defined unit)
Potentiometer pot_1 Position / calibrated quantity float32 (project-defined unit)

Vibration

Measurement JSON keys (port 1) Meaning Unit / type
Analog 1-axis vibration vib_1_rms_lf, vib_1_rms_hf, vib_1_ratio_lf_0..2, vib_1_ratio_hf_0..1 LF/HF RMS + sub-band energy ratios RMS (int16, scale 0.01); ratios (uint8 / 255)

Dry contact

Measurement JSON keys (port 1) Meaning Unit / type
Dry contact (synchronous) dryc_1 Contact state uint8 (0 open, 1 closed)
Asynchronous dry contact (Alarm mode) async_dryc_1 Contact state on alarm check uint8 (0 open, 1 closed)

Integration rules (backend)

  • Use serial_number (from payload) as a practical key for device identification and data organization in ingest pipelines.
  • Persist raw payload and decoded JSON for traceability.
  • For int16 scaled values, apply scale before storing business metrics (0.1 step).
  • For float32 channels, unit is application-dependent; expose unit metadata from your device configuration context.
  • If status indicates keepalive, do not expect measurement keys.
  • If payload length is inconsistent with configured port measurements, reject the frame and flag decoding error.

Dashboard recommendations

  • Separate clearly:
  • device health metrics (storageVoltage, thermogenVoltage, internal temperatures),
  • process metrics (port measurements),
  • alarm state (status + source flags).

Example decoded payloads

Keepalive frame

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

Measurement frame (PT1000 on port 1)

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