mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Score heat-pump dwellings via Table 4e Group 2 controls and Appendix N efficiency 🟩
#1635: 'Programmer, room thermostat and TRVs' on a heat pump → 2210 (PCDB heat_pump_controls), and the lodgement now carries Table 4a category 4 — without it the calculator's Appendix N3.6/N3.7 gate never fired and the PCDB heat pump was billed as 100%-efficient direct electric (6.0/18.5 vs pre 62/57). With the category threaded the two LRHA WAVE 3 fixtures score 52.1/56.9 (the latter within 0.5). LRHA 59→61 computed, within-0.5 42.6%, MAE 2.830 — ratchets hold. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
436675d64f
commit
9d761f6ad1
1 changed files with 37 additions and 5 deletions
|
|
@ -6491,6 +6491,11 @@ def _map_sap_heating(
|
|||
has_fghrs=main.flue_gas_heat_recovery_system,
|
||||
main_fuel_type=main_fuel,
|
||||
sap_main_heating_code=sap_main_heating_code,
|
||||
main_heating_category=(
|
||||
_PASHUB_HEATING_CATEGORY_HEAT_PUMP
|
||||
if main.system_type.lower() in _PASHUB_HEAT_PUMP_SYSTEM_TYPES
|
||||
else None
|
||||
),
|
||||
heat_emitter_type=_pashub_heat_emitter_code(main.emitter),
|
||||
emitter_temperature=main.emitter_temperature,
|
||||
fan_flue_present=main.fan_assist,
|
||||
|
|
@ -7941,6 +7946,29 @@ _PASHUB_HEAT_NETWORK_CONTROL_TO_SAP10: Dict[str, int] = {
|
|||
}
|
||||
|
||||
|
||||
# PasHub `system_type` labels that are SAP 10.2 Table 4e GROUP 2: HEAT PUMPS
|
||||
# WITH RADIATORS OR UNDERFLOOR HEATING (spec PDF p.172). Their control labels
|
||||
# carry 22xx codes; the system's efficiency comes from the lodged PCDB product
|
||||
# (`main_heating_index_number`), not a Table 4a rd row, so
|
||||
# `_pashub_main_heating_system_code` correctly leaves the code None.
|
||||
_PASHUB_HEAT_PUMP_SYSTEM_TYPES: frozenset[str] = frozenset({
|
||||
"heat pump with radiators or underfloor heating",
|
||||
})
|
||||
# Table 4a main-heating category 4 (heat pumps) — the calculator's Appendix
|
||||
# N3.6/N3.7 efficiency, extended-heating and §4f pumps+fans paths all gate on
|
||||
# `main_heating_category == 4` (same category the Elmhurst mapper lodges via
|
||||
# `_ELMHURST_HEATING_CATEGORY_HEAT_PUMP`). Without it a PCDB heat pump is
|
||||
# billed as 100%-efficient direct electric.
|
||||
_PASHUB_HEATING_CATEGORY_HEAT_PUMP: Final[int] = 4
|
||||
|
||||
|
||||
# PasHub surveyed heat-pump control labels → their SAP 10.2 Table 4e Group 2
|
||||
# code (PCDB `heat_pump_controls`, control type 2, temp adjustment 0.0).
|
||||
_PASHUB_HEAT_PUMP_CONTROL_TO_SAP10: Dict[str, int] = {
|
||||
"Programmer, room thermostat and TRVs": 2210,
|
||||
}
|
||||
|
||||
|
||||
# PasHub `system_type` labels that are SAP 10.2 Table 4e GROUP 4: ELECTRIC
|
||||
# STORAGE SYSTEMS (spec PDF p.173). A distinct group from boiler/heat-network,
|
||||
# so its control labels carry their own 24xx codes (see the boiler comment on
|
||||
|
|
@ -8013,9 +8041,10 @@ def _pashub_main_heating_control_code(
|
|||
The resolution is system-aware: the same control label recurs across Table
|
||||
4e's system groups under different 2xxx codes, so the code is chosen by the
|
||||
system's group — Group 1 boiler (`_PASHUB_MAIN_HEATING_CONTROL_TO_SAP10`),
|
||||
Group 3 heat network (`_PASHUB_HEAT_NETWORK_CONTROL_TO_SAP10`), Group 4
|
||||
electric storage (`_PASHUB_STORAGE_HEATER_CONTROL_TO_SAP10`) or Group 6 room
|
||||
heater (`_PASHUB_ROOM_HEATER_CONTROL_TO_SAP10`). Any other system group, or a
|
||||
Group 2 heat pump (`_PASHUB_HEAT_PUMP_CONTROL_TO_SAP10`), Group 3 heat
|
||||
network (`_PASHUB_HEAT_NETWORK_CONTROL_TO_SAP10`), Group 4 electric storage
|
||||
(`_PASHUB_STORAGE_HEATER_CONTROL_TO_SAP10`) or Group 6 room heater
|
||||
(`_PASHUB_ROOM_HEATER_CONTROL_TO_SAP10`). Any other system group, or a
|
||||
label the group's lookup does not cover, strict-raises `UnmappedPasHubLabel`
|
||||
(naming the label and system) rather than silently taking a wrong-group code
|
||||
— the gap is fixed here, never mis-rated or strict-raised deep in the
|
||||
|
|
@ -8025,6 +8054,8 @@ def _pashub_main_heating_control_code(
|
|||
system = system_type.lower()
|
||||
if system in _PASHUB_BOILER_SYSTEM_TYPES:
|
||||
group_map = _PASHUB_MAIN_HEATING_CONTROL_TO_SAP10
|
||||
elif system in _PASHUB_HEAT_PUMP_SYSTEM_TYPES:
|
||||
group_map = _PASHUB_HEAT_PUMP_CONTROL_TO_SAP10
|
||||
elif system in _PASHUB_HEAT_NETWORK_SYSTEM_TYPES:
|
||||
group_map = _PASHUB_HEAT_NETWORK_CONTROL_TO_SAP10
|
||||
elif system in _PASHUB_STORAGE_HEATER_SYSTEM_TYPES:
|
||||
|
|
@ -8035,8 +8066,9 @@ def _pashub_main_heating_control_code(
|
|||
raise UnmappedPasHubLabel(
|
||||
"main heating control",
|
||||
f"{control_label!r} on unsupported system {system_type!r} "
|
||||
f"(only Table 4e Group 1 boiler, Group 3 heat-network, Group 4 "
|
||||
f"electric-storage + Group 6 room-heater codes are mapped)",
|
||||
f"(only Table 4e Group 1 boiler, Group 2 heat-pump, Group 3 "
|
||||
f"heat-network, Group 4 electric-storage + Group 6 room-heater "
|
||||
f"codes are mapped)",
|
||||
)
|
||||
code = group_map.get(control_label)
|
||||
if code is None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue