mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Map PasHub secondary-heating fuel to a SAP10 fuel code
secondary_fuel_type was hardcoded None in the from_site_notes mapper, dropping the fuel for the ~67 Guinness GMCA 205 properties that lodge a "Panel, convector or radiant heaters" secondary heater. Adds _pashub_secondary_fuel_code (ADR-0015 pattern, mirrors _pashub_main_fuel_code) mapping "Electricity" -> SAP10 code 30, with "No Secondary Heating"/blank -> None and unknown labels strict-raising UnmappedPasHubLabel. Fixes #1564 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
f7e6bf1184
commit
56b551674e
2 changed files with 58 additions and 6 deletions
|
|
@ -6042,12 +6042,7 @@ def _map_sap_heating(
|
|||
main = heating.main_heating
|
||||
secondary = heating.secondary_heating
|
||||
|
||||
# secondary_fuel_type is an int code in the domain model; we can't map a
|
||||
# site-notes string directly, so leave it None unless there is secondary heating.
|
||||
# The string fuel type is preserved via sap_heating when needed.
|
||||
secondary_fuel_type = (
|
||||
None if secondary.secondary_fuel == "No Secondary Heating" else None
|
||||
)
|
||||
secondary_fuel_type = _pashub_secondary_fuel_code(secondary.secondary_fuel)
|
||||
|
||||
shower_outlets = (
|
||||
ShowerOutlets(
|
||||
|
|
@ -7115,6 +7110,28 @@ _PASHUB_MAIN_FUEL_TO_SAP10: Dict[str, int] = {
|
|||
"Electricity": 30, # the standard-electricity fuel code
|
||||
}
|
||||
|
||||
# PasHub surveyed secondary-heating `secondary_fuel` label → SAP 10.2 Table 32
|
||||
# fuel code that `secondary_fuel_type` (an int in the domain model) consumes.
|
||||
# "No Secondary Heating" is the no-secondary-heater shape and maps to None,
|
||||
# not a fuel code.
|
||||
_PASHUB_SECONDARY_FUEL_TO_SAP10: Dict[str, int] = {
|
||||
"Electricity": 30, # standard electricity, Table 32 code 30
|
||||
}
|
||||
|
||||
|
||||
def _pashub_secondary_fuel_code(fuel_label: str) -> Optional[int]:
|
||||
"""Resolve a PasHub surveyed secondary-heating Fuel label to a SAP10
|
||||
Table 32 fuel code at the mapper boundary (ADR-0015). "No Secondary
|
||||
Heating" is the no-secondary-heater shape and maps to None; a non-empty
|
||||
label the lookup does not cover strict-raises `UnmappedPasHubLabel` so
|
||||
the gap is fixed here, never silently mis-billed downstream."""
|
||||
if not fuel_label or fuel_label == "No Secondary Heating":
|
||||
return None
|
||||
code = _PASHUB_SECONDARY_FUEL_TO_SAP10.get(fuel_label)
|
||||
if code is None:
|
||||
raise UnmappedPasHubLabel("secondary fuel", fuel_label)
|
||||
return code
|
||||
|
||||
|
||||
def _pashub_main_fuel_code(fuel_label: str) -> Union[int, str]:
|
||||
"""Resolve a PasHub surveyed main-heating Fuel label to a SAP10 fuel code
|
||||
|
|
|
|||
|
|
@ -113,6 +113,41 @@ class TestWallConstructionCoding:
|
|||
EpcPropertyDataMapper.from_site_notes(survey)
|
||||
|
||||
|
||||
class TestSecondaryFuelTypeCoding:
|
||||
"""`from_site_notes` must int-code the PAS Hub secondary-heating
|
||||
`secondary_fuel` label to the SAP 10.2 Table 32 `secondary_fuel_type`
|
||||
code, not leave it hardcoded `None`. ~67/205 Guinness cohort properties
|
||||
lodge a "Panel, convector or radiant heaters" secondary heater whose
|
||||
fuel was silently dropped (issue #1564).
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"label, expected_code",
|
||||
[
|
||||
("Electricity", 30), # standard electricity, Table 32 code 30
|
||||
("No Secondary Heating", None), # no secondary heater lodged
|
||||
("", None), # no lodging
|
||||
],
|
||||
)
|
||||
def test_label_maps_to_sap_code(
|
||||
self, label: str, expected_code: Optional[int]
|
||||
) -> None:
|
||||
data = load("pashub_rdsap_site_notes_example1.json")
|
||||
data["heating_and_hot_water"]["secondary_heating"]["secondary_fuel"] = label
|
||||
survey = from_dict(PasHubRdSapSiteNotes, data)
|
||||
result = EpcPropertyDataMapper.from_site_notes(survey)
|
||||
assert result.sap_heating.secondary_fuel_type == expected_code
|
||||
|
||||
def test_unknown_label_strict_raises(self) -> None:
|
||||
data = load("pashub_rdsap_site_notes_example1.json")
|
||||
data["heating_and_hot_water"]["secondary_heating"][
|
||||
"secondary_fuel"
|
||||
] = "Bulk LPG"
|
||||
survey = from_dict(PasHubRdSapSiteNotes, data)
|
||||
with pytest.raises(UnmappedPasHubLabel):
|
||||
EpcPropertyDataMapper.from_site_notes(survey)
|
||||
|
||||
|
||||
class TestWallInsulationTypeCoding:
|
||||
"""`from_site_notes` must int-code the PAS Hub `walls_insulation_type` label
|
||||
to the SAP10 wall-insulation code `u_wall` consumes (matching the Elmhurst
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue