Milesight WT101: LoRaWAN Smart Radiator Thermostat
Milesight WT101 LoRaWAN radiator thermostat: own ChirpStack/ThingsBoard decoder, decoded example, valve control and open-window detection.
- LoRaWAN
- Class A, OTAA/ABP
- Temperature range
- -20 to +60 °C, accuracy +-0.5 °C
- Valve fitting
- M30 x 1.5 mm, adapters for RA/RAV/RAVL/M28
- Battery
- 2x 1.5 V Li-FeS2 AA, up to 5 years
- Ingress protection
- IP30 (indoor)
- Heating plans
- 1 date period + up to 16 schedules
- Configuration
- NFC (Milesight ToolBox)
What the WT101 measures
Room temperature
Built-in sensor, -20 to +60 °C, 0.1 °C resolution; drives the valve toward the target temperature.
Target temperature
Setpoint the device is regulating to, set locally, by schedule or by downlink.
Valve opening
Current stepper-motor valve position as a percentage (0 to 100 %).
Window detection
Open-window event from a rapid temperature drop; can pause heating to save energy.
Tamper & freeze status
Install/uninstall (tamper) state and freeze-protection trigger to guard against frozen pipes.
Integration
Sensor / controller
Measures or controls in the field and sends LoRaWAN uplinks.
LoRaWAN gateway
Receives the radio packets and forwards them to the server.
ChirpStack
Network server: manages sessions and decodes the payload.
ThingsBoard / Grafana
Dashboards, alarms, rules and reports.
function decodeUplink(input) {
var bytes = input.bytes;
var data = {};
for (var i = 0; i < bytes.length; ) {
var channel = bytes[i++];
var type = bytes[i++];
if (channel === 0x01 && type === 0x75) { // battery (%)
data.battery = bytes[i]; i += 1;
} else if (channel === 0x03 && type === 0x67) { // room temperature (°C)
data.temperature = readInt16LE(bytes, i) / 10; i += 2;
} else if (channel === 0x04 && type === 0x67) { // target temperature (°C)
data.target_temperature = readInt16LE(bytes, i) / 10; i += 2;
} else if (channel === 0x05 && type === 0x92) { // valve opening (%)
data.valve_opening = bytes[i]; i += 1;
} else if (channel === 0x06 && type === 0x00) { // tamper status
data.tamper_status = bytes[i] === 1 ? "uninstalled" : "installed"; i += 1;
} else if (channel === 0x07 && type === 0x00) { // open-window detection
data.window_detection = bytes[i] === 1 ? "open" : "normal"; i += 1;
} else if (channel === 0x09 && type === 0x90) { // motor stroke
data.motor_stroke = readUInt16LE(bytes, i); i += 2;
} else if (channel === 0x0a && type === 0x00) { // freeze protection
data.freeze_protection = bytes[i] === 1 ? "triggered" : "normal"; i += 1;
} else if (channel === 0x0b && type === 0x90) { // motor current position
data.motor_position = readUInt16LE(bytes, i); i += 2;
} else {
break;
}
}
return { data: data };
}
function readUInt16LE(b, i) {
return ((b[i + 1] << 8) | b[i]) & 0xffff;
}
function readInt16LE(b, i) {
var v = readUInt16LE(b, i);
return v > 0x7fff ? v - 0x10000 : v;
}
Implemented from the published Milesight byte specification (Communication Protocol / User Guide).
Channel format: 01 75 battery (%), 03 67 room temperature (INT16 little-endian, /10), 04 67 target temperature (/10), 05 92 valve opening (%), 06 00 tamper, 07 00 open-window, 09 90 motor stroke, 0a 00 freeze protection, 0b 90 motor position. Implemented from the published Milesight byte specification. Downlink-response and heating-schedule frames (0xf8/0xf9/0xfe/0xff) appear only after configuration and can be added when needed; for ThingsBoard the same channel logic goes into an uplink converter.
Uplink (hex)
0175640367CD000467DC0005923C070000Decoded JSON
{ "battery": 100, "temperature": 20.5, "target_temperature": 22, "valve_opening": 60, "window_detection": "normal" }Configuration & pitfalls
NFC setup
Keys, reporting interval, heating plans and child lock are set over NFC with the Milesight ToolBox before mounting on the radiator.
Valve calibration
After fitting, run the motor stroke calibration so the device learns the valve travel; a failed calibration is reported and the valve will not regulate correctly.
Open-window strategy
Decide whether the valve keeps its position or closes when a window-open event fires, and tune the temperature-drop threshold to avoid false triggers from drafts.
Offline control mode
Choose how the valve behaves if LoRaWAN drops: keep position, run embedded temperature control, or close. Set this explicitly so rooms do not overheat during an outage.
How merkaio supports your WT101
From sourcing to day-to-day operation, all from one partner on our own European infrastructure.
Pre-staging & provisioning
We configure the WT101, set keys, intervals and alarms, and ship it ready to deploy.
Own decoder
Payload codec for ChirpStack v4 and ThingsBoard, implemented from the Milesight specification.
Dashboard integration
Data lands in your ThingsBoard or Grafana, with alarms and reports.
Operations & monitoring
We run the LoRaWAN stack and dashboards on European infrastructure, you just use the data.
Frequently asked questions
Let's discuss your infrastructure. Digital and on-site.
Whether it's IoT platform development, hardware selection, managed hosting for ChirpStack, ThingsBoard, Grafana or NetBird VPN, or migration from a self-hosted setup - we'll find the right solution for your use case. Book a free 30-minute consultation, no commitment required.
Your contact
Timo Wevelsiep
Founder, merkaio
15 minutes, no commitment, directly with Timo.
Decoder for ChirpStack v4. merkaio is an independent integrator and is not affiliated with Milesight.