From a1fc697d933ca1f4a583c6ca212afe719937c532 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Sat, 6 Jun 2026 17:01:40 +0000 Subject: [PATCH] test(modelling): ASHP before/after cascade pin (001431) at 1e-4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A typical mains-gas combi house re-lodged as an air-source heat pump closes at 1e-4 (gas-boiler 1 example from the technical specialist). Closes one named gap the pin surfaced: a whole-system replacement to a PCDB-indexed system left the old Table 4a sap_main_heating_code (104) beside the new heat-pump index, and the stale code won the calculator's efficiency dispatch (hot water billed at boiler not HP efficiency, ΔSAP 3.98). _fold_heating now enforces the mutual exclusion of the two efficiency anchors (setting an index clears the SAP code and vice versa). Also fixed a pre-existing pyright annotation in the lighting applicator test. ADR-0024. Co-Authored-By: Claude Opus 4.8 --- .../modelling/scoring/overlay_applicator.py | 10 ++++ .../modelling/fixtures/ashp_001431_after.pdf | Bin 0 -> 79451 bytes .../ashp_from_gas_boiler_001431_before.pdf | Bin 0 -> 78621 bytes .../modelling/test_elmhurst_cascade_pins.py | 21 ++++++++ .../modelling/test_overlay_applicator.py | 45 +++++++++++++++++- 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/domain/modelling/fixtures/ashp_001431_after.pdf create mode 100644 tests/domain/modelling/fixtures/ashp_from_gas_boiler_001431_before.pdf diff --git a/domain/modelling/scoring/overlay_applicator.py b/domain/modelling/scoring/overlay_applicator.py index 73934779..11d6e562 100644 --- a/domain/modelling/scoring/overlay_applicator.py +++ b/domain/modelling/scoring/overlay_applicator.py @@ -90,6 +90,16 @@ def _fold_heating(epc: EpcPropertyData, overlay: HeatingOverlay) -> None: value = getattr(overlay, field_name) if value is not None: setattr(main, field_name, value) + # `main_heating_index_number` (PCDB-resolved, e.g. a heat pump) and + # `sap_main_heating_code` (Table 4a-resolved, e.g. storage heaters) are + # mutually-exclusive efficiency anchors: a whole-system replacement to one + # must clear the other, else a stale code from the old system wins the + # calculator's dispatch (e.g. a gas-boiler code 104 left beside a heat-pump + # index makes hot water use boiler efficiency, not the HP SCOP). + if overlay.main_heating_index_number is not None: + main.sap_main_heating_code = None + elif overlay.sap_main_heating_code is not None: + main.main_heating_index_number = None for field_name in _SAP_HEATING_FIELDS: value = getattr(overlay, field_name) if value is not None: diff --git a/tests/domain/modelling/fixtures/ashp_001431_after.pdf b/tests/domain/modelling/fixtures/ashp_001431_after.pdf new file mode 100644 index 0000000000000000000000000000000000000000..538a8ed282cafc9d58744b31065962081b45c4b5 GIT binary patch literal 79451 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 F{tKCn1ZDsL literal 0 HcmV?d00001 diff --git a/tests/domain/modelling/fixtures/ashp_from_gas_boiler_001431_before.pdf b/tests/domain/modelling/fixtures/ashp_from_gas_boiler_001431_before.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f67db819a2c67be7faab42e54462da4d49a8db68 GIT binary patch literal 78621 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

+fVKqYJAk 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 N # Act / Assert _assert_overlay_reproduces_after(before, after, option.overlay) + + +def test_ashp_overlay_reproduces_the_relodged_after_from_a_gas_boiler() -> None: + # Arrange — a typical mains-gas combi house re-lodged as an air-source heat + # pump (fuel 26 -> 30, SAP code 104 -> PCDB index 101413 + category 4, + # control 2106 -> 2210), off mains gas, gaining a heat-pump cylinder + # (ADR-0024). + before: EpcPropertyData = parse_recommendation_summary( + "ashp_from_gas_boiler_001431_before.pdf" + ) + after: EpcPropertyData = parse_recommendation_summary( + "ashp_001431_after.pdf" + ) + recommendation: Recommendation | None = recommend_heating(before, _AnyProduct()) + assert recommendation is not None + option = next( + o for o in recommendation.options if o.measure_type == "air_source_heat_pump" + ) + + # Act / Assert + _assert_overlay_reproduces_after(before, after, option.overlay) diff --git a/tests/domain/modelling/test_overlay_applicator.py b/tests/domain/modelling/test_overlay_applicator.py index 16228ec5..75d2c901 100644 --- a/tests/domain/modelling/test_overlay_applicator.py +++ b/tests/domain/modelling/test_overlay_applicator.py @@ -327,11 +327,54 @@ def test_baseline_heating_is_not_mutated_by_a_heating_overlay() -> None: assert baseline.sap_energy_source.mains_gas == original_mains_gas +def test_heating_index_overlay_clears_a_stale_sap_main_heating_code() -> None: + # Arrange — 000490's gas combi lodges a Table 4a code; an ASHP bundle sets a + # PCDB index instead. The two are mutually-exclusive efficiency anchors, so + # the stale code must be cleared or it wins the calculator's dispatch. + baseline: EpcPropertyData = build_epc() + baseline.sap_heating.main_heating_details[0].sap_main_heating_code = 104 + + # Act + result: EpcPropertyData = apply_simulations( + baseline, + [ + EpcSimulation( + heating=HeatingOverlay( + main_heating_index_number=101413, main_heating_category=4 + ) + ) + ], + ) + + # Assert — the index is set and the old SAP code is gone. + main = result.sap_heating.main_heating_details[0] + assert main.main_heating_index_number == 101413 + assert main.sap_main_heating_code is None + + +def test_heating_sap_code_overlay_clears_a_stale_index() -> None: + # Arrange — a dwelling with a PCDB-indexed system; an HHR storage bundle sets + # a Table 4a code instead, so the stale index must be cleared. + baseline: EpcPropertyData = build_epc() + baseline.sap_heating.main_heating_details[0].main_heating_index_number = 8262 + + # Act + result: EpcPropertyData = apply_simulations( + baseline, + [EpcSimulation(heating=HeatingOverlay(sap_main_heating_code=409))], + ) + + # Assert + main = result.sap_heating.main_heating_details[0] + assert main.sap_main_heating_code == 409 + assert main.main_heating_index_number is None + + def test_baseline_lighting_is_not_mutated_by_a_lighting_overlay() -> None: # Arrange — 000490 lodges 8 low-energy-unknown bulbs, 0 LED. baseline: EpcPropertyData = build_epc() original_led: int = baseline.led_fixed_lighting_bulbs_count - original_lel: int = baseline.low_energy_fixed_lighting_bulbs_count + original_lel: int | None = baseline.low_energy_fixed_lighting_bulbs_count # Act — fold an all-LED overlay (led = the 8 total). _: EpcPropertyData = apply_simulations(