Score forecasts against reality; expose forecast trajectories
There was no evidence of how accurate the thermal model is: the only number was an in-sample 5-minute error. At every poll, record each room's reading, the outdoor temperature, the radiator-lag estimate and the model parameters. 15, 30, 60 and 120 minutes later, replay the room from that poll with the parameters it had then (out of sample), the outdoor temperature held constant and the radiator lag that actually followed from the relay's real history, and compare with the reading now. A no-change forecast is scored alongside. Only spans with regular polls and a well-known lag are scored. 7 days of per-room statistics are saved with the model (optional "evaluation" payload key; about 18 KB at most). Four new sensors, Heating MPC Forecast Error 15/30/60/120 min, show the mean absolute error with bias, persistence error, skill and per-room detail. On the synthetic lagged plant the 60-minute error is 0.03 °C against 0.39 °C for persistence. Room forecast entities gain forecast_15min and plan_15min attributes and are labelled counterfactual. Volatile attributes are unrecorded. The model is now saved after scoring, so saved statistics are current. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
43915ba810
commit
3afb6688a5
9 files changed
+454
-16
No files matched your search
@@ -50,8 +50,13 @@ Entities (entity IDs may vary):
|
||||
- `sensor.heating_mpc_status` — learning/ready/paused status and diagnostics, including outside weather, active source, all valid alternative weather values, model coefficients, proposed 15-minute plan.
|
||||
- `sensor.heating_mpc_weighted_temperature` — own room-weighted average, informative only.
|
||||
- `sensor.mpc_outdoor_temperature` — selected external temp and alternatives.
|
||||
- Per-room predicted temperatures after 60 minutes.
|
||||
- Per-room predicted temperatures after 60 minutes. Attributes `forecast_15min` (the
|
||||
temperature every 15 minutes over the horizon) and `plan_15min` (the proposed
|
||||
ON/OFF plan). These assume the MPC's plan is executed; while Generic Thermostat
|
||||
controls the relay they are **counterfactual**.
|
||||
- `binary_sensor.heating_mpc_proposed_heat` — **hypothetical** heating demand (unavailable until ready).
|
||||
- **Heating MPC Forecast Error 15/30/60/120 min** — how far the thermal model's
|
||||
forecasts were from what actually happened (see *Forecast accuracy*).
|
||||
|
||||
## Known limitations / safety
|
||||
|
||||
@@ -126,6 +131,40 @@ After a day of running, set each limit comfortably above (about 1.5–2×) the l
|
||||
`max_age_seconds_24h` among the sensors it covers. The relay and thermostat have no
|
||||
age limit.
|
||||
|
||||
## Forecast accuracy
|
||||
|
||||
The four **Forecast Error** sensors measure the thermal model against reality,
|
||||
continuously and out of sample. At every poll the integration records each room's
|
||||
reading, the outdoor temperature, the radiator-lag estimate and the model's
|
||||
parameters. 15, 30, 60 and 120 minutes later it replays that room from the earlier
|
||||
reading using the parameters it had **then**, the outdoor temperature held at its
|
||||
starting value, and the radiator heat that actually followed from the relay's real
|
||||
ON/OFF history. The result is compared with the current reading.
|
||||
|
||||
This tests the thermal model, not the MPC plan, because the plan is never
|
||||
executed. Each sensor's state is the mean absolute error (°C) over the last 7 days,
|
||||
across all rooms. Attributes, all in °C except counts:
|
||||
|
||||
- `samples` — number of scored forecasts. Consecutive forecasts overlap, so they
|
||||
are not independent; treat small counts as indicative only.
|
||||
- `bias` — mean error: negative means the model predicts too cold.
|
||||
- `persistence_mae` — error of simply assuming no change; the baseline to beat.
|
||||
- `skill` — `1 - mae / persistence_mae`: 1 is perfect, 0 is no better than
|
||||
assuming no change, negative is worse. Empty while the temperature did not change.
|
||||
- `rooms` — the same numbers per room (not written to the Recorder).
|
||||
|
||||
Forecasts are scored only where the inputs were known: polls 4.5–5.5 minutes
|
||||
apart, a usable reading at the start and the end, and a well-known radiator-lag
|
||||
estimate throughout. A missing relay, outdoor temperature or all rooms restarts the
|
||||
replay window, so scores resume 15–120 minutes later. Statistics are kept with the
|
||||
model and survive restarts; deleting the model resets them.
|
||||
|
||||
What it does not cover: outdoor temperature changes during the horizon (held
|
||||
constant, as in the MPC), and periods when the model was still learning (included,
|
||||
so early numbers are pessimistic). The roadmap's working target is about
|
||||
0.3–0.4 °C at 60 minutes with clearly positive skill, before any control is
|
||||
considered.
|
||||
|
||||
## Release notes
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md) for changes and upgrade notes per version, and
|
||||
|
||||
Reference in new issue
Block a user