Self-learning, weather-aware heating control for Home Assistant
⚠️ Use at your own risk. ThermoSmart is not affiliated with Home Assistant or Nabu Casa. It controls physical heating devices. Always set a safe minimum temperature and verify behaviour in Observation mode before enabling Active Control.
ThermoSmart observes how your building heats and cools, then uses that data — together with weather forecasts and presence detection — to control your TRVs. One config entry = one heating zone.
- Learns your building — heating rate, heat loss and weather sensitivity derived from real observations in your home, not factory defaults
- Adapts to conditions — outdoor temperature, wind, solar radiation and forecasts feed into every decision
- Starts passively — Observation mode collects data without touching your existing setup
- Fully local — no cloud, no subscription
Features: automatic pre-heating · TPI control with learned coefficients · weather-aware setpoints · slope-based window detection · outcome scoring to improve learning quality
A dedicated Lovelace card is available: thermosmart-card
Temperature ring, drag-to-set, mode buttons, history sparkline, confidence bar — install separately via HACS (Frontend).
Three heating zones managed by ThermoSmart. The temperature ring shows current and target temperature at a glance. Mode buttons, outdoor conditions, and a history graph (Actual / Target / Outdoor) are visible per zone. Screenshot uses the optional thermosmart-card Lovelace frontend.
HACS → Integrations → ⋮ → Custom repositories → URL: https://github.com/Mikasmarthome/ThermoSmart → Category: Integration → Add
HACS → Integrations → find ThermoSmart → Download → select the latest release → Download
Restart Home Assistant, then: Settings → Integrations → Add Integration → ThermoSmart
Add ThermoSmart System first (Summer mode select + Vacation switch), then add each heating zone.
Observation mode is recommended to start. With Active Control off, ThermoSmart watches your existing TRVs and builds an initial thermal model without changing anything in your setup. Use the first day or two to verify that sensors, temperatures, and schedules are configured correctly — then enable Active Control whenever you're ready. Learning continues in both modes; Observation mode is not a prerequisite.
| Step | Fields |
|---|---|
| 1 – Devices | Zone name · TRVs · Temperature sensors (optional) · Humidity sensors · Window / door sensors · Window delays · Valve maintenance · Calibration invert |
| 2 – Temperatures | Comfort · Night · Away · Vacation · Eco · Tolerance · Weekday/weekend schedule times |
| 3 – Presence | Person entities · Home zone · Learning on/off |
| 4 – Weather | Weather entity · Outdoor temp/humidity · Wind speed · Solar radiation · Precipitation |
External temperature sensors are optional. Since v1.0.3, ThermoSmart automatically uses the TRV's built-in temperature sensor as fallback when no external sensor is configured. Adding a dedicated room sensor improves accuracy, but is not required to get started.
| Entity | Description |
|---|---|
climate.thermosmart_* |
Virtual thermostat — target/current temp, HVAC mode, presets |
select.*_mode |
Heating mode: Auto / Comfort / Eco / Night / Away / Vacation |
switch.*_active_control |
Active Control on/off |
switch.*_learning |
Learning algorithm on/off |
sensor.*_status |
Zone status |
sensor.*_confidence |
Learning progress 0–100 % |
sensor.*_adjusted_target |
Configured target temperature (schedule or mode) |
sensor.*_preheat_minutes |
Calculated preheat lead time in minutes |
Additional diagnostic sensors (disabled by default): TRV setpoint · TPI duty-cycle · Weather offset · Temperature slope · Heat loss · Heating power · Outcome score · Solar gain · TRV observations · Window cooling rate · EMA temperature
Note:
sensor.*_confidenceand the Heat Loss, Heating Power, Outcome Score, TRV Observations, and Window Cooling Rate diagnostic sensors are backed by the Learning Engine — their values and extra attributes reflect the Learning Engine's model state.
| Entity | Description |
|---|---|
select.thermosmart_summer_mode |
Summer mode — automatic / on / off |
switch.thermosmart_vacation_mode |
Vacation mode — all zones → vacation temperature |
switch.thermosmart_global_debug |
Debug Log — enables DEBUG logging for the integration at runtime |
ThermoSmart includes a Device Profile system that enables correct behaviour across a wide range of TRVs out of the box. Each profile encodes the device's target_temp_step, temperature limits, and any quirks — so ThermoSmart can write precise setpoints without manual calibration.
For devices without a specific profile, ThermoSmart falls back to a generic profile that works with any climate entity supporting set_temperature.
Real-world tested with active ThermoSmart control:
| Device | Protocol | Notes |
|---|---|---|
| SONOFF TRVZB | Zigbee (Z2M) | Fully tested — external temperature, valve control, motor-protection |
| Eve Thermo (SEA80x) | HomeKit | Fully tested — observation mode, read-only valve sensor |
Using a different TRV? Open a GitHub Discussion with your device model and protocol — real-world feedback is the fastest path to a dedicated profile.
These devices have a named profile with device-specific handling applied automatically.
| Device | Protocol | Profile-specific behavior |
|---|---|---|
| SONOFF TRVZB | Zigbee (Z2M) | valve_opening_degree treated as max-opening limit (not written). Room temperature pushed to external_temperature_input for improved TRV-internal accuracy. Motor-protection on valve close. HVAC watchdog active. |
| Eurotronic Spirit | Zigbee (Z2M / ZHA) | HVAC mode written to heat before each setpoint — required for the TRV to accept external setpoints reliably. |
| Eurotronic SPZB0001 | Zigbee (Z2M / ZHA) | Same HVAC-first setpoint workflow as Eurotronic Spirit. |
| Avatto ME167 | Zigbee (Z2M) | Calibration offset sign is inverted to match this device's firmware convention. |
| Eve Thermo (HomeKit / SEA80x) | HomeKit | Valve position exposed as read-only sensor — ThermoSmart reads it for learning but does not write to it. External temperature, temperature source select, and calibration writes are disabled. |
| Beca BHT-002 | Zigbee (Z2M) | Calibration plausibility limit tightened to ±3 °C to account for known firmware offset behaviour on some revisions. |
These devices have a named profile. Autodetection of valve, calibration, and quirk entities runs as normal. No device-specific overrides apply beyond what the hardware exposes. Dedicated profiles allow future device-specific optimizations and quirks handling while remaining compatible with generic climate devices.
| Device | Protocol |
|---|---|
| Tuya TS0601 | Zigbee (Z2M) |
| Moes TV02 | Zigbee (Z2M) |
| Aqara TRV (SRTS-A01) | Zigbee (Z2M / ZHA) |
| Danfoss Ally | Zigbee (Z2M / ZHA) |
| Bosch BTH-RA | Zigbee (Z2M / ZHA) |
| Innr COZB001 | Zigbee (Z2M) |
ThermoSmart can observe these devices and record learning data, but active setpoint control is not recommended. Cloud-based devices periodically override setpoints from external sources — ThermoSmart would learn the cloud's behaviour rather than your building's.
| Device | Reason |
|---|---|
| tado° | Relies on the tado° cloud API. External setpoints are routinely overridden by the cloud schedule. |
| Daikin Climate | Heat pump / multi-split system. ThermoSmart's TPI control targets single-zone radiator heating and is not designed for this device class. |
| Netatmo Smart Radiator Valve | Cloud connectivity required for primary control. Local entity availability varies by setup. |
Any climate entity supporting set_temperature that does not match a named profile receives the generic fallback profile. Setpoint boost and all auto-detected features (valve, calibration, quirk entities) apply as normal.
| Profile | Applies to |
|---|---|
| Generic TRV | All unrecognised climate entities |
| Generic Zigbee TRV | Prepared — platform detection planned |
| Generic HomeKit TRV | Prepared — platform detection planned |
| Protocol | Obs. Mode | Active Control | Direct Valve | Auto-Calibration |
|---|---|---|---|---|
| Zigbee2MQTT | ✅ | ✅ | ✅ auto-detected¹ | ✅ auto-detected¹ |
| ZHA | ✅ | ✅ setpoint boost | ||
| Z-Wave JS | ✅ | ✅ setpoint boost | ❌ | |
| Matter | ✅ | ✅ setpoint boost | ❌ | ❌ |
| Homematic IP (local) | ✅ | ✅ setpoint boost | level pattern, untested |
temperature_offset |
| Fritz!DECT / Bosch | ✅ | ✅ setpoint boost | ❌ | ❌ |
| Tado / Netatmo | ❌ | ❌ |
¹ Auto-detection finds a matching entity and writes values to it — it does not guarantee physical function on every device.
Direct valve control auto-detects writable number entities matching: pi_heating_demand, valve_position, heating_demand, or level. Note: valve_opening_degree (used on some devices as a max-opening limit, not a live position) is intentionally excluded and not written by ThermoSmart.
Setpoint boost converts TPI duty-cycle to setpoint = target + duty% × 8 °C via climate.set_temperature. Works on all devices; less precise than direct valve control.
| Option | Behaviour |
|---|---|
automatic |
Activates when the 72 h rolling outdoor average exceeds 18 °C; deactivates below 15 °C (3 °C hysteresis prevents rapid toggling) |
on |
Forces summer mode — heating disabled, frost protection (12 °C) active |
off |
Forces winter mode — normal heating regardless of outdoor temperature |
In summer mode all normal heating is suspended. TRVs are held at 12 °C to keep valves exercised.
Sets all zones to the configured vacation temperature (default 12 °C). Takes priority over schedule and presence detection. Independent of summer mode.
| Status | Meaning |
|---|---|
observation_mode |
Active Control OFF, learning ON |
heating |
Actively heating toward target |
idle |
Target reached, maintaining |
preheating |
Heating before scheduled comfort time |
window_open |
Window detected (sensor or slope), heating paused |
away |
All persons away |
vacation |
Vacation mode active |
summer |
Summer mode — frost protection only |
heating_failure |
Heating commanded but temperature falling 35+ min |
disabled |
Active Control OFF, learning OFF |
How do I update ThermoSmart?
HACS → Integrations → ThermoSmart → Update → Restart Home Assistant. Learning data is preserved across updates.
What is Observation mode?
Active Control OFF: ThermoSmart reads what your existing controller does and learns from it — nothing in your setup changes. Switch to Active Control when you're ready.
What do the Learning and Active Control switches actually do together?
ThermoSmart combines two independent switches:
- Learning enabled + Active Control off — ThermoSmart observes and learns, but does not control your devices (no service calls).
- Learning disabled + Active Control on — ThermoSmart controls deterministically using TPI, without any adaptive learning adjustments.
- Learning enabled + Active Control on — ThermoSmart may apply bounded adaptive adjustments on top of TPI control, once confidence and safety gates allow it.
- Both off — ThermoSmart remains inactive for that zone.
How long until the learning algorithm is effective?
Learning builds from active heating observations and works in both Observation mode and Active Control. Stage 1 (<5 obs): physical fallback only. Stage 2 (5–50): first patterns emerge. Stage 3 (50+): learning dominates. How quickly you reach each stage depends on how often your heating runs — results improve steadily as observations accumulate.
A sensor goes offline — what happens?
ThermoSmart averages the remaining sensors. Temperature decisions pause only if all sensors in a zone are unavailable simultaneously.
Where is the learning data stored?
Learning data is stored locally under Home Assistant's /config/.storage/ directory. For debugging or support, use the Create support export button instead of sharing raw storage files — the export is designed to include useful diagnostics while avoiding raw Home Assistant storage data. Do not share or manually edit files under /config/.storage unless specifically asked by a maintainer.
Which TRVs use direct valve control?
ThermoSmart auto-detects a direct-valve entity on each TRV device and writes the TPI duty-cycle (0–100%) to it when one is found. Recognised patterns:
| Pattern | Example devices |
|---|---|
valve_position |
Eurotronic Spirit (SPZB0001) |
pi_heating_demand |
Tuya TS0601_3/5, some Danfoss |
heating_demand |
Alternative name for the above |
level |
Homematic IP (hahomematic, 0.0–1.0 scaled) |
TRVs without a recognised pattern — including SONOFF TRVZB — are controlled via setpoint boost (climate.set_temperature). On SONOFF TRVZB, ThermoSmart additionally writes the room temperature to external_temperature_input, which feeds the TRV's own internal controller for better accuracy. valve_opening_degree is intentionally not written: on this device it configures a maximum-opening limit, not the live valve position.
SONOFF TRVZB via Zigbee2MQTT — heat vs auto mode and internal weekly schedule
Zigbee2MQTT exposes two HVAC modes on the SONOFF TRVZB:
heat— manual setpoint mode: the TRV follows the setpoint written by ThermoSmart (or any other controller)auto— the TRV follows its own internal weekly schedule and ignores externally written setpoints
When ThermoSmart is in Active Control, it calls climate.set_temperature on every cycle. This automatically switches the TRV to heat mode, so the internal weekly schedule is bypassed — the TRV follows ThermoSmart's setpoints instead.
You do not need to delete the internal schedule. It has no effect while the TRV is in heat mode. If Active Control is ever disabled and the TRV is switched back to auto manually, the internal schedule becomes active again.
In Observation mode ThermoSmart does not write setpoints, so the TRV stays in whatever mode it was last set to (typically auto after initial pairing). Observations and learning are recorded correctly regardless of the TRV's active mode.
ThermoSmart can export an anonymized snapshot of its learning data as a JSON file — for voluntary debugging or to contribute data to future Learning Engine improvements.
How to export:
- Press the Create Research Export button in the ThermoSmart System device card, or
- Call the service
thermosmart.export_learning_datafrom Developer Tools → Services.
The file is saved to /config/www/ and can be opened via /local/<filename> appended to your Home Assistant URL.
Note for automations: the completion notification's
notification_iddiffers by trigger — the Create Research Export button usesthermosmart_research_export, while thethermosmart.export_learning_dataservice call usesthermosmart_export. If you have an automation matching on the notification ID, check which trigger you use.
Privacy — what the export contains:
- ThermoSmart version, export timestamp, zone count
- Per-zone: TRV count, sensor counts, feature flags (booleans only)
- Per-zone: all numeric learning data (observations, rates, confidence, boost factor, …)
- Observation timestamps (required for longitudinal learning analysis)
Privacy — what the export does NOT contain:
- Passwords or authentication tokens of any kind
- Entity IDs, device names, or integration names
- Person names or user identifiers
- Street addresses or geographic coordinates
The export is strictly local. No data is sent anywhere automatically. You can review the file before deciding whether to share it.
24 UI languages supported: BG · CA · CS · DA · DE · EL · EN · ES · FI · FR · HU · IT · NB · NL · PL · PT · RO · RU · SK · SL · SV · TR · UK · ZH-Hans
Additional languages welcome via Pull Request (custom_components/thermosmart/translations/).
Bugs → GitHub Issues: HA version, ThermoSmart version, what happened, log lines (Settings → System → Logs → thermosmart)
Features → Issues with label enhancement
Especially welcome: Testing with more TRV models · Additional translations · Device quirk patterns
New device? If your TRV is not listed above or behaves unexpectedly, open a GitHub Discussion with your device model, protocol, and HA log lines — this is the fastest path to getting a dedicated profile added.
MIT — see LICENSE

