mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Preserve an existing more-off-peak cert meter under a heating overlay 🟩
A landlord heating override DESCRIBES the dwelling, so its assumed off-peak meter (Dual/E7) is a coherent default — it must not downgrade a cert that already lodges a more-off-peak meter (e.g. property 709874's 24-hour all-low tariff). The overlay opts in via keep_existing_off_peak_meter; _fold_heating then keeps the cert's meter when both it and the desired meter are off-peak. Heating MEASURES build HeatingOverlay directly and leave the flag False, so they still re-meter for real (Elmhurst re-lodges 18-hour -> Dual on a storage install) — the cascade pins stay green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e3c023e0f6
commit
e02e6a76e1
3 changed files with 47 additions and 2 deletions
|
|
@ -164,5 +164,10 @@ def main_heating_overlay_for(
|
|||
sap_main_heating_code=code,
|
||||
meter_type=_meter_for(code),
|
||||
main_heating_control=_control_for(code),
|
||||
# A landlord override describes the existing dwelling, so its assumed
|
||||
# off-peak meter must not downgrade a more-off-peak cert meter
|
||||
# (e.g. a 24-hour all-low tariff). Measures, which re-meter for real,
|
||||
# build their HeatingOverlay directly and leave this False.
|
||||
keep_existing_off_peak_meter=True,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -152,6 +152,22 @@ _SAP_HEATING_FIELDS: tuple[str, ...] = (
|
|||
_ENERGY_SOURCE_FIELDS: tuple[str, ...] = ("meter_type", "mains_gas")
|
||||
|
||||
|
||||
def _is_off_peak_meter(meter_type: object) -> bool:
|
||||
"""True iff the meter resolves to an off-peak Table 12a tariff (not the
|
||||
STANDARD single-rate column). Unparseable / absent meters count as not
|
||||
off-peak so a coherent override meter still applies to them."""
|
||||
from domain.sap10_calculator.exceptions import UnmappedSapCode
|
||||
from domain.sap10_calculator.tables.table_12a import (
|
||||
Tariff,
|
||||
tariff_from_meter_type,
|
||||
)
|
||||
|
||||
try:
|
||||
return tariff_from_meter_type(meter_type) is not Tariff.STANDARD
|
||||
except UnmappedSapCode:
|
||||
return False
|
||||
|
||||
|
||||
def _fold_heating(epc: EpcPropertyData, overlay: HeatingOverlay) -> None:
|
||||
"""Write a `HeatingOverlay`'s non-``None`` fields onto the (copied) dwelling,
|
||||
routing each to its home: the primary ``main_heating_details[0]``, the
|
||||
|
|
@ -181,8 +197,25 @@ def _fold_heating(epc: EpcPropertyData, overlay: HeatingOverlay) -> None:
|
|||
epc.has_hot_water_cylinder = overlay.has_hot_water_cylinder
|
||||
for field_name in _ENERGY_SOURCE_FIELDS:
|
||||
value = getattr(overlay, field_name)
|
||||
if value is not None:
|
||||
setattr(epc.sap_energy_source, field_name, value)
|
||||
if value is None:
|
||||
continue
|
||||
# A landlord heating override's assumed meter (Dual for off-peak
|
||||
# systems) is a coherent default, not a re-metering of the cert: when it
|
||||
# opts in (`keep_existing_off_peak_meter`), don't downgrade a cert that
|
||||
# already lodges a MORE off-peak meter (e.g. a 24-hour all-low tariff) to
|
||||
# the overlay's 7-hour E7 — keep the cert's (more specific) one. Single/
|
||||
# unknown existing meters still receive the off-peak meter, and a switch
|
||||
# to single-rate still resets it (its desired value isn't off-peak).
|
||||
# Heating MEASURES leave the flag False — they re-meter for real
|
||||
# (Elmhurst re-lodges 18-hour → Dual on a storage install).
|
||||
if (
|
||||
field_name == "meter_type"
|
||||
and overlay.keep_existing_off_peak_meter
|
||||
and _is_off_peak_meter(value)
|
||||
and _is_off_peak_meter(epc.sap_energy_source.meter_type)
|
||||
):
|
||||
continue
|
||||
setattr(epc.sap_energy_source, field_name, value)
|
||||
|
||||
|
||||
# `SolarOverlay` fields all live on `sap_energy_source` (the home of the SAP
|
||||
|
|
|
|||
|
|
@ -193,6 +193,13 @@ class HeatingOverlay:
|
|||
# sap_energy_source
|
||||
meter_type: Optional[str] = None
|
||||
mains_gas: Optional[bool] = None
|
||||
# A landlord heating-system override DESCRIBES the existing dwelling, so its
|
||||
# assumed off-peak (`meter_type`) is a coherent default, not a re-metering:
|
||||
# it must not downgrade a cert that already lodges a MORE off-peak meter
|
||||
# (e.g. a 24-hour all-low tariff → the overlay's 7-hour E7). A heating
|
||||
# MEASURE re-meters for real (Elmhurst re-lodges 18-hour → Dual on a storage
|
||||
# install), so it leaves this False. `_fold_heating` reads it.
|
||||
keep_existing_off_peak_meter: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue