The Appendix M1 §3a PV-eligible-demand cascade `_pv_eligible_demand_ monthly_kwh` assembled its `cooking_monthly_kwh` argument from `internal_gains_result.cooking_monthly_w × 24 × n_m / 1000`. That field is the SAP 10.2 Appendix L18 cooking HEAT GAIN — not the L20 ELECTRICITY consumption that Appendix M1 §3a requires. Per SAP 10.2 Appendix L (p.91): L18: G_C = 35 + 7 × N (heat gain in watts, used by §5) L20: E_cook = 138 + 28 × N (electricity in kWh/yr, used by M1) L21: E_cook,m = E_cook × n_m / 365 (monthly electricity) The two formulas differ by ~2.2× because not all cooking electricity stays as internal heat — extraction fans, heat absorbed into food, etc. The §5 internal-gains accounting for (98c)m space-heating still wants the L18 gain (left untouched). Only the M1 §3a path needs the L20 electricity figure. Magnitude on cert 0380 (cohort-2 ASHP+5kWh battery, TFA 60.43): - Pre-fix cascade cooking annual (L18 watt-hours): 428.6 kWh - Spec L20 cooking annual: 193.7 kWh (2.21× over-count) - Pre-fix cascade D_PV summer Jul: 311.6 kWh - Worksheet-implied D_PV Jul (β-inverse on (233a/b)m): ~292.6 kWh - Pre-fix cascade (233a) annual: 1925.55 vs worksheet 1899.73 (+25.82) The cohort-2 ASHP STANDARD-tariff cluster (20 certs, all using PV + battery, all winter-peaked HP load + summer PV surplus): - Pre-S0380.71: mean PE residual -3.10 kWh/m² - Post-S0380.71 (main heat monthly Table 12d/12e): -0.66 - Post-S0380.72 (HW monthly Table 12d/12e): -0.36 - Post-S0380.73 (Appendix L20 cooking electricity): -0.06 Cumulative S0380.71-.73: 48× compression of the cluster. Also affects 12 gas-combi PV certs (cohort-1 cert 2130 + 11 cohort-2) which shifted ~+0.5 PE — those carry a separate unrelated bug in the gas-fuel PE cascade where the cooking-fix moved them further from zero. Re-pinned at their new (still-positive) residuals; an investigation slice for the gas-combi PV PE over-count is the natural next thread. Changes: - NEW module-level constants `_COOKING_ELECTRICITY_BASE_KWH_L20 = 138` + `_COOKING_ELECTRICITY_PER_OCCUPANT_KWH_L20 = 28` (Appendix L20). - `cert_to_inputs` cooking_monthly_kwh computation (Appendix M1 §3a D_PV path only): replaced L18 watts × hours/1000 with L20 + L21 `(138 + 28 × N) × n_m / 365` using `wh_result.occupancy` for N. - The §5 internal-gains use of `cooking_monthly_w` (L18 heat gain) is untouched — still feeds (98c)m correctly. Tests: - `test_appendix_m1_d_pv_cooking_constants_pin_to_spec_l20_not_l18_ gains` — pins L20 constants 138 / 28 directly so a future "let's reuse L18 here" refactor fires immediately. - `test_golden_fixtures.py`: 20 ASHP cluster + 12 gas-combi PV cert pins re-pinned at the post-S0380.73 residuals. Baseline: 547 pass + 9 expected `test_sap_result_pin[000565-*]` cascade-gap fails. Pyright net-zero on every touched file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .devcontainer | ||
| .github/workflows | ||
| .idea | ||
| .vscode | ||
| applications | ||
| asset_list | ||
| backend | ||
| backlog | ||
| datatypes | ||
| deployment/terraform | ||
| docs/adr | ||
| domain | ||
| epr_data_exports | ||
| etl | ||
| infrastructure | ||
| model_data/requirements | ||
| orchestration | ||
| recommendations | ||
| repositories | ||
| scripts | ||
| sfr/principal_pitch | ||
| survey_report | ||
| tests | ||
| utilities | ||
| utils | ||
| .coveragerc | ||
| .dockerignore | ||
| .gitignore | ||
| __init__.py | ||
| ara_backend_design.md | ||
| BaseUtility.py | ||
| CLAUDE.md | ||
| conftest.py | ||
| CONTEXT.md | ||
| devcontainer.sh | ||
| Dockerfile.test | ||
| Dockerfile.test.dockerignore | ||
| Makefile | ||
| MEMORY.md | ||
| package-lock.json | ||
| package.json | ||
| pyproject.toml | ||
| pyrightconfig.json | ||
| pytest.ini | ||
| README.md | ||
| run_lambda_local.sh | ||
| serverless.yml | ||
| test.requirements.txt | ||
| tox.ini | ||
| UBIQUITOUS_LANGUAGE.md | ||
Model Repository
This repository contains the code pertaining to the development of the data science and machine learning products being utilised by Hestia.
The different folders in this repository relate to services that can be used independently, or can be imported and used as part of a larger application
Getting Started
Prerequisites
Dev Container Setup
This repo uses a Docker Compose-based dev container. The model-backend service joins a shared-dev Docker network so it can communicate with other local services (e.g. a frontend container) running on your machine.
VS Code users: The initializeCommand in devcontainer.json creates the shared-dev network automatically before the container starts. No manual step required — just open the repo and select Reopen in Container.
Non-VS Code / CI workflows: Run the following once before starting the container:
make dev-setup
This is idempotent and safe to re-run if the network already exists.
Folders
backend/
This folder contains the code for the fastapi backend service, which provides an interface to much of the functionality in this repository, for the frontend
model_data/
This folder contains related to the reading and preparation of assessment model data, including pulling out epc attributes
Testing
All tests can be run, against the configuration in pytest.ini running
pytest
This will run the complete panel of tests and report on coverage in the locations specified by the pytest.ini file.
To run tests in a specific service, e.g. inside of model_data, simply run
pytest --cov-config=model_data/.coveragerc --cov=model_data
This will produce the test results and coverage reports