mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
fix(mapper): map cylinder "No Insulation" to insulation_type=None
The Elmhurst §15.1 "Insulated: No Insulation" label was lodged but absent from `_ELMHURST_CYLINDER_INSULATION_LABEL_TO_SAP10`, so `_elmhurst_cylinder_insulation_code` raised UnmappedElmhurstLabel — blocking the parse of every Solar PV example cert (the solar `before` lodges "No Insulation"). An uninsulated cylinder has no insulation *type*, so per the no-misleading-insulation convention it maps to `cylinder_insulation_type = None` rather than naming a material; the lodged 0 mm thickness carries the storage-loss signal the SAP 10.2 Table 2 dispatch needs. Slice 1 of the Solar PV Recommendation Generator (ADR-0026). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
222704cbc2
commit
545bb8c328
2 changed files with 61 additions and 0 deletions
|
|
@ -4868,6 +4868,16 @@ _ELMHURST_CYLINDER_INSULATION_LABEL_TO_SAP10: Dict[str, int] = {
|
||||||
"Jacket": 2,
|
"Jacket": 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Elmhurst §15.1 "Insulated" labels for an uninsulated cylinder. These are
|
||||||
|
# lodged (not absent), but an uninsulated cylinder has no insulation *type* —
|
||||||
|
# per the no-misleading-insulation convention it maps to
|
||||||
|
# `cylinder_insulation_type = None` rather than naming a material. The lodged
|
||||||
|
# §15.1 "Insulation Thickness" (0 mm) carries the storage-loss signal the
|
||||||
|
# cascade's SAP 10.2 Table 2 dispatch needs.
|
||||||
|
_ELMHURST_CYLINDER_NO_INSULATION_LABELS: frozenset[str] = frozenset({
|
||||||
|
"No Insulation",
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
# Elmhurst §15.0 "Water Heating Fuel Type" labels that route to solid-
|
# Elmhurst §15.0 "Water Heating Fuel Type" labels that route to solid-
|
||||||
# fuel Table 32 codes (Anthracite, House coal, Wood logs/pellets, etc.).
|
# fuel Table 32 codes (Anthracite, House coal, Wood logs/pellets, etc.).
|
||||||
|
|
@ -4978,6 +4988,8 @@ def _elmhurst_cylinder_insulation_code(
|
||||||
mapping dict — see `_elmhurst_cylinder_size_code` rationale."""
|
mapping dict — see `_elmhurst_cylinder_size_code` rationale."""
|
||||||
if not cylinder_present or cylinder_insulation_label is None:
|
if not cylinder_present or cylinder_insulation_label is None:
|
||||||
return None
|
return None
|
||||||
|
if cylinder_insulation_label in _ELMHURST_CYLINDER_NO_INSULATION_LABELS:
|
||||||
|
return None
|
||||||
code = _ELMHURST_CYLINDER_INSULATION_LABEL_TO_SAP10.get(cylinder_insulation_label)
|
code = _ELMHURST_CYLINDER_INSULATION_LABEL_TO_SAP10.get(cylinder_insulation_label)
|
||||||
if code is None:
|
if code is None:
|
||||||
raise UnmappedElmhurstLabel("cylinder_insulation", cylinder_insulation_label)
|
raise UnmappedElmhurstLabel("cylinder_insulation", cylinder_insulation_label)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
"""Mapper boundary: the Elmhurst §15.1 "Insulated" cylinder label.
|
||||||
|
|
||||||
|
A cylinder lodged "No Insulation" is an uninsulated cylinder, not a mapper
|
||||||
|
gap. Per the no-misleading-insulation convention it maps to
|
||||||
|
`cylinder_insulation_type = None` (don't name an insulation material on an
|
||||||
|
uninsulated surface) rather than raising `UnmappedElmhurstLabel`. This
|
||||||
|
unblocks parsing every solar example cert (the solar `before` cert lodges
|
||||||
|
"No Insulation").
|
||||||
|
"""
|
||||||
|
|
||||||
|
from datatypes.epc.domain.mapper import (
|
||||||
|
UnmappedElmhurstLabel,
|
||||||
|
_elmhurst_cylinder_insulation_code, # pyright: ignore[reportPrivateUsage]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_insulation_label_maps_to_none() -> None:
|
||||||
|
# Arrange
|
||||||
|
label = "No Insulation"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
code = _elmhurst_cylinder_insulation_code(label, cylinder_present=True)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert code is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_foam_label_still_maps_to_factory_code() -> None:
|
||||||
|
# Arrange
|
||||||
|
label = "Foam"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
code = _elmhurst_cylinder_insulation_code(label, cylinder_present=True)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
assert code == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_unknown_label_still_raises() -> None:
|
||||||
|
# Arrange
|
||||||
|
label = "Spray-on unicorn felt"
|
||||||
|
|
||||||
|
# Act / Assert
|
||||||
|
try:
|
||||||
|
_elmhurst_cylinder_insulation_code(label, cylinder_present=True)
|
||||||
|
raised = False
|
||||||
|
except UnmappedElmhurstLabel:
|
||||||
|
raised = True
|
||||||
|
assert raised
|
||||||
Loading…
Add table
Reference in a new issue