Language: Français | English
Adaptive TPI plugin for Versatile Thermostat, built on top of vtherm_api.
vtherm_adaptive_tpi provides an external adaptive_tpi proportional algorithm for Versatile Thermostat.
Its goal is to learn, during normal thermostat operation:
- deadtime (
nd) - thermal losses (
b) - heating authority (
a)
and to use these learned values to adjust the thermostat gains over time.
The plugin stays in the TPI family:
- it computes a requested
on_percentfor the next cycle - Versatile Thermostat still commits the actual current-cycle power through its normal cycle scheduler
- learning happens only from completed real cycles
TPI is a regulation algorithm built around a proportional loop
through gain_indoor plus a feed-forward term through gain_outdoor to
compensate thermal losses. There is no integral correction term used to cancel
steady-state errors, so the I in TPI can be misleading.
If you need a more advanced proportional-integral controller with feed-forward, see vtherm-smartpi.
The integration includes:
- Home Assistant integration scaffolding
- registration through
vtherm_api - runtime connection to Versatile Thermostat cycle callbacks
- coarse deadtime estimation
- OFF-window learning for
b - ON-window learning for
a - conservative gain projection
- persistent runtime state
- diagnostics exposed in the climate
specific_states
At startup, the plugin does not know the plant yet.
The normal progression is:
- if ON and OFF deadtimes are not both identified yet, startup bootstrap may force clean OFF->ON->OFF attempts
- ON and OFF deadtimes start to emerge
bstarts learning from OFF windowsastarts only later, once deadtime is credible andbis stable
Typical early observations are:
control_rate_per_hourstill unsetcontrol_rate_converged = falsedrift_rate_converged = false- gains still close to defaults
startup_sequence_active = trueduring the initial forced sequence
The runtime loop is:
- the controller computes the next requested
on_percent - the VT scheduler commits a real cycle and its applied power
- the plugin records the cycle context
- at cycle end, the plugin validates the cycle for learning
- the deadtime model is updated
- short learning windows are reconstructed from cycle history
bmay learn from OFF windowsamay learn from ON windows, once deadtime andbare readygain_indoorandgain_outdoorare projected conservatively
When ON and OFF deadtimes are not both identified yet, startup may temporarily override the nominal command.
For meaningful bootstrap observations, the radiator should be cold before the sequence starts.
- if already above the low threshold, stay OFF until
target - 0.5°C - if already below the low threshold, start the heating step directly
- from
target - 0.5°C, heat at100%untiltarget + 0.3°C - then command
0%until the room returns to the setpoint - if both ON and OFF deadtimes are identified before the setpoint is reached, keep the final OFF return-to-target step active
- if either ON or OFF deadtime is missing at the setpoint, retry the complete bootstrap cycle
- once both deadtimes are identified and the setpoint is reached, return to normal regulation
- each bootstrap threshold crossing forces an immediate cycle restart so the scheduler does not wait for the previous cycle boundary
blearning remains governed by the normal OFF-window rules; the final return-to-target step only forces the command to0%
The plugin exposes learning diagnostics in the climate specific_states.
The most useful fields to inspect first are:
adaptive_phaseactuator_modecurrent_cycle_percentnext_cycle_percentvalve_curve_convergedvalve_curve_observations_acceptedvalve_curve_last_reasonstartup_sequence_activestartup_sequence_stagestartup_sequence_attemptstartup_sequence_completion_reasondeadtime_cyclesdeadtime_confidencedeadtime_on_cyclesdeadtime_on_confidencedeadtime_on_lockeddeadtime_off_cyclesdeadtime_off_confidencedeadtime_off_lockeddrift_rate_per_hourdrift_rate_confidencedrift_samplessample_window_sizecontrol_rate_per_hourcontrol_rate_confidencecontrol_rate_convergedcontrol_sampleslast_learning_resultlast_learning_familylast_runtime_blocker
Healthy learning often looks like this:
deadtime_cyclesstarts moving before it is considered reliabledrift_rate_per_hourappears beforecontrol_rate_per_hourdrift_samples / sample_window_sizefills progressively until the rolling window is fulllast_runtime_blockeroften stays related to deadtime or cooling convergence for a whilegain_indoorandgain_outdoorstay near defaults until confidence is good enough
If you want to go deeper:
- Diagnostics User-facing runtime diagnostics and how to interpret them
- Architecture Internal architecture and learning flow
- custom_components/vtherm_adaptive_tpi Home Assistant integration and adaptive algorithm code
- docs Project documentation
- tests Behavioral tests for the integration
- plans Design notes, mathematical specs, implementation plans, and review reports
This plugin depends on:
versatile_thermostatvtherm_api
Development should be done with compatible versions of both sides.