initial commit v0.2.1

This commit is contained in:
buzera committed 2026-10-26 17:34:32 +02:00
commit 2b9a10979b
19 files changed
+1665

No files matched your search

+146
View File
@@ -0,0 +1,146 @@
# AGENTS.md — Heating MPC
## Project mission
Build a **local, configurable, testable Home Assistant custom integration** for model-predictive heating control on **Home Assistant OS (HAOS), Raspberry Pi 5**. The home has multiple indoor temperature sensors, configurable comfort weights, outdoor weather sensors, **one physical ON/OFF gas-boiler relay**, and an existing Home Assistant `generic_thermostat`.
The project starts as a **read-only observer**. It learns thermal behavior and predicts possible heating decisions. Any future control of real heating equipment is a separate, explicitly authorized milestone.
**Working agreement:** Architecture, requirements and results are discussed in ChatGPT; source-code implementation, tests and commits happen in Codex in this repository. Treat the files and current code in this repository as the implementation source of truth, not verbal descriptions of earlier ZIP releases.
## Starting point / status
- Baseline: **v0.2.1**, experimental custom integration (`custom_components/heating_mpc`).
- Native HA config and options flows; no Docker service, MQTT broker or direct InfluxDB connection needed.
- Reads room sensors, an existing `climate` entity, the physical relay state and prioritized weather sources.
- Uses 5-minute observations, per-room linear RC-like thermal models with a heating-lag approximation, persistent learned parameters, and an enumerative binary MPC optimizer.
- Exposes status/diagnostics, a weighted temperature, selected outdoor temperature, per-room 60-minute prediction entities and a **hypothetical** proposed-heat binary sensor.
- Weather variables other than outdoor temperature are currently for **diagnostics/comparison only**.
- No backfill from Recorder; no hourly weather forecasts; no validated 60-minute out-of-sample accuracy; no actuator control.
- Offline unit tests exist in `tests/`. Real HAOS integration and restart/unload behavior still need thorough testing.
**Do not claim an item is implemented or validated solely because it is listed in ROADMAP.md.** Check the code and tests first.
## Non-negotiable safety rules
1. **Observation-only by default.** The existing `generic_thermostat` is the sole controller of the physical boiler switch until the user explicitly approves a future control milestone. Never quietly add `switch.turn_on`, `switch.turn_off`, `climate.set_temperature`, `climate.set_hvac_mode`, `climate.set_preset_mode`, relay automations, or equivalent writes.
2. **Never connect `binary_sensor.heating_mpc_proposed_heat` directly to the relay.** It is diagnostic output, not a certified control signal.
3. **One physical relay, one writer.** Any future live implementation must provide a proven handover/arbiter design; `generic_thermostat` and MPC must never compete over the same actuator.
4. **Manual `heat/off` is authoritative.** The user controls HVAC mode; do not automatically switch from `off` to `heat`, including after restart. Preserve user-selected Comfort/Away/Sleep targets (currently 22/19/21 °C) instead of resetting them.
5. **Fail safe.** On missing/stale/implausible sensor data, optimizer failure, restarts, incomplete initialization or loss of connectivity: never issue an unvalidated heat request. For future live control, define and test safe fallback/recovery before enabling it. Fallback must not create two simultaneous writers.
6. **Protect the boiler.** For future control, enforce minimum ON and OFF times, bounded setpoints, watchdog and recovery rules. Do not change gas/combustion settings, boiler flow temperature, firmware or wiring. The Immergas boiler is **non-condensing**, with conventional radiators; setting the boiler's flow temperature is outside this integration's scope.
7. **No experiments that heat the apartment without the user's opt-in.** Avoid automatically generating artificial ON cycles to accelerate model training.
8. Never introduce cloud dependencies, secrets in source control, or external network access for model inference. Default to local operation and HA entities.
## Hardware and Home Assistant context
- HA host: Raspberry Pi 5 with HAOS.
- Heating: non-condensing Immergas Eolo Star (exact variant to be verified), aluminum radiators, copper plumbing, two-room apartment; relay is binary ON/OFF.
- Existing thermostat platform: `generic_thermostat`; source temperature is a **weighted indoor average**. Existing Comfort/Away/Sleep targets: 22/19/21 °C; user manually selects `heat`/`off`.
- Known example switch: `switch.central_heating_switch`. Known weighted average sensor: `sensor.average_temperature`. The exact `climate` entity ID must be verified; **do not assume** `climate.thermostat`.
- Previously configured individual sensor examples (informational, not defaults):
- `sensor.living_universal_remote_temperature`
- `sensor.hue_motion_sensor_1_temperature`
- `sensor.air_purifier_temperature`
- `sensor.bedroom_universal_remote_temperature`
- `sensor.bathroom_temperature`
- Outdoor weather comes from existing HA sensors originally populated from OpenWeatherMap/InfluxDB. The user wants to swap and compare providers **in the UI**, not in code.
- The weather series includes temperature, wind, clouds, humidity, feels-like, pressure, visibility, rain and snow. Sensor units, freshness and meanings must be checked before using them to train a model.
All example entity IDs are **examples only**. No user-specific ID, room count, provider, comfort target, weights or outdoor data source may be hard-coded.
## Configurability contract
- Use **Config Flow + Options Flow** for entity selection and tuning. Avoid requiring YAML edits for regular operations.
- Allow selecting, removing and replacing indoor sensors (up to the current supported limit), plus independent positive comfort weights.
- Every weather variable should accept an ordered list of HA sensor entity IDs. Select the first healthy, unit-compatible, plausible **and eventually fresh** source; expose the chosen source and alternatives in diagnostics.
- Temperature must be available; other meteorological variables must be optional and cannot break the thermal controller if absent.
- Support reconfiguration without corrupting learned models. Preserve compatible room histories; invalidate or migrate incompatible state explicitly and document why. When changing weather providers, beware of systematic sensor offsets.
- A `climate` reference is read-only during shadow mode. Its requested target/preset/HVAC mode must remain owned by the existing thermostat/user.
- Use translation keys for UI strings; maintain at least `en` and `ro` when changing exposed UI flows.
- Entity unique IDs must remain stable across safe upgrades; handle removed/replaced sensors without leaving orphan entities.
## Architecture boundaries
Keep separation between:
1. **HA integration layer:** config entries, sensors, entity registry, event/update lifecycle, storage, read-only state acquisition.
2. **Data preparation:** quality/staleness checks, unit normalization, sensor alignment and handling missing data.
3. **Thermal model:** pure Python, independently testable learning/prediction algorithms for each room (eventually interactions between rooms).
4. **Optimization:** pure Python, independently testable finite-horizon ON/OFF plan evaluation with actuator constraints.
5. **Evaluation/diagnostics:** timestamps, input provenance, forecast trajectories, prediction errors and comparison to actual observed events.
6. **Optional future actuator layer:** disabled/absent until separately designed, tested and explicitly approved by the user.
Favor the standard library and small dependencies. Heavy compute must not block Home Assistant's asyncio event loop. Use supported HA APIs and offload expensive optimization if needed. Avoid unnecessary polling, disk writes, excessive log volume and unbounded entity attributes.
## Modeling rules
- Current model form: `dT_5m = a * (T_out - T_room) + b * effective_heat + c`, with a smoothed heater-command proxy. Coefficients are estimates, not measured boiler efficiency.
- A relay `on` is **not proof that the gas burner is firing**. Never treat ON duration as metered gas usage or claim fuel savings without gas-consumption evidence.
- Track sample count and ON/OFF distribution. An in-sample **5-minute MAE is not** validated 60-minute forecast accuracy.
- Implement holdout / walk-forward testing for horizons of 15, 30, 60 and 120 minutes; compare to naive persistence and the existing thermostat.
- Record the plan and the input snapshot that produced a prediction, then compare it to actual temperatures only under appropriate command/exogenous-input assumptions. Distinguish **counterfactual MPC forecasts** from forecasts of the **actual** `generic_thermostat` behavior.
- Validate model identifiability, parameter stability, outlier rejection, missing observations, power outages, heater transitions within a sampling window, and multiple sensors in the same physical room.
- Weather covariates beyond temperature should be added only if they improve held-out performance; avoid treating `feels_like` as physical outdoor air temperature. Forecast values and observed values must be distinguished.
- One switch heats all rooms: optimization can trade off room comfort, but cannot independently heat a cold bathroom without influencing warmer rooms.
## Repository conventions
Expected structure (adapt only through deliberate refactoring):
```text
custom_components/heating_mpc/
__init__.py
manifest.json
config_flow.py
const.py
coordinator.py
physics.py
weather_sources.py
sensor.py
binary_sensor.py
strings.json
translations/{en,ro}.json
hacs.json
tests/
README.md
AGENTS.md
ROADMAP.md
```
- Keep pure model/optimizer logic importable and testable without Home Assistant installed.
- Keep config migration and persisted-model schema backward compatible where possible; version persisted data explicitly when evolving its format.
- Follow Home Assistant conventions for async config entry setup/unload/remove, entity lifecycle, options flows and translation validation.
- Avoid speculative API usage. Verify Home Assistant behavior with a runnable test or documented supported API before depending on it.
- Add tests with every behavior change; prioritize tests for lifecycle, reload, reconfiguration, persistence and fault handling.
- Make small focused commits and record changes in a changelog or release notes. Never advance version numbers without corresponding tests/documentation.
## Development workflow for Codex
1. **Inspect the repository first.** Read `README.md`, `ROADMAP.md`, implementation and tests. Determine the actual current version/behavior.
2. **Audit baseline v0.2.1 before major features:** confirm shadow-only semantics, config entry migration, sensor collection, update/reload, uninstall cleanup and persisted-state correctness. Identify and fix correctness/safety bugs first.
3. For each task, state the scope, compatibility and safety implications. Keep modifications narrow; do not combine cleanup with an unauthorized live-controller implementation.
4. Run at minimum:
```bash
python -m unittest discover -s tests -v
python -m compileall -q custom_components/heating_mpc
```
Add more integration tests, lint/type checks and HA validation as tooling is introduced. Report exactly what was and wasn't run.
5. Add/adjust tests for edge cases and migrations. Update README/ROADMAP and translations when the user-facing behavior changes.
6. Summarize touched files, tests, known limitations and how the user can safely try the change on HAOS. Do not claim HAOS/device testing unless performed.
7. **No autonomous deployment to the real boiler.** Installing code is not authorization to enable control mode.
## Release acceptance rules
A release is not ready simply because unit tests pass. Require:
- No regression in the existing Generic Thermostat or its presets/manual HVAC mode.
- No unexpected service calls to heater/thermostat while in shadow mode.
- Correct handling of unavailable, stale, nonnumeric and changing input sources.
- Config/options flow, restart, reload, entity-registry cleanup, model persistence and uninstall verified.
- Documented diagnostics and limitations; no unsupported fuel-savings promises.
- For any future live control: a separate safety review, test evidence, opt-in UX, exclusive relay ownership, watchdog/fallback and explicit user approval.
See `ROADMAP.md` for ordered milestones. Prioritize correctness, reproducibility and user control over adding features quickly.