Confirmed: the check run after the optimizer compared only zone sensors,
outdoor temperature, thermostat and relay. A window opening, a UPS load
change or a wind change during the calculation went unnoticed; nothing
prevented an older update that finished late from overwriting a newer
result; and an update in flight during unload still saved.
- Every input a prediction uses is captured as a normalized snapshot
(zone and outdoor temperatures, wind speed/direction/gust, heat-source
power, window states, relay state and switch time, thermostat mode and
target) and compared after the calculation with tolerances (0.25 °C,
50 W, 1 m/s, 2 m/s gusts, 20° direction around the circle; exact for
relay, thermostat and windows). A meaningful change discards the plan
and lists the inputs in changed_inputs; noise does not. No immediate
recalculation: an off-schedule poll would break the 5-minute learning
interval; the next regular poll computes a fresh plan.
- Updates are numbered; one overtaken by a newer update, or running when
the entry unloads, keeps the newer data and skips saving and
optimizing. Configuration changes reload the entry, so they are covered.
- A per-entry storage lock makes a reloaded coordinator restore only
after the previous one's save finished, and integration removal waits
for it too, so a late save cannot recreate a deleted model file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
During a first test the Status entity only said "learning" for the
first half hour (the radiator-lag wait after a restart), and the
attributes explaining why were hard to find. Add two sensors:
- Learning Progress (%): for the least trained room, the mean of its
three readiness requirements (200 samples, 30 ON, 30 OFF), each capped
at 100 %; 100 % means ready. Attributes show the counts.
- Last Sample: an enum of the last poll's learning outcome, with English
and Romanian state names (e.g. "Waiting for radiators to settle"). Its
history shows when learning happens.
Polls blocked by missing shared inputs now report waiting_for_inputs.
Readiness thresholds move to const.py.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A single stale, unavailable, missing or invalid room sensor paused
learning and forecasts for every room. That is not acceptable once the
MPC may control heating.
Now such a room is left out: the weighted temperature, learning and the
optimizer use the remaining rooms with their weights re-normalized, and
a room learns only across poll pairs where it was usable at both ends.
Readiness considers only the rooms used. Everything pauses only when no
room is usable or a shared input (relay, thermostat, outdoor
temperature) is missing.
A new setup/Configure checkbox, room_stale_use_last_value (default off),
keeps using a stale room sensor's last value instead, for sensors that
report only on change. It never applies to unavailable or invalid
sensors, or to a sensor silent for more than 24 hours.
Status adds excluded_rooms, weight_coverage and a per-room "used" flag.
English and Romanian labels and help text added.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Choosing room and weather freshness limits required knowing how long
each sensor normally goes without reporting, which HA does not show.
Add max_age_seconds_24h to every source in input_quality: the largest
report age seen at polls over the last 24 hours (hourly buckets, reset
on reload, underestimates by up to one poll interval).
input_quality and weather_comparison change every poll, so the Recorder
stored a new attribute row every five minutes. Mark them unrecorded;
they remain visible on the Status entity. Model coefficients and other
attributes are still recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>