diff --git a/AUDIT.md b/AUDIT.md index 3f4e34e..e7ddc68 100644 --- a/AUDIT.md +++ b/AUDIT.md @@ -206,3 +206,22 @@ resets the relay's `last_changed`, so continuity cannot be verified anyway). **Verification.** `sh scripts/check.sh` passes in both test environments (pip check, 65 offline tests, 18 HA Core tests, compilation, package/translation/changelog checks, `git diff --check`). The offline tests also pass on Python 3.9.6. + + +## 0.2.3 — stale-room policy + +Decided by the user: pausing everything because one room sensor is unusable is +not acceptable for future control. An unusable room is now left out and the other +rooms' weights re-normalized; an opt-in checkbox keeps a stale sensor's last value +for sensors that report only on change. Two safeguards were added: the keep-last +option stops after 24 hours without a report, and Status exposes `excluded_rooms` +and `weight_coverage`, so a forecast based on a small share of the comfort weight +is visible. + +Open for the control design: a minimum `weight_coverage` below which the MPC must +not decide, and the outdoor-temperature outage policy (still pauses). Simulated +two-hour bedroom outage: the other room kept learning (7 → 25 samples, previously +frozen at 7) and the bedroom resumed one poll after reporting again. + +**Verification.** `sh scripts/check.sh` passes for HA 2025.12.0 and 2026.2.3 (69 +offline tests, 18 HA Core tests). The offline tests also pass on Python 3.9.6. diff --git a/CHANGELOG.md b/CHANGELOG.md index 94bb095..acbcee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,38 @@ Engineering findings and test evidence behind each change are in [AUDIT.md](AUDIT.md). -## 0.2.2 — 2026-10-26 +## 0.2.3 — 2026-10-26 + +A stale or failed room sensor no longer pauses the whole integration. Still +**observation-only**. Upgrading from 0.2.1 (0.2.2 was not deployed): follow the +0.2.2 upgrade notes below as well. + +### Changed + +- A room sensor that is stale, unavailable, missing or invalid is now **left out** + instead of pausing everything: the weighted temperature, learning and forecasts + continue with the other rooms, whose comfort weights are re-normalized. Learning + and forecasts pause only if no room is usable, or if the relay, thermostat or + outdoor temperature is missing. Readiness considers only the rooms used. + +### Added + +- Checkbox **Keep using the last value of a room sensor that stopped reporting** + (setup and Configure, default off), for sensors that report only when the value + changes. A stale sensor's last value is then still used, for up to 24 hours + without a report. Unavailable or invalid sensors are always left out. +- Status attributes `excluded_rooms` and `weight_coverage` (share of the total + comfort weight covered by the rooms used), and a per-room `used` flag in + `input_quality`. + +### Upgrade notes + +- The new checkbox appears in **Configure**; existing installations start with it + off. If a room is often listed in `excluded_rooms` while its temperature is + steady, either raise that room's report-age limit or turn the checkbox on. +- Rollback to 0.2.2 or 0.2.1 is safe; older versions ignore the new setting. + +## 0.2.2 — 2026-10-26 (not deployed) Reliability release (Milestone 0). Still **observation-only**: the integration never calls the relay, the thermostat or any other service. No new options or UI text; diff --git a/README.md b/README.md index f0c1ba7..fb14bc8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Heating MPC 0.2.2 — custom integration for Home Assistant OS +# Heating MPC 0.2.3 — custom integration for Home Assistant OS **Experimental, observation-only (shadow mode).** It **never** changes the Generic Thermostat, the physical relay, the boiler's setpoint, `heat/off`, or Comfort/Away/Sleep. No Docker add-on, MQTT or InfluxDB connection is needed. diff --git a/ROADMAP.md b/ROADMAP.md index 9c16ec5..f773976 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -10,7 +10,7 @@ Success means predictable comfort, understandable decisions, safe operation and ## Current baseline — v0.2.1 -> **Current release: 0.2.2** — Milestone 0 reliability work on top of this +> **Current release: 0.2.3** — Milestone 0 reliability work on top of this > baseline; see [CHANGELOG.md](CHANGELOG.md). The lists below describe 0.2.1. **Implemented (experimental):** @@ -165,12 +165,15 @@ Only after the Milestone 3 gate has been satisfied: Items 1–3 of the original backlog are done (see AUDIT.md and CHANGELOG.md 0.2.2). -1. **HAOS acceptance of 0.2.2 by the user:** install, restart, options reload, room - removal and re-adding, manual heat/off, a missing sensor, uninstall on a - disposable entry; confirm Generic Thermostat behavior is unchanged. -2. Finish Milestone 0: decide the stale-room policy (pause all rooms, as now, or - keep learning healthy rooms); committed rollback/migration fixtures; failed-fit - counters; lint/type checks; remote CI run. +1. **HAOS acceptance of 0.2.3 by the user:** install, restart, options reload, room + removal and re-adding, manual heat/off, a stale and an unavailable room sensor + (with the keep-last-value checkbox off and on), uninstall on a disposable + entry; confirm Generic Thermostat behavior is unchanged. +2. Finish Milestone 0: committed rollback/migration fixtures; failed-fit counters; + lint/type checks; remote CI run. Stale-room policy decided in 0.2.3 (leave the + room out, or optionally keep its last value for up to 24 hours). Before live + control, decide a minimum `weight_coverage` and the outdoor-temperature outage + policy, which still pauses. 3. Milestone 1: record forecasts with their input snapshot and evaluate them walk-forward at 15/30/60/120 minutes against persistence, replaying the actual relay sequence; then expose trajectories for a dashboard. diff --git a/custom_components/heating_mpc/manifest.json b/custom_components/heating_mpc/manifest.json index 84c20f8..592f529 100644 --- a/custom_components/heating_mpc/manifest.json +++ b/custom_components/heating_mpc/manifest.json @@ -9,5 +9,5 @@ "iot_class": "local_polling", "requirements": [], "single_config_entry": true, - "version": "0.2.2" + "version": "0.2.3" }