Thermozona
Multi room floor heating
Install / Use
/learn @thermozona/ThermozonaREADME
Thermozona 💧🔥
<p align="center"> <img src="https://raw.githubusercontent.com/thermozona/thermozona/main/assets/logo@2x.png" alt="Thermozona logo" height="256" /> </p> <p align="center"> <a href="https://my.home-assistant.io/redirect/hacs_repository/?owner=thermozona&repository=thermozona&category=integration"> <img src="https://my.home-assistant.io/badges/hacs_repository.svg" alt="Open your Home Assistant instance and add Thermozona to HACS" /> </a> </p>Welcome to Thermozona, the Home Assistant integration that keeps your floors smart, cozy, and energy-efficient. It steers both heating and cooling loops, so the same zoning logic works in summer and winter. With weather-aware control and a smooth HA experience, you get year-round comfort tailored to every room. 🏡✨
Learn more at thermozona.com.
I built Thermozona while upgrading my own home: every underfloor heating manifold now uses Zigbee relays to drive the actuators, so each circuit can be switched independently as a zone. This project wraps that setup into a reusable integration—whether you run Zigbee, KNX, or another transport, Thermozona coordinates the relays, sensors, and heat pump so your floors stay perfectly balanced.
On the heat source side I connected an Ecoforest EcoGeo B2 over Modbus, but Thermozona itself is heat-pump agnostic: it exposes the desired heating/cooling state and flow temperature so you can mirror them—via Modbus, KNX, MQTT, or anything else—into whichever unit you own.
<p align="center"> <img src="https://raw.githubusercontent.com/thermozona/thermozona/main/docs/images/underfloorheating.jpg" alt="Thermozona-controlled underfloor heating manifolds" width="300" /> <img src="https://raw.githubusercontent.com/thermozona/thermozona/main/docs/images/image-relais.jpg" alt="Underfloor heating manifold with four actuators" width="300" /> </p>Dashboard example 🖥️
<p align="center"> <img src="https://raw.githubusercontent.com/thermozona/thermozona/main/docs/images/dashboard-thermozona.png" alt="Thermozona dashboard example" width="600" /> </p>The dashboard shows one thermostat per zone you define in configuration.yaml. Each zone maps to a separate underfloor circuit (or group of circuits), giving you granular control from Home Assistant while Thermozona keeps the heat pump in sync.
Highlights ⚡
- 🧠 Smart controller – Free tier includes manual and auto heat/cool switching.
- 🌡️ Weather compensation – Dynamically adjusts flow temperature based on the outdoor climate.
- 🧩 Flexible zones – Combine multiple circuits per room and bring your favorite temperature sensors.
- 🎛️ Full climate entities – Each zone shows up as a native climate entity inside Home Assistant.
- 🚀 Tiered model – Core stays free; advanced control features are unlocked with a local sponsorship key.
Sponsorship model: Free vs Sponsor License
Thermozona is community-funded. The core integration stays open and free, while sponsor-required components unlock advanced control features.
| Free (MIT, HACS) | Sponsor License (license key) | |---|---| | Bang-bang regeling per zone | PWM/PI control mode | | Handmatige + auto heat/cool mode | Runtime flow-curve tuning | | Simple flow mode + weather compensation | Pro flow supervisor (DI, slow/fast weighting, preheat) | | Warmtepomp status entities | Stagger optimization across zones | | | Actuator delay compensation |
pro.license_key must be a valid signed JWT and is validated locally (signature + claims + time window) at integration load time. There is no cloud dependency.
You will be able to get a Sponsor token at https://github.com/sponsors/thermozona. This is not online yet; in the meantime, request a token by email at info@thermozona.com.
Pro license generation
Thermozona Pro tokens are signed with Ed25519. The integration ships with a public key and only accepts tokens signed by the matching private key. For full generation instructions, environment variable details, and examples, run:
python scripts/issue_pro_license.py --help
Optional local verification:
python scripts/verify_pro_license.py "<jwt-token>"
Place the generated token in configuration.yaml:
thermozona:
pro:
license_key: "<jwt-token>"
# flow_mode: pro_supervisor # Optional override; auto-selects pro_supervisor when license is valid
⚠️ Never commit private keys to this repository, Home Assistant config backups, CI logs, or shell history.
Flow Temperature breakdown attributes
Thermozona exposes a Flow Temperature sensor entity that tracks the computed supply temperature. For observability, the sensor also includes state attributes that show which factors contributed to the final number.
These attributes are intended for dashboards and debugging; keys may evolve over time. They are not required for normal operation.
Common attributes:
effective_mode:heatorcoolflow_mode:simpleorpro_supervisoroutside_temp_c: outdoor temperature (when available)flow_curve_offset_c: effective flow-curve offset appliedflow_temp_unclamped_c: calculated value before clampingflow_temp_c: final value (rounded to 0.1C)clamp_min_c,clamp_max_c: applied bounds
Simple mode (examples):
target_ref_c: zone target used as reference (max for heating, min for cooling)base_offset_c: configured base offsetweather_slope: configured weather slopeweather_comp_c: outside-temperature compensation term
Pro supervisor (heating) adds demand-related terms such as:
demand_index,di_slow,di_fastkp,trim_p_c,integral_enabled,integral_cfast_boost_c,preheat_boost_c
For key rotation, you can provide multiple public keys to Home Assistant via THERMOZONA_LICENSE_PUBLIC_KEYS_JSON as a JSON object ({"kid":"-----BEGIN PUBLIC KEY-----..."}), while issuer tokens set the matching kid header.
Key rotation runbook
- Generate a new Ed25519 key pair and store the private key in your password manager (for example KeePass).
- Add the new public key to
THERMOZONA_LICENSE_PUBLIC_KEYS_JSONnext to the current key (keep both active during migration). - Start issuing new tokens with the new
--kidvalue. - Wait until old tokens naturally expire.
- Remove the old
kidfromTHERMOZONA_LICENSE_PUBLIC_KEYS_JSON.
Licensing transparency
- Core/open components are licensed under MIT (
LICENSE). - Sponsor-required components are excluded from MIT and licensed under
LICENSE-COMMERCIAL.md. - See
NOTICEand file headers for component-level licensing.
Installation 🚧
Thermozona does not require HACS. You can install it directly as a custom integration.
Manual install (no HACS required)
-
Clone this repository.
-
Copy the integration into your Home Assistant config directory:
./scripts/install_manual.sh /path/to/home-assistant-configRun this command on the machine where you cloned this repository.
Example:
./scripts/install_manual.sh /config -
Edit
configuration.yamland add athermozona:block with your zones. -
Restart Home Assistant so it loads the integration.
To update manually later, pull the latest changes and run the same command again.
Via HACS (optional)
If you already use HACS, Thermozona is listed in the default HACS store.
- Open HACS in Home Assistant and choose
Integrations. - Search for Thermozona and install it.
- Restart Home Assistant so it loads the component.
- Add a
thermozona:block to yourconfiguration.yaml(see Configuration). - Restart Home Assistant so it loads the integration with your YAML settings.
Configuration 🔧
ℹ️ Thermozona is configured exclusively through YAML. There is no Add Integration/Config Flow in the UI yet—Home Assistant will pick up your setup from
configuration.yamlafter a restart (or by reloading the integration).
Add this example configuration to configuration.yaml to get started:
thermozona:
outside_temp_sensor: sensor.outdoor
# flow_mode: simple # Optional override: simple or pro_supervisor
heating_base_offset: 3.0 # Optional: raise/lower the base heating offset
cooling_base_offset: 2.5 # Optional: make cooling supply warmer/colder
flow_curve_offset: 0.0 # Optional baseline for UI flow-curve tuning
weather_slope_heat: 0.25 # Optional weather slope for heating
weather_slope_cool: 0.20 # Optional weather slope for cooling
simple_flow: # Optional free-tier write behavior
write_deadband_c: 0.5
write_min_interval_minutes: 15
pro: # Optional Sponsor License config
license_key: eyJhbGciOi...<signed_pro_token>
flow: # Optional Pro supervisor tuning
kp: 1.0
use_integral: false
ti_minutes: 180
i_max: 1.5
error_norm_max: 2.0
duty_ema_minutes: 20
error_weight: 0.6
duty_weight: 0.4
slow_mix_weight: 0.8
fast_mix_weight: 0.2
fast_error_deadband_c: 0.4
fast_boost_gain: 1.2
fast_boost_cap_c: 1.2
slew_up_c_per_5m: 0.3
slew_down_c_per_5m: 0.2
write_deadband_c: 0.3
write_min_interval_minutes: 10
preheat_enabled: false
preheat_forecast_sensor: sensor.outdoor_forecast_2h
preheat_solar_sensor: sensor.solar_irradiance_forecast_2h
preheat_gain: 0.35
preheat_solar_gain_per_w_m2: 0.0
preheat_cap_c: 1.2
preheat_min_slow_di: 0.25
zones:
living_room:
circuits:
- switch.manifold_living_left
- switch.manifold_living_right
temp_sensor: sensor.living_room
hysteresis: 0.2
zone_response: slow # Optional: slow (default) or fast
zone_flow_weight: 1.0 # Optional: influence in Pro flow supervisor
zone_solar_weight: 1.6 # Optional: higher value = stronger solar softening impact for this z
