Sonoff TRVZB in Home Assistant – my setup, my pain, and what I wanna try out next
For a while I wanted to write down how my heating setup in Home Assistant actually works. Not because it's particularly simple, quite the opposite. But that's exactly why: I don't want to start from scratch again and have no idea why I built things the way I did. So. Let's go.
The hardware
Four Sonoff TRVZBs. One in the bathroom, two in the living room, one in the kitchen. Living room and kitchen are open-plan, which makes things a bit more interesting. On top of that, a couple of Zigbee temperature and humidity sensors in each room that act as external reference points.
The journey
Before I get into what I'm running now, quick recap of what I'm not running anymore and why.
Attempt 1: Versatile Thermostat. A HACS integration that turns any heating device into a "smart" virtual thermostat. It controls the TRV valve directly through calibration entities Sonoff exposed back then, the open and close angle settings, and uses those to regulate temperature via a TPI algorithm. The idea is solid: instead of just telling the valve "open" or "close", it modulates the opening percentage based on the difference between current and target temperature.
Problem: after some time, the little pin inside the valve started miscalculating. It would get stuck or lose its reference point. I had to pull the batteries, re-pair the device, and start over. A colleague of mine with the exact same hardware had the same experience. So I decided: I'm not touching those calibration values anymore. Disabled the entities and moved on.
Attempt 2: Smart Thermostat (PID). Same concept in principle, just a different algorithm. PID is theoretically more precise, it learns your room's thermal characteristics over time through Kp, Ki, and Kd gain values. There's a lot of tuning involved and it genuinely takes weeks to converge on something decent. I gave it a shot. After several weeks it started overshooting, the temperature would drop, the valve would open hard, overshoot the target, close, drop again. Classic oscillation from a poorly tuned PID. I didn't have the patience to tune it properly so I dropped it.
Then Sonoff shipped a firmware update.
Adaptive mode. Out of nowhere. A firmware feature that lets the valve modulate its pin position in percentage, basically what I'd spent hours trying to build manually from the outside. Their blog describes it like this:
Previously the TRV followed a simple logic: if the room temperature is below target, valve fully opens. Once target is reached, valve fully closes. With Smart Temperature Control enabled, it dynamically adjusts the valve opening based on actual conditions. When far from target it opens wider, when close to target it gradually reduces opening to prevent overshooting.
So yeah. All that time investment, for nothing. The firmware just does it now, internally, via its own PID.
The catch: it's still a black box. You can't see the actual valve opening percentage. You don't know for certain if it uses the external temperature sensor entities, the offset settings, or your window sensor. You just set a target temperature and trust the process. And honestly? It works pretty well. But it's summer right now so I can't properly test it.
What I'm actually running
Here's where it gets maybe slightly overkill for a 50m² apartment, but hear me out.
The core idea is simple: each room has a target temperature sensor (a template sensor) that the thermostat automation reads from. That template decides what the actual target should be based on the current mode. The mode itself is determined by another template sensor called activemode.
For the living room and kitchen group, the active modes are:
- Standard — normal target temperature, configurable via a number helper
- Away — lower temperature when nobody's home, detected automatically via person entities
- Boost — cranks the whole group to 25°C for a set duration
- Single Boost — boost for individual TRVs only, not the whole group
- Window open — drops target to 0°C when a window sensor fires, so the valve closes and you're not heating the outside
- Manual — automation disabled, you're on your own
The bathroom has the same logic plus one extra mode: Wake up. This one reads my phone's next alarm time via a sensor, calculates 15 minutes before it, and sets an input_datetime to that time. When that time hits, it activates a warm-up phase. The bathroom gets preheated before I'm even out of bed.
The automations tie everything together. A blueprint runs continuously and watches the target temperature sensor, then sets the climate entity on the TRVs accordingly. There are separate automations for boost timers: when boost activates, a timer starts, a delay runs, and when the delay finishes the boolean flips back off. The mode sensor re-evaluates and everything returns to normal. The individual TRV boosts work the same way but per-device.
I also have an automation that continuously writes the room temperature from my sensor into the TRV's external temperature entity, every 5 minutes and on state change. This matters because the TRVZB has a built-in temperature sensor right next to the radiator, which is basically useless. Feeding it the actual room temperature makes a noticeable difference.
The dashboard uses Bubble Card pop-ups. Tap the climate card, get a graph of temperature and humidity over 48h, plus controls for boost duration, individual radiator boosts, and target temperature adjustment per mode. Everything lights up visually when a boost is active.
What I'm thinking about next
I'm considering going back to Better Thermostat. It's a HACS integration I used as a fallback throughout all of this, and it was always the most stable option. It supports multiple control algorithms including MPC, PID with auto-tuning, TPI, and an AI time-based mode, and handles grouping multiple TRVs into one virtual thermostat natively. Beyond the algorithm stuff, it also handles things like automatically shutting the valves off when outside temperature exceeds a threshold, better window detection with configurable delays, and offset-based calibration that doesn't touch the dangerous calibration entities I burned myself on before.
The reason I stopped using it was always the same: I believed trusting the TRV's own firmware with a clean external temperature feed was the most reliable approach. I still think that might be true. But I never got to test Better Thermostat properly with the adaptive mode firmware running underneath it. That combination might actually be worth trying.
Currently all automations are disabled because it's warm enough that it doesn't matter. When winter comes back I want to make a real decision. Either stick with what I have, or give Better Thermostat a proper shot this time around.
This post is mostly so future-me knows where things stand. And if it helps someone else figure out their TRVZB setup, great. There's not a lot of clear documentation out there on this stuff. Most of it you just have to figure out yourself. Or ask me :3