Dragino LHT65 Payload Decoder

Decode Dragino LHT65 LoRaWAN payloads online: battery, SHT temperature and humidity, and the DS18B20 external probe. Includes the payload structure, verified examples and a decodeUplink codec for ChirpStack v4 and The Things Stack.

Type: Temperature & humidity sensor with external probe LoRaWAN class: Class A FPort: 2 Payload: 11 bytes Endianness: Big-endian

Example payloads

CBF60B0D02560109327FFF Battery 3.062 V (good) · 28.29 °C · 59.8 % · DS18B20 probe at 23.54 °C
CBF60B0D0256017FFF7FFF Same readings with the external probe disconnected (0x7FFF sentinel)
CBF6FEA102560109327FFF Negative built-in temperature: −3.51 °C (two's complement)

Payload structure

Bytes Field Type / scale Description
0–1 Battery + status uint16, bitfield Bits 15–14: battery status (0 = ultra-low, 1 = low, 2 = OK, 3 = good). Bits 13–0: battery voltage in mV.
2–3 Built-in temperature (SHT) int16 ÷ 100 → °C Signed two's complement. Example: 0x0B0D = 2829 → 28.29 °C; 0xFEA1 = −351 → −3.51 °C.
4–5 Built-in humidity (SHT) uint16 ÷ 10 → %RH Example: 0x0256 = 598 → 59.8 %.
6 External sensor type uint8 0x01 = DS18B20 temperature probe (the default cable shipped with the LHT65).
7–8 External temperature (DS18B20) int16 ÷ 100 → °C 0x7FFF is a sentinel meaning the probe is not connected.
9–10 Reserved Unused when the external sensor is the DS18B20 probe.

Ready-to-use codec

ChirpStack v4 and The Things Stack share the same decodeUplink(input) signature: paste this into the device profile codec (ChirpStack) or the payload formatter (TTN).

function decodeUplink(input) {
  var b = input.bytes;
  function int16(i) { var v = (b[i] << 8) | b[i + 1]; return v >= 0x8000 ? v - 0x10000 : v; }
  var data = {
    battery_v: ((b[0] << 8 | b[1]) & 0x3FFF) / 1000,
    battery_status: ["ultra_low", "low", "ok", "good"][(b[0] >> 6) & 0x03],
    temperature_c: int16(2) / 100,
    humidity_pct: ((b[4] << 8) | b[5]) / 10,
    ext_sensor: b[6]
  };
  if (b[6] === 1) {
    var raw = (b[7] << 8) | b[8];
    data.ext_temperature_c = (raw === 0x7FFF) ? null : int16(7) / 100;
  }
  return { data: data };
}

The Dragino LHT65 sends its periodic sensor uplink on FPort 2 as a fixed 11-byte, big-endian frame. It combines a built-in SHT-series temperature/humidity sensor with an external connector, which in the standard kit carries a DS18B20 temperature probe on a cable.

Three details are worth knowing when you write or debug a decoder for it:

  • The battery field carries two values. The two most significant bits are a battery status code, and the remaining 14 bits are the voltage in millivolts. Masking with 0x3FFF is mandatory — decoding the whole 16 bits gives voltages above 50 V.
  • Temperatures are signed. Both the internal and the external temperature use int16 two’s complement divided by 100. A decoder that does not handle the sign shows −3.51 °C as 652.85 °C.
  • 0x7FFF means “no probe”. When the DS18B20 is not connected, bytes 7–8 contain the sentinel 0x7FFF, not a temperature. The codec on this page returns null in that case.

References

  • Dragino LHT65 user manual (payload chapter) — dragino.com
  • The codec above follows the same field names used across the Yubox tools.