mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Closes the CO2 / PE residuals for CH1 (boiler community heating, SAP code 301) and CH3 (HP community heating, SAP code 304) via SAP 10.2 Table 4a (PDF p.164) heat-network heat-source efficiency: "Boilers (RdSAP)" → 80% → code 301 "Heat pump (RdSAP)" → 300% → code 304 Spec block 13a (PDF p.153) (467) "PE associated with heat source 2" = [(307b)+(310b)] × 100 / (467b) — i.e. fuel input = network_input × 100 / heat_source_eff before applying Table 12 PE factor. Block 12b (367) mirrors for CO2. The cascade meters network_input directly (eff = 1/DLF for the cost path via Table 12 heat-network rate), so PE / CO2 factors are scaled by 1/heat_source_eff at lookup time — mathematically equivalent to spec's (network_input / eff) × factor. Three changes: 1. New `_HEAT_NETWORK_HEAT_SOURCE_EFFICIENCY: Final[dict[int, float]]` keyed on SAP code: 301 → 0.80, 304 → 3.00. SAP 302 (CHP+boilers) is omitted — the 35%/65% split + displaced-electricity credit per spec block 13b (464)/(466)/(364)/(366) needs the .171 follow-up. 2. New `_heat_network_heat_source_efficiency_scaling(main)` helper returning 1.0 for non-heat-network mains + SAP 302, and 1/heat_source_eff for SAP 301 / 304. 3. Wired into `_main_heating_co2_factor_kg_per_kwh` and `_main_heating_primary_factor` non-electric branches (heat networks are non-electric per `_is_electric_main`). Both functions return `Table_12_factor × scaling` so the cascade's `network_input × scaled_factor` lands on the spec `(network_input / eff) × Table_12_factor`. Closures vs pre-S0380.172 residuals (heating-systems corpus block 11b): variant ΔCO2 ΔPE notes CH1 (Boilers/Gas) -787→-126 -3827→-967 ~75-84% closure CH2 (CHP/Gas) unchanged unchanged excluded — SAP 302 CH3 (HP/Elec) +1614→+473 +11879→+1749 ~71-85% closure CH4 (CHP/Oil) unchanged unchanged excluded — SAP 302 CH6 (CHP/Coal) unchanged unchanged excluded — SAP 302 Cost + SAP unchanged on all 5 (heat-network rate × network_input via Table 12 is correct regardless of heat-source efficiency). Residual CH1 / CH3 gap drivers (follow-up scope): - WHC=901 HW path: cascade reads cert-lodged "Mains gas" as HW fuel on community-heating certs; should fall through to main fuel for the heat-network so the scaling applies on HW side too. - Elmhurst 0.8523 multiplier on heat-network energy column (worksheet (467) energy = spec_formula × 0.8523 uniformly across non-CHP heat-network rows; mechanism not yet identified — spec divergence candidate for SAP_CALCULATOR.md §8). Cohort no-regression verified: 9 ASHP + 38 cohort-2 golden fixtures pass unchanged; the 41-variant heating-systems corpus has identical residuals for non-heat-network certs. The 2 closed CH variants are re-pinned at their new sub-1000 magnitudes. Test baseline at HEAD: 926 pass + 1 skipped (was 926 + 1 at predecessor a4b5f4e7; pin updates net to 0). Pyright net-zero on affected files (cert_to_inputs.py, test_heating_systems_corpus.py): 32 → 32. Per [[feedback-spec-citation-in-commits]] the dispatch table cites SAP 10.2 Table 4a (PDF p.164) verbatim row labels. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| fixtures | ||
| __init__.py | ||
| test_elmhurst_end_to_end.py | ||
| test_elmhurst_extractor.py | ||
| test_end_to_end.py | ||
| test_extractor.py | ||
| test_heating_systems_corpus.py | ||
| test_pdf.py | ||
| test_summary_pdf_mapper_chain.py | ||