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 reserved Always 0xFF — not exposed in decoded JSON 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, bits 2–3 of the status nibble indicate sources; the reference decoder exposes them as alarm_source_port (bit 2) and alarm_source_system (bit 3, HVT/HEAT/MOVE)

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 (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
AC current (CT coil, RMS) acct_1, acct_1_hz RMS + frequency (333 mV secondary) float32 (A), 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 LF velocity RMS (int16, scale 0.01) in mm/s; HF acceleration RMS in m/s²; 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)

Industrial integration (IT / data)

Database design, ingestion pipelines, SCADA/historian patterns, validation checklist, and runnable examples (Python, Node.js) are documented in the Harvestree Integration Guide.

Summary backend rules:

  • Use serial_number and DevEUI for device identification in ingest pipelines.
  • Persist raw payload and decoded JSON for traceability.
  • Apply int16 scale factors before storing business metrics.
  • If status is keepalive (0), do not expect port measurement keys.

Example decoded payloads

Keepalive frame

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

Measurement frame (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
}