Drag a solid-fuel room heater's coherent room-heater companions 🟩

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-30 16:44:04 +00:00
parent d5280e9d96
commit 0cd30a13e6

View file

@ -68,6 +68,17 @@ _ASSUMED_DUAL_METER_CODES = OFF_PEAK_IMPLYING_HEATING_CODES | _ROOM_HEATER_CODES
_MANUAL_CHARGE_CONTROL = 2401
_STORAGE_HEATER_CODES = frozenset(range(401, 410))
# SAP Table 4a category 10 ("Room heaters") and its conservative Table 4e Group 6
# control. A landlord names a room heater, not its control; code 2601 ("no
# thermostatic control of room temperature") is the lowest-SAP room-heater
# control — the modal one real solid-fuel room-heater certs lodge — so it never
# over-credits an unobserved control (the room-heater mirror of the storage
# manual-charge default). Scoped per family as archetypes land; solid-fuel room
# heaters are Table 4a 631-636.
_ROOM_HEATER_CATEGORY = 10
_ROOM_HEATER_CONTROL = 2601
_SOLID_FUEL_ROOM_HEATER_CODES = frozenset(range(631, 637))
# SAP Table 4c full boiler-control code: programmer + room thermostat + TRVs. The
# landlord names the boiler, not its controls — but a gas boiler installed under
# modern Building Regs must carry compliant controls, and this overlay already
@ -130,6 +141,17 @@ def _control_for(code: int) -> Optional[int]:
return _MANUAL_CHARGE_CONTROL
if code in _GAS_BOILER_CODES:
return _FULL_BOILER_CONTROL
if code in _SOLID_FUEL_ROOM_HEATER_CODES:
return _ROOM_HEATER_CONTROL
return None
def _category_for(code: int) -> Optional[int]:
"""The SAP Table 4a heating category a code implies, where the archetype
fixes it. Room heaters are category 10 set so a system-only override reads
as a room-heater system, not whatever category the replaced system carried."""
if code in _SOLID_FUEL_ROOM_HEATER_CODES:
return _ROOM_HEATER_CATEGORY
return None
@ -163,6 +185,7 @@ def main_heating_overlay_for(
return EpcSimulation(
heating=HeatingOverlay(
sap_main_heating_code=code,
main_heating_category=_category_for(code),
meter_type=_meter_for(code),
main_heating_control=_control_for(code),
# A landlord override describes the existing dwelling, so its assumed