Smart Home · How-to
Every room at Villakurt holds its own temperature automatically — using battery Bluetooth sensors, a BLE-to-WiFi bridge, Home Assistant as the brain, and Sonoff relays driving the heating manifold. Here's the whole chain, end to end.
A tiny Bluetooth thermometer in each room reports the temperature; Home Assistant compares it to your target and switches the matching heating loop on or off. The hard part is getting a Bluetooth reading to a cloud-hosted Home Assistant — that's what TheengsGateway solves.
Closed loop: as the room warms, the BLE sensor reports it and Home Assistant stops calling for heat.
Each room has a small Xiaomi LYWSD03MMC / MJWSD05MMC
thermometer running custom ATC / PVVX firmware. Instead of
a proprietary app, the firmware broadcasts temperature,
humidity and battery in a plain BLE advertisement every few
seconds — no pairing, no connection, runs for ~a year on one CR2032 coin cell.
In Home Assistant these arrive as entities like
sensor.atc_584905_..._tempc.
BLE only travels a few metres and Villakurt's Home Assistant runs on a cloud server — so the signal can't reach it directly. A small always-on device at the house runs TheengsGateway: it listens to the BLE advertisements, decodes the Xiaomi/ATC/PVVX payload into real values, and republishes them over WiFi as MQTT messages. This is the BLE-to-WiFi conversion: Bluetooth in, MQTT-over-IP out.
TheengsGateway publishes to Mosquitto
(mqtt.villakurt.eu:1883), the home's message bus. Home Assistant
subscribes via its MQTT integration and turns each reading into a live
temperature sensor — the same path every other sensor at Villakurt uses.
Each zone is a Home Assistant generic_thermostat.
It ties a room's BLE sensor (target_sensor) to a heating relay
(heater) and applies the logic: heat when the room falls
0.2 °C below target, stop when it rises 0.2 °C above, drop to a
16 °C away mode when nobody's home, and re-send the command every
3 minutes (keep_alive) so a relay never misses a switch.
When a zone calls for heat, Home Assistant flips a Sonoff relay channel (via the eWeLink / SonoffLAN integration). That channel powers a thermoelectric actuator on the heating manifold, which opens the loop and lets warm water flow to that room's circuit. Turn the switch off and the actuator closes — simple, mechanical, reliable.
| Component | What it is | Role in the chain |
|---|---|---|
| Xiaomi LYWSD03MMC / MJWSD05MMC | BLE thermo-hygrometer, CR2032, flashed with ATC/PVVX firmware | Measures & broadcasts room temperature over Bluetooth |
| TheengsGateway | Open-source BLE-to-MQTT gateway on a local always-on host | Converts BLE advertisements → WiFi/MQTT |
| Mosquitto | MQTT broker (mqtt.villakurt.eu:1883) |
Message bus between the gateway and Home Assistant |
| Home Assistant | 8× generic_thermostat zones (upper + ground floor) |
The brain — compares temperature to target, commands the relays |
| Sonoff relays (×2, 4-channel) | eWeLink / SonoffLAN — one device per floor, 4 channels each | Switches power to the manifold actuators |
| Thermoelectric actuators | Manifold valve heads on the underfloor / radiator loops | Physically open / close each room's heating circuit |
Why this design? No cloud thermostats, no per-room wall units, no wiring back to a panel. Cheap battery sensors + a single BLE bridge + relays you already trust = per-room climate control that's fully local and survives an internet outage. Every reading is logged to InfluxDB, so the heating itself becomes data.