github KartoffelToby/better_thermostat 1.9.3

4 hours ago

🚨 Action Required: Update Better Thermostat BEFORE updating Home Assistant to 2026.10

Important

Please install Better Thermostat 1.9.3 before updating your Home Assistant instance to 2026.10.
If you update Home Assistant first, your thermostats will reset to factory defaults on every reboot, losing your target temperatures, modes, presets, and learned room properties.

🛑 What you need to do:

  1. Update Better Thermostat to 1.9.3 first (via HACS or manual download).
  2. Restart Home Assistant.
  3. Now update Home Assistant to 2026.10.

❓ Why does this order matter?

On Home Assistant 2026.10, earlier versions of Better Thermostat lose their memory every time your system restarts. Your thermostats come back up on generic defaults — forgetting your target temperature, heating mode (Heat/Off), presets (Eco, Comfort, Sleep), and the thermal speeds your rooms have learned.

  • Why this happens: Home Assistant 2026.10 cleans up its startup memory immediately after booting. Older versions of Better Thermostat waited until Home Assistant had fully booted before asking for your saved settings, only to find that memory already wiped clean.
  • How 1.9.3 fixes it: Better Thermostat now captures and locks in your saved temperatures before Home Assistant can clear that memory.
  • Already upgraded to 2026.10? Don't panic — simply update Better Thermostat to 1.9.3 now and restart. While Home Assistant is actively running, your current settings remain in place, and 1.9.3 will keep them safely preserved for all future reboots.
  • Sliders and switches were already safe. Number and switch entities (like calibration numbers and presets) already saved their state differently and were never affected.

🌡️ Radiators take over when your room sensor goes silent

If your room temperature sensor ran out of battery, lost connection, took too long to wake up after a reboot, or sent an unreadable reading, Better Thermostat previously stalled during startup or gave up on heating the room.

  • The TRV's internal sensor steps in as a fallback. When the external room sensor stays unavailable or sends invalid readings past the startup grace window, Better Thermostat automatically regulates on the TRV's internal temperature so your home stays warm.
  • Control smoothly returns when the sensor wakes up. As soon as the room sensor reports a valid reading again, Better Thermostat switches right back to it. The temperature filter is restarted cleanly so historical cold readings do not skew the current room temperature, and any "implausible temperature" repair notice on your dashboard is cleared automatically.
  • Startup never hangs on a slow weather forecast. If your weather service takes too long to reply, Better Thermostat gives it 10 seconds and then moves on with starting the room, instead of freezing indefinitely.
  • One offline radiator no longer blinds the entire room. Previously, if a single TRV in a room was unavailable, event listeners bailed out early — ignoring window contacts, door sensors, and humidity updates for the whole room. The rest of your room now continues listening and heating normally.

🔒 Child-locked and switched-off dials stay as you set them

Interacting with physical TRV dials previously led to several confusing surprises: turning a knob on a child-locked device did not revert right away; switching a valve on at its knob was not recognized by the room; and adjustments made while the thermostat was off or windows were open unexpectedly took over when heating turned back on. All resolved.

  • Child-locked devices turn back immediately. When someone turns a dial or presses a button on a child-locked TRV, Better Thermostat immediately commands it back to its locked temperature and mode, even if the report arrives in the middle of an active control cycle.
  • Switching a head on at the dial turns the room on. Turning a physical TRV knob out of off is now cleanly recognized, bringing the room into heating mode.
  • No surprise setpoint jumps when heating resumes. Turning a dial while the thermostat was turned off or while a window was open is no longer remembered to hijack your target temperature when the room turns back on.
  • Turning back to the current target counts as a manual turn. If you turn a knob back to the temperature Better Thermostat last commanded, it is now treated as an intentional manual adjustment rather than ignored as an echo of its own past write.
  • Off-grid targets are adopted reliably. Turning a knob toward a target that sits between the device's step boundaries is adopted accurately instead of discarded.

❄️ Overheating protection leaves an idle valve closed

