mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Merge branch 'main' into feature/pashub-map-main-heating-control-1557
This commit is contained in:
commit
1e9231a086
2 changed files with 76 additions and 8 deletions
|
|
@ -6026,7 +6026,7 @@ def _map_sap_window(window: Window) -> SapWindow:
|
|||
glazing_gap=window.glazing_gap,
|
||||
orientation=window.orientation,
|
||||
window_type=window.window_type,
|
||||
glazing_type=window.glazing_type,
|
||||
glazing_type=_pashub_glazing_type_int(window.glazing_type),
|
||||
window_width=window.width_m,
|
||||
window_height=window.height_m,
|
||||
draught_proofed=window.draught_proofed,
|
||||
|
|
@ -7261,6 +7261,37 @@ def _pashub_wall_insulation_type_int(label: Optional[str]) -> Union[int, str]:
|
|||
return _PASHUB_WALL_INSULATION_TYPE_TO_SAP10[key]
|
||||
|
||||
|
||||
# PasHub surveyed window `glazing_type` label → SAP10 cascade glazing code that
|
||||
# the calculator reads for both the window U (`_GLAZING_CODE_TO_UWINDOW` /
|
||||
# u_window, RdSAP 10 Table 24) and the solar g-value
|
||||
# (`_G_PERPENDICULAR_BY_GLAZING_TYPE`, Table 6b). The install-year band is
|
||||
# load-bearing on U (double pre-2002 = 2.8, 2002-2021 = 2.0, post-2022 = 1.4);
|
||||
# an unknown install date defaults to the conservative pre-2002 code (per the
|
||||
# `_API_GLAZING_TYPE_TO_TRANSMISSION` "pre-2002 / unknown install date" pairing).
|
||||
_PASHUB_GLAZING_TYPE_TO_SAP10: Dict[str, int] = {
|
||||
"Double glazing installed before 2002": 3, # double pre-2002 (U 2.8)
|
||||
"Double glazing installed between 2002 - 2021": 2, # double 2002-2022 (U 2.0)
|
||||
"Double glazing, Unknown install date": 3, # unknown → pre-2002 default (U 2.8)
|
||||
"Double glazing installed during or after 2022": 13, # double 2022+ (U 1.4)
|
||||
}
|
||||
|
||||
|
||||
def _pashub_glazing_type_int(label: Optional[str]) -> Union[int, str]:
|
||||
"""Resolve a PasHub surveyed window `glazing_type` label to its SAP10 cascade
|
||||
glazing code at the mapper boundary. A blank label is "no lodging" and passes
|
||||
through as the empty string (the field is `Union[int, str]`; the calculator's
|
||||
isinstance-int guards then fall to their double-glazed defaults); a non-empty
|
||||
label the lookup does not cover strict-raises `UnmappedPasHubLabel` so the
|
||||
coverage gap is fixed here rather than silently pinning every window to the
|
||||
double-pre-2002 U=2.8 default downstream (#1562)."""
|
||||
if label is None or not label.strip():
|
||||
return ""
|
||||
key = label.strip()
|
||||
if key not in _PASHUB_GLAZING_TYPE_TO_SAP10:
|
||||
raise UnmappedPasHubLabel("glazing type", label)
|
||||
return _PASHUB_GLAZING_TYPE_TO_SAP10[key]
|
||||
|
||||
|
||||
def _resolve_elmhurst_underfloor_subtype(
|
||||
main_floor: ElmhurstFloorDetails,
|
||||
main_age_band: str,
|
||||
|
|
|
|||
|
|
@ -151,6 +151,43 @@ class TestWallInsulationTypeCoding:
|
|||
EpcPropertyDataMapper.from_site_notes(survey)
|
||||
|
||||
|
||||
class TestGlazingTypeCoding:
|
||||
"""`from_site_notes` must int-code the PAS Hub window `glazing_type` label to
|
||||
the SAP10 cascade glazing code the calculator reads (`_GLAZING_CODE_TO_UWINDOW`
|
||||
for the window U, `_G_PERPENDICULAR_BY_GLAZING_TYPE` for solar g), not copy the
|
||||
raw label. A raw label reads as `None`, so every window falls to the double-
|
||||
pre-2002 U=2.8 default — over-counting heat loss on the ~852/1669 windows the
|
||||
survey dates to 2002-2021 (which are U=2.0) (Guinness cohort, issue #1562).
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"label, expected_code",
|
||||
[
|
||||
("Double glazing installed before 2002", 3), # double pre-2002, U 2.8
|
||||
("Double glazing installed between 2002 - 2021", 2), # double 2002-2022, U 2.0
|
||||
("Double glazing, Unknown install date", 3), # unknown → pre-2002 default, U 2.8
|
||||
("Double glazing installed during or after 2022", 13), # double 2022+, U 1.4
|
||||
("", ""), # no lodging — passes through (calc nulls it)
|
||||
],
|
||||
)
|
||||
def test_label_maps_to_sap_code(
|
||||
self, label: str, expected_code: "int | str"
|
||||
) -> None:
|
||||
data = load("pashub_rdsap_site_notes_example1.json")
|
||||
for window in data["windows"]:
|
||||
window["glazing_type"] = label
|
||||
survey = from_dict(PasHubRdSapSiteNotes, data)
|
||||
result = EpcPropertyDataMapper.from_site_notes(survey)
|
||||
assert result.sap_windows[0].glazing_type == expected_code
|
||||
|
||||
def test_unknown_label_strict_raises(self) -> None:
|
||||
data = load("pashub_rdsap_site_notes_example1.json")
|
||||
data["windows"][0]["glazing_type"] = "Quadruple glazing, vacuum"
|
||||
survey = from_dict(PasHubRdSapSiteNotes, data)
|
||||
with pytest.raises(UnmappedPasHubLabel):
|
||||
EpcPropertyDataMapper.from_site_notes(survey)
|
||||
|
||||
|
||||
class TestFromSiteNotesExample1:
|
||||
"""
|
||||
Fixture: pashub_rdsap_site_notes_example1.json
|
||||
|
|
@ -325,9 +362,9 @@ class TestFromSiteNotesExample1:
|
|||
assert result.sap_windows[0].orientation == "South East"
|
||||
|
||||
def test_window_glazing_type(self, result: EpcPropertyData) -> None:
|
||||
assert (
|
||||
result.sap_windows[0].glazing_type == "Double glazing, Unknown install date"
|
||||
)
|
||||
# windows[].glazing_type: "Double glazing, Unknown install date"
|
||||
# → SAP10 cascade code 3 (double pre-2002 default, U 2.8)
|
||||
assert result.sap_windows[0].glazing_type == 3
|
||||
|
||||
# --- building parts ---
|
||||
|
||||
|
|
@ -529,7 +566,7 @@ class TestFromSiteNotesExample1:
|
|||
glazing_gap="16 mm or more",
|
||||
orientation="South East",
|
||||
window_type="Window",
|
||||
glazing_type="Double glazing, Unknown install date",
|
||||
glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3
|
||||
window_width=1.0,
|
||||
window_height=1.36,
|
||||
draught_proofed=True,
|
||||
|
|
@ -542,7 +579,7 @@ class TestFromSiteNotesExample1:
|
|||
glazing_gap="16 mm or more",
|
||||
orientation="South East",
|
||||
window_type="Window",
|
||||
glazing_type="Double glazing, Unknown install date",
|
||||
glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3
|
||||
window_width=0.96,
|
||||
window_height=1.33,
|
||||
draught_proofed=True,
|
||||
|
|
@ -555,7 +592,7 @@ class TestFromSiteNotesExample1:
|
|||
glazing_gap="16 mm or more",
|
||||
orientation="North West",
|
||||
window_type="Window",
|
||||
glazing_type="Double glazing, Unknown install date",
|
||||
glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3
|
||||
window_width=0.96,
|
||||
window_height=1.04,
|
||||
draught_proofed=True,
|
||||
|
|
@ -568,7 +605,7 @@ class TestFromSiteNotesExample1:
|
|||
glazing_gap="16 mm or more",
|
||||
orientation="North West",
|
||||
window_type="Window",
|
||||
glazing_type="Double glazing, Unknown install date",
|
||||
glazing_type=3, # "Double glazing, Unknown install date" → cascade code 3
|
||||
window_width=0.97,
|
||||
window_height=1.02,
|
||||
draught_proofed=True,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue