diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 4fc0b0736..cdadf50bf 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -12,6 +12,7 @@ boiler bundles land in later slices. Detection + pricing only — impact is produced by scoring (ADR-0016). """ +from dataclasses import replace from typing import Optional from datatypes.epc.domain.epc_property_data import EpcPropertyData, MainHeatingDetail @@ -743,6 +744,16 @@ def _ashp_option( ``design_heat_loss_kw`` (ADR-0049), falling back to the floor-area proxy.""" if not _ashp_eligible(epc, restrictions): return None + # Size the pump to the dwelling: the calculator's design heat loss when the + # caller threaded it, else the floor-area proxy (ADR-0049). + heat_loss_kw: float = ( + design_heat_loss_kw + if design_heat_loss_kw is not None + else epc.total_floor_area_m2 * _KW_PER_M2 + ) + sized_overlay: HeatingOverlay = replace( + _ASHP_OVERLAY, main_heating_index_number=select_ashp_pcdb_id(heat_loss_kw) + ) # Cost is composed per-dwelling from the rate sheet (ADR-0025), not the # single catalogue scalar; the catalogue row is read only for its id, so an # absent ASHP row must not suppress the bundle — it just carries no id. @@ -754,7 +765,7 @@ def _ashp_option( "Replace the heating with an air-source heat pump, time-and-" "temperature-zone controls and a heat-pump hot-water cylinder" ), - overlay=EpcSimulation(heating=_ASHP_OVERLAY), + overlay=EpcSimulation(heating=sized_overlay), cost=cost, material_id=product.id if product is not None else None, ) diff --git a/tests/domain/modelling/test_heating_recommendation.py b/tests/domain/modelling/test_heating_recommendation.py index e01a55c17..2477150ef 100644 --- a/tests/domain/modelling/test_heating_recommendation.py +++ b/tests/domain/modelling/test_heating_recommendation.py @@ -203,8 +203,10 @@ def test_gas_boiler_house_yields_an_ashp_bundle() -> None: # bungalow regardless of current system or efficiency (ADR-0024). baseline: EpcPropertyData = _gas_boiler_house() - # Act - recommendation: Recommendation | None = recommend_heating(baseline, _StubProducts()) + # Act — a ~4 kW design heat loss sizes to the 5 kW aroTHERM plus (110257). + recommendation: Recommendation | None = recommend_heating( + baseline, _StubProducts(), design_heat_loss_kw=4.0 + ) # Assert — the ASHP bundle carries the absolute heat-pump end-state. assert recommendation is not None