mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Cylinder with unknown insulation defaults per RdSAP Table 29 age band 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
233f085fb3
commit
6accf365d7
1 changed files with 73 additions and 0 deletions
|
|
@ -6523,6 +6523,79 @@ def test_elmhurst_no_insulation_cylinder_thickness_zero_takes_uninsulated_loss()
|
|||
assert abs(got_jan_kwh - expected_jan_kwh) < 1e-4
|
||||
|
||||
|
||||
def test_cylinder_with_unknown_insulation_defaults_per_table_29_age_band() -> None:
|
||||
"""RdSAP 10 Table 29 (PDF p.56) "Hot water cylinder insulation if not
|
||||
accessible": when a cylinder is lodged but its insulation is unknown
|
||||
(type absent AND no thickness — ADR-0028 records ~308/1000 17.0 certs
|
||||
omitting `cylinder_insulation_type`), the age-band default applies:
|
||||
bands A-F → 12 mm loose jacket, G/H → 25 mm factory, I-M → 38 mm
|
||||
factory. This is the same Table 29 row the §10.7 no-water-heating
|
||||
default already uses. Previously the cascade returned None (zero
|
||||
storage loss), silently treating an unknown cylinder as a combi.
|
||||
Distinct from the uninsulated case: a lodged 0 mm means NO insulation
|
||||
(t = 0), an absent thickness means NOT ACCESSIBLE (Table 29).
|
||||
"""
|
||||
# Arrange — same dwelling, insulation fields both absent; the
|
||||
# fixture's building part lodges construction_age_band "B" → the
|
||||
# Table 29 A-F row (12 mm loose jacket).
|
||||
from domain.sap10_calculator.worksheet.water_heating import (
|
||||
cylinder_storage_loss_factor_table_2,
|
||||
cylinder_temperature_factor_table_2b,
|
||||
cylinder_volume_factor_table_2a,
|
||||
)
|
||||
|
||||
hp_main = MainHeatingDetail(
|
||||
has_fghrs=False,
|
||||
main_fuel_type=29,
|
||||
heat_emitter_type=1,
|
||||
emitter_temperature=1,
|
||||
main_heating_control=2206,
|
||||
main_heating_category=4,
|
||||
sap_main_heating_code=None,
|
||||
)
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=4,
|
||||
country_code="ENG",
|
||||
has_hot_water_cylinder=True,
|
||||
sap_building_parts=[make_building_part()], # age band B
|
||||
sap_heating=make_sap_heating(
|
||||
main_heating_details=[hp_main],
|
||||
water_heating_code=901,
|
||||
cylinder_size=3, # Medium → 160 L
|
||||
cylinder_insulation_type=None, # not lodged
|
||||
cylinder_insulation_thickness_mm=None, # not lodged
|
||||
cylinder_thermostat="Y",
|
||||
),
|
||||
)
|
||||
expected_jan_kwh = (
|
||||
160.0
|
||||
* cylinder_storage_loss_factor_table_2(
|
||||
insulation_type="loose_jacket", thickness_mm=12.0
|
||||
)
|
||||
* cylinder_volume_factor_table_2a(160.0)
|
||||
* cylinder_temperature_factor_table_2b(
|
||||
has_cylinder_thermostat=True, separately_timed_dhw=True
|
||||
)
|
||||
* 31
|
||||
)
|
||||
|
||||
# Act
|
||||
wh_result, _ = _water_heating_worksheet_and_gains(
|
||||
epc=epc,
|
||||
water_efficiency_pct=1.7,
|
||||
is_instantaneous=False,
|
||||
primary_age="D",
|
||||
pcdb_record=None,
|
||||
)
|
||||
|
||||
# Assert — the Table 29 band-B default (12 mm loose jacket), not the
|
||||
# zero-loss combi default and not the harsher uninsulated t=0.
|
||||
assert wh_result is not None
|
||||
got_jan_kwh = wh_result.solar_storage_monthly_kwh[0]
|
||||
assert abs(got_jan_kwh - expected_jan_kwh) < 1e-4
|
||||
|
||||
|
||||
def test_no_water_heating_default_age_a_to_f_uses_12mm_loose_jacket_per_table_29() -> None:
|
||||
"""RdSAP 10 §10.7 + Table 29 (PDF p.55-56): when no water heating
|
||||
system is lodged, the default cylinder takes the age-band insulation,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue