Model/tests/domain/sap10_calculator
Khalim Conn-Kowlessar 6a4539f26b fix(fuel): close case 47 — correct the second main heating system's fuel (off-peak pricing + Elmhurst Summary solid-fuel)
Two second-main fuel errors mis-cost a dual-main dwelling whose two main systems
burn different fuels (SAP 10.2 §10a worksheet (213) bills main 2 at its own fuel):

1. Off-peak/legacy scalar cost path (calculator.py + cert_to_inputs.py): main 2's
   kWh was priced at main 1's `space_heating_fuel_cost_gbp_per_kwh` scalar. Split
   main 1 vs main 2 and price main 2 at its OWN rate via the new
   `_main_2_space_heating_fuel_cost_gbp_per_kwh` (+ CalculatorInputs field).
   Scoped to a NON-electric second main (wood/oil/coal) — an electric second
   main keeps main 1's scalar (its off-peak Table 12a split is the deferred §10a
   slice; per-system splitting it regresses the off-peak electric cohort, certs
   13 Parkers Hill / 34 Dunley Road). 0 corpus impact (no corpus cert has a
   non-electric second main on an off-peak meter).

2. Elmhurst Summary mapper (mapper.py): when §14.1 omits the Fuel Type cell, a
   fuel-fired second main (room-heater SAP code) inherited main 1's fuel. Derive
   it from the SAP code's Table 4a category (solid 631-636 -> house coal, gas ->
   mains gas, liquid -> oil) before the main-1 inherit, mirroring
   `_elmhurst_secondary_fuel_from_sap_code` (same modal sub-fuel caveat). Boiler
   codes (<601) still inherit main 1 (case 6 oil rads+UFH).

simulated case 47 (electric room heaters + solid room heaters 633): our SAP
37.81 -> 55.09 vs Elmhurst current 57 (residual is the wood-vs-coal sub-fuel the
Summary export does not carry). Corpus unchanged 72.5% / MAE 0.793; batch 0
raised / 0 diverge; 000565 e2e green. (mapper.py also carries an earlier,
behaviour-free roof-window doc comment.) Spec-cited unit pins added (AAA).
pyright not installed locally — strict type gate not run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 08:46:00 +00:00
..
climate Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
rdsap fix(fuel): close case 47 — correct the second main heating system's fuel (off-peak pricing + Elmhurst Summary solid-fuel) 2026-06-23 08:46:00 +00:00
validation Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
worksheet Merge remote-tracking branch 'origin/main' into feature/per-cert-mapper-validation 2026-06-18 15:00:32 +00:00
__init__.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_bre_worked_examples.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_calculator.py fix(rating): floor the continuous SAP score at 1 (SAP 10.2 §13 / RdSAP 10 §13) 2026-06-19 14:03:13 +00:00
test_pcdb_etl.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_pcdb_lookup.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_pcdb_table_322_lookup.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_pcdb_table_329_lookup.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_pcdb_table_362_lookup.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_postcode_weather.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_real_cert_sap_accuracy.py Pin uprn_10093116336 (full-SAP gas-combi 2-storey semi): engine 83 vs Elmhurst 79 2026-06-17 09:41:29 +00:00
test_table_12.py Move sap10_calculator tests to tests/domain/sap10_calculator/ for CI 2026-06-02 16:58:00 +00:00
test_table_12a.py fix(tariff): Unknown meter + storage/CPSU main → off-peak (§12) 2026-06-06 19:02:34 +00:00
test_table_13.py fix(water-heating): 18-/24-hour immersion DHW bills 100% low-rate (Table 12a scope) 2026-06-10 22:01:35 +00:00
test_table_32.py fix(fuel): raise UnpricedFuelCode for unrecognised fuels instead of silently defaulting to mains gas 2026-06-23 08:31:04 +00:00