mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-19 08:53:17 +00:00
151 lines
5.2 KiB
Python
151 lines
5.2 KiB
Python
"""The Landlord-Override water-heating → heating Simulation Overlay mapping.
|
|
|
|
A water-heating value resolves to the SAP `water_heating_code` (system) and
|
|
`water_heating_fuel` the calculator reads; the overlay is whole-dwelling.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from domain.epc.property_overlays.water_heating_overlay import (
|
|
water_heating_overlay_for,
|
|
)
|
|
from domain.epc.property_overrides.water_heating_type import WaterHeatingType
|
|
from domain.modelling.scoring.overlay_applicator import apply_simulations
|
|
from tests.domain.sap10_calculator.worksheet._elmhurst_worksheet_000490 import (
|
|
build_epc,
|
|
)
|
|
|
|
|
|
def test_from_main_system_mains_gas_overlays_water_heating() -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for("From main system, mains gas", 0)
|
|
|
|
# Assert — "from main system" is water_heating_code 901, mains gas fuel 26.
|
|
assert simulation is not None
|
|
assert simulation.heating is not None
|
|
assert simulation.heating.water_heating_code == 901
|
|
assert simulation.heating.water_heating_fuel == 26
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("water_heating_value", "code", "fuel"),
|
|
[
|
|
("From main system, electricity", 901, 29),
|
|
("Electric immersion, electricity", 903, 29),
|
|
],
|
|
)
|
|
def test_water_heating_systems_decode_to_their_codes(
|
|
water_heating_value: str, code: int, fuel: int
|
|
) -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for(water_heating_value, 0)
|
|
|
|
# Assert
|
|
assert simulation is not None
|
|
assert simulation.heating is not None
|
|
assert simulation.heating.water_heating_code == code
|
|
assert simulation.heating.water_heating_fuel == fuel
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("water_heating_value", "code", "fuel"),
|
|
[
|
|
("From main system, oil", 901, 28),
|
|
("From main system, LPG (bulk)", 901, 27),
|
|
("From main system, bottled LPG", 901, 3),
|
|
("From main system, house coal", 901, 33),
|
|
# "boiler/circulator for water heating only" is SAP Table 4a code 911.
|
|
("Gas boiler/circulator, mains gas", 911, 26),
|
|
],
|
|
)
|
|
def test_more_water_heating_combos_decode_to_their_codes(
|
|
water_heating_value: str, code: int, fuel: int
|
|
) -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for(water_heating_value, 0)
|
|
|
|
# Assert
|
|
assert simulation is not None
|
|
assert simulation.heating is not None
|
|
assert simulation.heating.water_heating_code == code
|
|
assert simulation.heating.water_heating_fuel == fuel
|
|
|
|
|
|
def test_from_main_wood_logs_decodes_to_the_wood_fuel_not_house_coal() -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for("From main system, wood logs", 0)
|
|
|
|
# Assert — wood logs is RdSAP water_heating_fuel 6, from main system (901).
|
|
# A wood-fired dwelling's DHW must not fall to house coal (33), which scores
|
|
# ~14x the carbon (ADR-0043).
|
|
assert simulation is not None
|
|
assert simulation.heating is not None
|
|
assert simulation.heating.water_heating_code == 901
|
|
assert simulation.heating.water_heating_fuel == 6
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("water_heating_value", "fuel"),
|
|
[
|
|
# Biomass (community) — RdSAP fuel 31. Under a coherent community main
|
|
# the calculator scores DHW from the main, so this is a faithful,
|
|
# score-neutral relabel off house coal; the fuel is still emitted so an
|
|
# individual-main dwelling would score biomass, not coal (ADR-0043).
|
|
("From main system, biomass (community)", 31),
|
|
# Dual fuel (mineral + wood) — RdSAP fuel 9.
|
|
("From main system, dual fuel (mineral and wood)", 9),
|
|
# Biodiesel (community) — RdSAP fuel 34.
|
|
("From main system, biodiesel (community)", 34),
|
|
],
|
|
)
|
|
def test_biomass_family_water_heating_decodes_off_house_coal(
|
|
water_heating_value: str, fuel: int
|
|
) -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for(water_heating_value, 0)
|
|
|
|
# Assert — from main system (901), each to its own RdSAP fuel, not coal 33.
|
|
assert simulation is not None
|
|
assert simulation.heating is not None
|
|
assert simulation.heating.water_heating_code == 901
|
|
assert simulation.heating.water_heating_fuel == fuel
|
|
|
|
|
|
@pytest.mark.parametrize("water_heating_value", ["Unknown", ""])
|
|
def test_unresolvable_water_heating_produces_no_overlay(
|
|
water_heating_value: str,
|
|
) -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for(water_heating_value, 0)
|
|
|
|
# Assert
|
|
assert simulation is None
|
|
|
|
|
|
def test_water_heating_override_remaps_the_hot_water_arrangement() -> None:
|
|
# Arrange — landlord correction: HW is a separate electric immersion.
|
|
baseline = build_epc()
|
|
overlay = water_heating_overlay_for("Electric immersion, electricity", 0)
|
|
assert overlay is not None
|
|
|
|
# Act
|
|
result = apply_simulations(baseline, [overlay])
|
|
|
|
# Assert — the calculator reads these off sap_heating.
|
|
assert result.sap_heating.water_heating_code == 903
|
|
assert result.sap_heating.water_heating_fuel == 29
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"member", [m for m in WaterHeatingType if m is not WaterHeatingType.UNKNOWN]
|
|
)
|
|
def test_every_resolvable_water_heating_value_decodes(
|
|
member: WaterHeatingType,
|
|
) -> None:
|
|
# Act
|
|
simulation = water_heating_overlay_for(member.value, 0)
|
|
|
|
# Assert
|
|
assert simulation is not None
|