When your room reached its target temperature and went idle, overheating protection was supposed to prevent overshoot. Instead, an inverted calculation below the target + tolerance line did the exact opposite: it lowered the local offset and raised the setpoint, silently opening the valve and heating a room that was already warm enough.

  • Protection is now strictly neutral below the line. Up to target plus tolerance, overheating protection leaves the setpoint and offset untouched. Radiator valves stay firmly closed when the room is idle.

🧮 Predictive heating (MPC v2) runs on every system

The smart predictive heating mode (MPC v2) previously depended on a specialized software library (daqp) that was unavailable on many Home Assistant setups, such as Raspberry Pi and various ARM installations. Without it, MPC either failed or used a slower fallback that lagged behind.

  • A built-in solver replaces external dependencies. Better Thermostat now includes its own pure Python/NumPy quadratic programming solver, bringing identical, optimal valve control to every Home Assistant architecture with zero extra setup.
  • Disturbance estimates stay stable across reboots. Running disturbance estimates are held within a realistic physical bound (3 K per hour), matching the restored state so restarts do not cause sudden setpoint swings.
  • Glitchy sensor readings hold the valve safely. If an outdoor or room sensor temporarily reports invalid or infinite values, MPC v2 holds the previous valve position and logs a clear note rather than crashing or closing the valve.
  • Setpoint reductions are followed cleanly. The reference governor now tracks setpoint drops accurately even in mild weather when the steady-state valve opening is very small.

💾 Learned room speeds survive restarts and power cuts

Better Thermostat continuously learns how quickly each room heats up and cools down. This update ensures that learned knowledge safely survives reboots, power cuts, and software updates without getting wiped or corrupted.

  • Corrupted files are quarantined, not lost. If stored runtime state cannot be read or contains unexpected shapes, it is copied to a .corrupt backup file before any defaults are applied, preserving your data for recovery.
  • Learned properties are saved on shutdown. Any pending learned heating rates waiting in memory are saved directly to disk when Home Assistant shuts down.
  • Clean slate across host reboots. Integrator history and PID error tracking reset cleanly across a host reboot so temperature changes during downtime do not cause integral windup.
  • Coolers do not distort passive heat loss. The heat-loss tracker now pauses learning for several minutes after an active cooling unit shuts down, so the steep temperature drop from air conditioning is not mistaken for poor room insulation.

📐 Fahrenheit temperatures and step sizes behave natively

Several unit conversion quirks on Fahrenheit systems have been ironed out:

  • Sensible outdoor temperature threshold. The suggested outdoor temperature to pause heating now defaults to a comfortable 68 °F instead of literally 20 °F (which prevented heating above -6.7 °C!).
  • Crisp whole-degree setpoints. Target temperatures and presets round cleanly to whole degrees or your device's exact step size without fractional drift.
  • Valve maintenance restores the right unit. Temperatures restored after weekly anti-sticking maintenance are written back in Fahrenheit rather than accidentally converted as Celsius.
  • Radiators without an off mode turn off cleanly. Devices that lack an off mode and turn off by parking at their minimum temperature are now correctly recognized as off on Fahrenheit systems.

⚡ Failing devices back off quietly instead of flooding your log

When a radiator was unreachable or refused a command, Better Thermostat previously retried every few seconds, filling your Home Assistant logbook with error tracebacks and wasting CPU power.

  • Exponential backoff for failing cycles. A control cycle with persistent TRV errors pauses and backs off instead of immediately spinning the loop. Permanent device errors are logged at most once per hour instead of every few seconds.
  • Single-probe cycles for out-of-reach TRVs. Once a device has exhausted its retries, Better Thermostat checks it only once per heating cycle so the rest of your home is not delayed.
  • Cleaner logs. Intermediate retries are kept in debug logs; only an exhausted retry chain leaves a concise warning.
  • Lighter database load. Historical outdoor temperature averages are cached in memory instead of querying the Home Assistant database on every single sensor update.
  • Clear blueprint notification names. Notifications from Better Thermostat blueprints now use the friendly device name rather than raw internal IDs.

