Dragino LHT65N/S-DC LoRaWAN Dry Contact Sensor Integration Guide
Model catalog
Search for these models in ThinkLink by name or ID.
| Model type | Name | id_name | Platform model ID |
|---|---|---|---|
| RPC | [LHT65N-S-DC GET] 21313 | lht65n_s_dc_get_21313 | 134064840598515716 |
| RPC | [LHT65N-S-DC SET] 21313 | lht65n_s_dc_set_21313 | 134064840598515715 |
| Template | LHT65N-S-DC | LHT65N-S-DC_21313 | 134064840598515712 |
| Thing Model | [LHT65N-S-DC] | lht65n_s_dc_21313 | 134064840598515713 |
| Parameter Thing Model | [LHT65N-S-DC-PARA] | lht65n_s_dc_para_21313 | 134064840598515714 |
1. Sensor Overview
The Dragino LHT65N-DC and LHT65S-DC are LoRaWAN 1.0.3 Class A dry-contact sensors. They report switch state or interrupt events, a 32-bit pulse counter, internal temperature and humidity, battery health, and radio-link quality. The device joins by OTAA and uses a 2400 mAh non-rechargeable CR17450 Li-MnO2 battery.
| Item | Value |
|---|---|
| Project | DRAGINO-21313-LHT65N-S-DC |
| Business code | 21313 |
| Vendor / Models | Dragino / LHT65N-DC, LHT65S-DC |
| Tenant | PUBLIC |
| Template | LHT65N-S-DC |
| Default region | CN470 |
| Default uplink period | 43200 s (12 hours) |
| Default downlink FPort | 2 |
2. Product Features
- Native LoRaWAN Class A operation without EdgeBus or an external DTU.
- EXT=4 dry-contact state and interrupt reporting; EXT=8 32-bit pulse counting.
- Both-edge, falling-edge, or rising-edge interrupt modes and selectable pulse-counting edge.
- Temperature, humidity, battery voltage, and battery status in each real-time frame.
- Device-information query for firmware, band, sub-band, and battery voltage.
3. Application Scope and Wiring
- Passive contacts from door sensors, relay outputs, leak detectors, smoke detectors, and SOS devices.
- Cumulative counting from low-power pulse sources such as flow sensors.
- Low-power sites that need contact events and ambient temperature/humidity together.
Passive contact: one wire to VCC/VDD, the other wire to INT
Powered pulse source: VCC to VCC/VDD, GND to GND, signal to INTVerify that an externally powered input remains below 3.3 V before connecting it. Life-safety applications must not rely on this device or one wireless path alone.
4. Data Acquisition
4.1 FPort 2 Real-time Frame
The DC real-time payload is exactly 11 bytes in big-endian order:
| Bytes | Field | Encoding and Conversion |
|---|---|---|
| 0–1 | battery_status, battery | top 2 bits status; low 14 bits mV; ÷1000 V |
| 2–3 | temperature | int16BE ÷100 °C |
| 4–5 | humidity | low 12 bits of uint16BE ÷10 %RH |
| 6 bit7–4 | no_ack, poll_message, time_sync_ok, unix_time_request | each 0/1 |
| 6 bit3–0 | external_mode | 0x04=interrupt, 0x08=counting |
| 7 | dry_contact_state | EXT=4; 1=closed, 0=open |
| 8 | interrupt_event | EXT=4; 1=interrupt, 0=periodic |
| 7–10 | pulse_count | EXT=8; uint32BE |
Examples:
FPort 2: CBA40ABB025C0401017FFF
battery=2.980 V, battery_status=Good, temperature=27.47 °C,
humidity=60.4 %RH, external_mode=interrupt,
dry_contact_state=1, interrupt_event=1
FPort 2: CBA40ABB025C080000003C
external_mode=counting, pulse_count=60The parser accepts only 11-byte frames with EXT=4 or EXT=8. It adds rssi, snr, and adr when gateway metadata supplies them.
4.2 FPort 5 Device Information
| Bytes | Field | Encoding |
|---|---|---|
| 0 | sensor_model | fixed 0x0B |
| 1–2 | firmware_version | version nibbles |
| 3 | frequency_band | Dragino band enumeration |
| 4 | sub_band | 0xFF=N/A |
| 5–6 | battery | uint16BE mV ÷1000 V |
FPort 5: 0B01560BFF0BA4
sensor_model=LHT65N/S, firmware_version=1.5.6,
frequency_band=CN470, sub_band=N/A, battery=2.980 VFPort 3 historical replay and non-DC external probes are outside this model.
5. EdgeBus Model
This is a native LoRaWAN sensor. It requires no EB code and sends data directly through the LoRaWAN network.
6. Thing Models
The lht65n_s_dc_21313 telemetry model processes FPort 2. The lht65n_s_dc_para_21313 parameter model processes FPort 5.
| Field | Type | Unit | Meaning |
|---|---|---|---|
battery | number | V | Battery voltage |
battery_status | string | — | Ultra Low / Low / OK / Good |
temperature | number | °C | Internal temperature |
humidity | number | %RH | Internal humidity |
external_mode | string | — | interrupt / counting |
dry_contact_state | number | — | Contact state, EXT=4 |
interrupt_event | number | — | Interrupt origin, EXT=4 |
pulse_count | number | count | Cumulative count, EXT=8 |
no_ack / poll_message | number | — | Protocol flags |
time_sync_ok / unix_time_request | number | — | Time flags |
rssi / snr | number | dBm / dB | Gateway link quality |
adr | boolean | — | Adaptive data-rate state |
Core decoding logic:
const rawBattery = bytes.readUInt16BE(0);
const externalModeCode = bytes[6] & 0x0f;
telemetry.battery = Number(((rawBattery & 0x3fff) / 1000).toFixed(3));
telemetry.temperature = Number((bytes.readInt16BE(2) / 100).toFixed(2));
telemetry.humidity = Number(((bytes.readUInt16BE(4) & 0x0fff) / 10).toFixed(1));
if (externalModeCode == 0x04) {
telemetry.dry_contact_state = bytes[7] ? 1 : 0;
telemetry.interrupt_event = bytes[8] ? 1 : 0;
} else {
telemetry.pulse_count = bytes.readUInt32BE(7);
}7. Third-party Data Subscription
MQTT topic:
/v32/{Organization Account}/tkl/up/telemetry/{eui}Example:
{
"eui": "6353012af10a9331",
"active_time": "2026-07-26T08:35:48.000Z",
"thingModelId": "134064840598515713",
"thingModelIdName": "lht65n_s_dc_21313",
"telemetry_data": {
"battery": 2.98,
"battery_status": "Good",
"temperature": 27.47,
"humidity": 60.4,
"external_mode": "interrupt",
"dry_contact_state": 1,
"interrupt_event": 1,
"rssi": -72,
"snr": 8.5
}
}8. RPC
8.1 Settings
lht65n_s_dc_set_21313 builds one Class A user downlink per invocation:
| Setting | Parameter | Range | Downlink |
|---|---|---|---|
| Uplink period | period_up | 1–16777215 s | 01 + uint24BE |
| Both-edge interrupt | interrupt_both | — | A2 04 01 |
| Falling-edge interrupt | interrupt_falling | — | A2 04 02 |
| Rising-edge interrupt | interrupt_rising | — | A2 04 03 |
| Falling-edge counting | counting_falling | — | A2 08 01 00 |
| Rising-edge counting | counting_rising | — | A2 08 01 01 |
| Set cumulative count | pulse_count | 0–4294967295 | A2 08 02 + uint32BE |
period_up=43200 -> 01 00 A8 C0
pulse_count=60 -> A2 08 02 00 00 00 3C8.2 Device-information Query
lht65n_s_dc_get_21313 always sends 26 01. The device returns its information on a later FPort 5 uplink.
A Class A device normally receives a downlink only in receive windows following an uplink. RPC completion confirms downlink construction and submission, not that the device has applied a setting.
9. Template Selection
Select this PUBLIC template:
- Template:
LHT65N-S-DC - id_name:
LHT65N-S-DC_21313 - Template ID:
134064840598515712
Template defaults:
| Attribute | Default |
|---|---|
class_mode | ClassA |
standard | CN470 |
period_up | 43200 s |
downlink_port | 2 |
external_mode | interrupt_both |
pulse_count | 0 |
Register the OTAA device with the DevEUI, JoinEUI/AppEUI, and AppKey from its label; never store keys in the integration project. Match the band to the firmware and network. After first join, request device information to verify the band and firmware.
10. Testing and Additional Notes
The local test/lht65n_s_dc.test.mjs suite covers EXT=4, EXT=8, negative temperature, status flags, invalid port/length/EXT, FPort 5, all SET commands, GET, and JSON/template/index consistency.
Official references:
- https://www.dragino.com/products/lorawan-nb-iot-door-sensor-water-leak/item/328-lht65n-s-dc.html
- https://wiki.dragino.com/docs/LoRaWAN-End-Node/temperature-humidity-sensors/lht65n/
- https://wiki.dragino.com/docs/Configuration/end-node/lht65n-dc-connection-instruction/
- https://github.com/dragino/dragino-end-node-decoder/tree/main/LHT65N