Model/tests/domain/modelling/test_ashp_cost_inputs.py
Khalim Conn-Kowlessar f182f36802 feat(modelling): ashp_cost_inputs reads a dwelling into AshpCostInputs
Slice 7 of ADR-0025 costing: the modelling-layer interpretation half of the
split. ashp_cost_inputs derives existing system (mains_gas/fuel/SAP-code),
size band (floor area <= 75 m2), design heat loss (floor_area x 0.05 -- the
chosen proxy over HLC, ADR updated), radiator count (habitable + 3, floor-area
fallback) and reusable-wet-system flag. Catalogue math (Products) stays
EPC-free. ADR-0025 updated to record the floor-area pump-sizing choice.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 20:59:27 +00:00

31 lines
1.4 KiB
Python

"""The dwelling interpretation that feeds `Products.ashp_bundle_cost` — reading
an `EpcPropertyData` into a typed `AshpCostInputs` (ADR-0025). This is the
modelling-layer half of the split: it derives the existing system, property
size band, design heat loss (floor-area proxy), radiator count, and whether a
wet system can be reused — the catalogue math (Products) stays EPC-free.
"""
from domain.modelling.generators.heating_recommendation import ashp_cost_inputs
from domain.modelling.products import AshpCostInputs, AshpExistingSystem
from tests.domain.modelling._elmhurst_recommendation import (
parse_recommendation_summary,
)
def test_mains_gas_dwelling_maps_to_a_reusable_wet_gas_system() -> None:
# Arrange — a mains-gas regular boiler with radiators (90 m2, 7 habitable
# rooms): an existing wet system the ASHP can reuse.
epc = parse_recommendation_summary(
"ashp_from_system_boiler_with_cylinder_001431_before.pdf"
)
# Act
inputs: AshpCostInputs = ashp_cost_inputs(epc)
# Assert — gas, large (90 > 75 m2), 4.5 kW (90 x 0.05), 10 radiators
# (7 habitable + 3), reusable wet system.
assert inputs.existing_system is AshpExistingSystem.GAS
assert inputs.is_small_property is False
assert abs(inputs.design_heat_loss_kw - 4.5) <= 1e-9
assert inputs.radiator_count == 10
assert inputs.has_reusable_wet_system is True