🔧 Fixes for deCONZ, Sonoff TRVZB, Eurotronic and range-only TRVs

  • deCONZ calibration offset scaling. Temperature offset values are now scaled into centidegrees to match deCONZ's internal format.
  • Sonoff TRVZB under ZHA. Direct valve position control is now offered during setup when paired through ZHA, and sensor entity detection is much more reliable after device renames.
  • Eurotronic & select-based valves. Mode selections and calibration offset writes use blocking service calls that wait for confirmation, ensuring failures are caught and reported accurately.
  • Range-only thermostats. Radiators that only support temperature ranges receive their heating target through the correct range channel (target_temp_low) rather than failing on unsupported single-target commands.
Full commit-level changelog

What's Changed

  • fix: reset an MQTT TRV onto its manual preset instead of "none" (1.9) by @cl445 in #2275
  • fix: restore the HVAC mode after maintenance only when it moved (1.9) by @cl445 in #2277
  • fix: re-send the room temperature to mirroring TRVs on a timer (1.9) by @cl445 in #2279
  • fix: rename BT entity ids only when the thermostat was renamed (1.9) by @cl445 in #2273
  • fix: report degraded mode while a TRV is unavailable (1.9) by @cl445 in #2283
  • fix: read "a head is off" the same way at startup and at runtime (1.9) by @cl445 in #2285
  • fix: debounce internal TRV temperature per device instead of per room (1.9) by @cl445 in #2296
  • fix: let the MPC governor follow setpoint reductions (1.9) by @cl445 in #2297
  • fix: cancel the plateau timer when the entity is removed (1.9) by @cl445 in #2298
  • fix: skip unreadable TRV modes when snapshotting for valve maintenance (1.9) by @cl445 in #2304
  • fix: write select-based calibration offsets through the right service (1.9) by @cl445 in #2313
  • fix: stop reporting valve support for TRVs without a valve quirk (1.9) by @cl445 in #2318
  • fix: report refused valve writes in the TRVZB quirk (1.9) by @cl445 in #2322
  • fix: write the deCONZ calibration offset in the units deCONZ reads (1.9) by @cl445 in #2330
  • fix: report refused device writes in the model quirks (1.9) by @cl445 in #2332
  • fix: wait for the device before reporting an adopted TRV as tweaked (1.9) by @cl445 in #2335
  • fix: keep the control cycle running when a TRV write fails (1.9) by @cl445 in #2295
  • fix: let the entity cancel the background tasks it started (1.9) by @cl445 in #2338
  • fix: read MQTT offset bounds for a TRV without a calibration entity (1.9) by @cl445 in #2345
  • fix: restore the temperature range a cooler publishes (1.9) by @cl445 in #2349
  • fix: refresh the cached TRV mode when a control cycle ends (1.9) by @cl445 in #2347
  • fix: offer direct valve control where the model's quirk drives the valve (1.9) by @cl445 in #2354
  • fix: observe a TRV switched back on at its own knob (1.9) by @cl445 in #2356
  • test: run the async tests without a file-local anyio backend (1.9) by @cl445 in #2352
  • fix: link the BT device by via device id (1.9) by @cl445 in #2363
  • fix: read the TRV key when migrating a config entry to version 18 (1.9) by @cl445 in #2371
  • fix: pin the setpoint adoption rule in production instead of rebuilding it in tests (1.9) by @cl445 in #2377
  • fix: confirm a calibration offset the device reports a full step away (1.9) by @cl445 in #2379
  • fix: remember the setpoints a device may still echo after an unconfirmed write (1.9) by @cl445 in #2382
  • docs: name the Python floor where reporters look by @cl445 in #2387
  • fix: remove the door sensor repair issue with the config entry by @cl445 in #2460
  • fix: leave the config entry data untouched when building diagnostics by @cl445 in #2461
  • fix: log the setpoint a TRV reported, not only BT's clamped view of it (1.9) by @cl445 in #2467
  • fix: reuse the outdoor history mean instead of querying the recorder on every update (1.9) by @cl445 in #2469
  • fix: cancel a pending Away on return and apply the battery throttle (1.9) by @cl445 in #2470
  • fix: name the thermostat in blueprint notifications from the device input (1.9) by @cl445 in #2474
  • fix: keep a room listening while one TRV is unreachable (1.9) by @cl445 in #2417
  • fix: controller state survives a host reboot and names what the load drops (1.9) by @cl445 in #2425
  • fix: MPC v2 runs without daqp and plans with the disturbance (1.9) by @cl445 in #2427
  • fix: start a room without a TRV that outlasts the startup grace window (1.9) by @cl445 in #2421
  • fix: keep valve maintenance away from a TRV that is not set up yet (1.9) by @cl445 in #2457
  • fix: weather and mode decoding keep the room heating (1.9) by @cl445 in #2426
  • Write a range-only head's setpoint as its lower bound (1.9) by @cl445 in #2488
  • fix: let MPC v2 without daqp command what daqp would, and hold the valve on a non-finite plan (1.9) by @cl445 in #2456
  • fix: adopt a one-step cooling press, turn a child-locked device back at once, and keep a switched-on room as heat (1.9) by @cl445 in #2454
  • fix: platforms read the thermostat after boot (1.9) by @cl445 in #2424
  • fix: let platform entities follow algorithm and name changes, and make device triggers fire on the change they name (1.9) by @cl445 in #2451
  • fix: apply room readings in arrival order, clear the temperature repair, re-read a lost battery level (1.9) by @cl445 in #2420
  • fix: re-read a stored battery level when the battery entity reports a new one (1.9) by @cl445 in #2478
  • docs: wrap the long lines in the MPC v2 QP solver docstrings (1.9) by @cl445 in #2502
  • fix: back off a failing control cycle, retry valve writes, give the startup sync its retries (1.9) by @cl445 in #2418
  • fix: keep TRV events that arrive during a control cycle (1.9) by @cl445 in #2419
  • fix: bound the weather forecast call so startup cannot stall on it (1.9) by @cl445 in #2472
  • fix: read a head turned back to its last confirmed setpoint as the user's turn (1.9) by @cl445 in #2513
  • fix: skip disabled and device-less registry entries (1.9) by @cl445 in #2422
  • fix: keep each thermostat to one entry and make migration, repairs and settings consistent (1.9) by @cl445 in #2448
  • fix: start the room at its heads' setpoint and let learning reach the measured rates (1.9) by @cl445 in #2449
  • fix: back off a control cycle that keeps failing and stop the loop's watchdogs with the entity (1.9) by @cl445 in #2453
  • fix: send the cooler its setpoint on its own grid, turn back a locked press during a cycle, and log failed retries once (1.9) by @cl445 in #2455
  • fix: switching a head on does not adopt a setpoint turned while it was off (1.9) by @cl445 in #2521
  • fix: Fahrenheit writes and defaults (1.9) by @cl445 in #2423
  • fix: report a refused mode write and give an out-of-reach TRV one write attempt per cycle (1.9) by @cl445 in #2452
  • bump version bump to 1.9.3 by @KartoffelToby
  • fix: control on the TRV temperature once the room sensor stays unavailable (1.9) by @cl445 in #2479
  • fix: start a room on the TRV temperature when its sensor outlasts the startup grace window (1.9) by @cl445 in #2484
  • fix: take a setpoint the device already holds as Better Thermostat's own (1.9) by @cl445 in #2530
  • fix: keep a copy of unreadable controller state and save pending learning on stop (1.9) by @cl445 in #2450
  • fix: a report after a head's switch-on does not bring the turn either (1.9) by @cl445 in #2544
  • fix: correct a head turned to the room's target during a cycle (1.9) by @cl445 in #2526
  • fix: take a reading the debounce turned away once the interval is over (1.9) by @cl445 in #2524
  • fix: keep overheating protection from raising an idle setpoint (1.9) by @ovsteenb in #2492
  • fix: read an entry's settings from its options as well as its data (1.9) by @cl445 in #2591

Full Changelog: 1.9.2...1.9.3

New Contributors

Don't miss a new better_thermostat release

NewReleases is sending notifications on new releases.