mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Resolve a high-heat-retention storage override to SAP code 409 🟥
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6819ca7d89
commit
79f48c0564
2 changed files with 107 additions and 0 deletions
|
|
@ -0,0 +1,94 @@
|
|||
# A baseline HHRSH override drags its intrinsic SAP-409 controls, not the generic manual storage default
|
||||
|
||||
## Status
|
||||
|
||||
accepted
|
||||
|
||||
## Context
|
||||
|
||||
A **Landlord Override** naming *"High heat retention storage heaters"* (HHRSH) had
|
||||
no home in the heating taxonomy: `MainHeatingSystemType` carried
|
||||
`ELECTRIC_STORAGE_OLD` (SAP 401), `_SLIMLINE` (402), `_CONVECTOR` (403) and
|
||||
`_FAN` (404), but no High-Heat-Retention member. So the LLM classifier funnelled
|
||||
the **best modern storage** into **`"Electric storage heaters, old"` (401)** — the
|
||||
**worst** large-volume type. An audit found **111** `property_overrides` rows on
|
||||
that mapping (`'Electric Storage Systems: High heat retention storage heaters'` →
|
||||
`'Electric storage heaters, old'`). Same missing-archetype defect as ADR-0041.
|
||||
|
||||
HHRSH is a distinct, modellable RdSAP system: **SAP Table 4a code 409** (high heat
|
||||
retention storage heaters), which the calculator already scores
|
||||
(`sap_efficiencies` carries `409: 1.00`). The **HHRSH *measure*** already installs
|
||||
this exact code (`_HHR_STORAGE_SAP_CODE = 409`,
|
||||
`domain/modelling/generators/heating_recommendation.py`) on a **Dual** off-peak
|
||||
meter with **control 2404**.
|
||||
|
||||
The subtlety is the **charge control**. `main_heating_system_overlay._control_for`
|
||||
drags the **conservative manual** charge control (`2401`) for *every* storage code
|
||||
401–409, following ADR-0041's amendment ("an *unobserved* storage charge control
|
||||
defaults to the conservative manual one"). Table 4e Group 4's mean-internal-
|
||||
temperature adjustments are **manual +0.7 °C, automatic/Celect +0.4 °C, HHR 0 °C**
|
||||
— so a manual default carries a penalty. Applying it to a 409 heater would swap
|
||||
"scored as old-storage 401" for "scored as 409-but-penalised" — still under-
|
||||
crediting the 111 dwellings, and pairing 409 with manual control is not a
|
||||
combination RdSAP produces.
|
||||
|
||||
**HHRSH has a single, intrinsic charge control (2404).** The control is therefore
|
||||
*named by the archetype*, not *unobserved* — unlike a generic storage heater whose
|
||||
control genuinely is unknown. So ADR-0041's manual-default rule does not apply to
|
||||
409.
|
||||
|
||||
## Decision
|
||||
|
||||
Add the baseline HHRSH archetype and let it drag its **coherent, intrinsic**
|
||||
companions — mirroring how a gas-boiler archetype drags full modern controls
|
||||
(`_control_for`) rather than a conservative default.
|
||||
|
||||
1. **`MainHeatingSystemType.ELECTRIC_STORAGE_HIGH_HEAT_RETENTION` =
|
||||
`"Electric storage heaters, high heat retention"`**, mapped in
|
||||
`_MAIN_HEATING_CODES` to **SAP Table 4a code 409**.
|
||||
2. **Control 2404 (HHRSH controls), not the manual default.** `_control_for`
|
||||
special-cases 409 → `2404` ahead of the generic storage → `2401`. HHRSH's single
|
||||
intrinsic control is archetype-implied, an **exception to ADR-0041's
|
||||
unobserved-storage manual default** (which stands for 401–404).
|
||||
3. **Electricity fuel (RdSAP 29).** `_natural_fuel_for` drags electricity for 409,
|
||||
per ADR-0041's "storage → electricity" — so a mis-lodged non-electric fuel can't
|
||||
leave an electric-storage dwelling incoherent. Scoped to 409 ("scoped per family
|
||||
as archetypes land"); the pre-existing 401–404 fuel-drag gap is not touched here.
|
||||
4. **Dual/off-peak meter falls out of the code** — 409 is already in
|
||||
`_ASSUMED_DUAL_METER_CODES`, so the off-peak meter drags automatically (ADR-0035
|
||||
coherent companions).
|
||||
5. **Deterministic guard + reclassify, TEXT-first / pgEnum-deferred.** A
|
||||
`main_heating_guard` recognises the structured `"Electric Storage Systems: High
|
||||
heat retention storage heaters"` phrasing (wired via `GuardedColumnClassifier`);
|
||||
`scripts/reclassify_hhrsh_storage.py` reuses the same guard as its decision
|
||||
function, updates `property_overrides.override_value` (TEXT) unconditionally, and
|
||||
defers the `landlord_main_heating_system_overrides.value` pgEnum-cache write for
|
||||
the new value.
|
||||
|
||||
## Consequences
|
||||
|
||||
- The 111 HHRSH dwellings score as **409 + HHR control 2404 + off-peak meter +
|
||||
electricity** — the efficient modern archetype — instead of the worst old
|
||||
large-volume 401. Correct Rebaselining (ADR-0039).
|
||||
- **FE-owned pgEnum addition (Dan):** one new `main_heating_system` value,
|
||||
`"Electric storage heaters, high heat retention"` (memory
|
||||
`main-heating-system-pgenum-is-fe-owned`). TEXT read path is fixed on merge; the
|
||||
cache write defers until the migration lands.
|
||||
- **Baseline vs measure stay distinct but consistent:** both use code 409 +
|
||||
control 2404; the measure additionally installs a designed HW cylinder / immersion
|
||||
end-state, which a baseline (existing-system) override does not.
|
||||
- Extends [ADR-0041](0041-landlord-heating-classification-targets-a-complete-modellable-taxonomy.md)
|
||||
(complete taxonomy; **refines** its manual-default amendment for the single-
|
||||
control HHRSH case) and [ADR-0035](0035-coherent-heating-system-synthesis.md)
|
||||
(companions drag from the code).
|
||||
|
||||
### Alternatives rejected
|
||||
|
||||
- **409 + manual control (2401), holding to ADR-0041's default.** Rejected: HHRSH's
|
||||
control is intrinsic (single option), not unobserved; the +0.7 °C manual penalty
|
||||
under-credits, and 409+manual is not a real RdSAP combination.
|
||||
- **Reuse an existing storage archetype (401–404).** Rejected: none carries the
|
||||
HHR retention/control — the whole point of the mis-score.
|
||||
- **Leave fuel unresolved (as 401–404 do).** Rejected for 409: an explicit
|
||||
electricity drag keeps the system coherent if the lodged fuel is wrong; the older
|
||||
archetypes' gap is a separate, out-of-scope cleanup.
|
||||
|
|
@ -98,6 +98,19 @@ def test_storage_heater_subtypes_decode_to_their_codes(
|
|||
assert simulation.heating.sap_main_heating_code == code
|
||||
|
||||
|
||||
def test_high_heat_retention_storage_decodes_to_its_own_code_not_old_storage() -> None:
|
||||
# Act
|
||||
simulation = main_heating_overlay_for(
|
||||
"Electric storage heaters, high heat retention", 0
|
||||
)
|
||||
|
||||
# Assert — HHRSH is SAP Table 4a code 409, NOT old large-volume storage (401)
|
||||
# the classifier funnelled it into (ADR-0044).
|
||||
assert simulation is not None
|
||||
assert simulation.heating is not None
|
||||
assert simulation.heating.sap_main_heating_code == 409
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"main_heating_value",
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue