Add Reset learned model to Configure
Configure now opens a menu: Settings (the previous form) or Reset learned model. After an explicit confirmation the entry is unloaded, the learned parts of the stored model (zone, extended and ventilation coefficients, models kept for removed zones, Model Error and Forecast Error statistics, fingerprints) are removed under the storage lock, and the entry is set up again. Configuration, heat-source baselines and the window event log are kept, and model_changes records the reset. Unloading first means no update still running can write the old model back. English and Romanian strings; the gust hint now refers to Model Error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
28ff953ddd
commit
49565d610a
8 files changed
+174
-12
No files matched your search
@@ -65,6 +65,34 @@ def model_removed(hass: HomeAssistant, entry_id: str) -> bool:
|
||||
return entry_id in hass.data.get(f"{DOMAIN}_removed", ())
|
||||
|
||||
|
||||
# Stored keys holding what was learned. The rest is observation, not model: the
|
||||
# heat sources' baseline samples, the window history and the heater's identity.
|
||||
LEARNED_KEYS = ("learners", "retired_learners", "zone_models", "ventilation_models", "evaluation",
|
||||
"operational_evaluation", "fingerprint_version", "fingerprints", "on_samples", "off_samples")
|
||||
|
||||
|
||||
async def async_reset_learned_model(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
"""Forget everything learned for this entry; the configuration is not touched.
|
||||
|
||||
The entry is unloaded first, so no running update can save the old model
|
||||
afterwards, then set up again from the stripped data. Accuracy statistics go
|
||||
too: they describe the model being discarded.
|
||||
"""
|
||||
await hass.config_entries.async_unload(entry.entry_id)
|
||||
store = Store(hass, 1, f"{DOMAIN}.{entry.entry_id}")
|
||||
async with storage_lock(hass, entry.entry_id):
|
||||
stored = await store.async_load()
|
||||
if isinstance(stored, dict):
|
||||
kept = {key: value for key, value in stored.items() if key not in LEARNED_KEYS}
|
||||
changes = kept.get("model_changes") if isinstance(kept.get("model_changes"), list) else []
|
||||
kept["model_changes"] = [*changes, {
|
||||
"time": datetime.now(timezone.utc).isoformat(timespec="seconds"), "zone": "all",
|
||||
"recalibrated": ["all"], "reasons": ["learned model reset by the user"]}][-MAX_MODEL_CHANGES:]
|
||||
await store.async_save(kept)
|
||||
_LOGGER.info("Heating MPC: learned model reset by the user")
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
|
||||
|
||||
def entry_zone_list(entry: ConfigEntry, config: dict[str, Any]) -> list[Zone]:
|
||||
"""Zones from the entry's zone subentries; one zone per legacy room sensor otherwise."""
|
||||
subentries = getattr(entry, "subentries", None) or {}
|
||||
|
||||
Reference in new issue
Block a user