Per ADR-0010 §10a amendment (2026-05-21) + RdSAP 10 Specification §19.1 (PDF page 80-81): "The SAP rating for RdSAP 10 is to be calculated using Table 32 prices (not Table 12) for section 10a and 10b." The §10a `fuel_cost` orchestrator already used RdSAP 10 Table 32 prices for STANDARD-tariff certs (via `table_32_unit_price_p_per_kwh`). The legacy off-peak fallback scalar path on `CalculatorInputs.*_fuel_cost_ gbp_per_kwh` (which fires when `tariff is not STANDARD` → `_ZERO_FUEL_COST_FOR_OFF_PEAK`) was reading from `prices.unit_price_p_ per_kwh`, which was still wired to SAP 10.2 Table 12 prices via the `SAP_10_2_SPEC_PRICES` PriceTable constant. For cert 000565 (Dual meter → TEN_HOUR tariff + mains-gas DHW via WHC 914), this leaked Table 12's 3.64 p/kWh mains gas rate (vs Table 32's 3.48) into HW cost — a £6 over-count on 3755 HW kWh that landed continuous SAP 0.041 below the 28.5 integer rounding boundary, flipping sap_score 29 → 28. Verbatim Table 32 (PDF page 95) rows touched by this slice: Mains gas 3.48 p/kWh (Table 12 was 3.64) 7-hour low tariff 5.50 p/kWh (Table 12 was 9.40) Standard electricity 13.19 p/kWh (Table 12 was 16.49) Fix is one PriceTable constant — `RDSAP_10_TABLE_32_PRICES` wires `table_32_unit_price_p_per_kwh` + the 5.50 / 13.19 scalars per the amendment. `SAP_10_2_SPEC_PRICES` becomes a back-compat alias so existing `prices=SAP_10_2_SPEC_PRICES` test imports continue working but route through Table 32 at the call site. Cert 000565 movements at HEAD (this commit): - sap_score: 28 → **29 ✓ EXACT** (was Δ−1) - sap_score_continuous: 28.4680 → 28.5355 (Δ−0.041 → Δ+0.027) - total_fuel_cost_gbp: 4683.88 → 4677.87 (Δ+3.62 → Δ−2.39) - ecf: 5.3910 → 5.3841 (Δ+0.004 → Δ−0.003) - hot_water_kwh_per_yr: 3755.03 = 3755.03 ✓ EXACT (unchanged) Cumulative cert 000565 closure across S0380.77/78/79/80/81: - hot_water_kwh: +1399 → +260 → −238 → 0 → 0 ✓ - sap_score (integer): +1 → −1 → 0 → −1 → 0 ✓ EXACT - sap_score_continuous: +0.60 → −0.035 → +0.057 → −0.041 → +0.027 Cohort impact: STANDARD-tariff certs (the 6 U985 fixtures 000474/000477/000480/000487/000490/000516 and all cohort-2/golden gas combi certs) route through the §10a orchestrator that already used Table 32 — zero shift. Off-peak certs in the test suite are cert 000565 only at this point (Dual / TEN_HOUR); golden cohort unaffected. Three existing scalar-pin tests in `test_cert_to_inputs.py` re-pinned to Table 32 values: - `test_gas_heating_with_electric_immersion_charges_hw_at_electricity_ rate` (0.0364 → 0.0348 gas; 0.1649 → 0.1319 std elec) - `test_off_peak_meter_routes_electric_costs_to_low_rate` (0.094 → 0.055 7-hour low fallback) - `test_standard_meter_keeps_electric_costs_on_standard_rate` (0.1649 → 0.1319 std elec) New test pins the rule: `test_rdsap_10_table_32_prices_charge_mains_gas_hot_water_at_3p48_per_kwh` quotes the §19.1 spec and asserts cert 000565 HW £/kWh = 0.0348. Test baseline: 553 pass + 8 expected `test_sap_result_pin[000565-*]` fails (was 551 + 9; sap_score now closes EXACT). The remaining 8 fails on cert 000565 are the documented work-queue residuals — RR fold-in (space_heating, main_heating_fuel), Table 12d/12e dual-rate blend for lighting + CO2, MEV PCDB record (pumps_fans). Pyright net-zero on touched files (45 errors, matching baseline). 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