mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
feat(tariff): complete §12 Unknown-meter clause — GSHP/WSHP main triggers off-peak (RdSAP 10 PDF p.62)
Closes the follow-up from 22fe4f41. RdSAP 10 §12's third Unknown-meter
exception bullet — "main heating is ground source or water source heat pump" —
was unimplemented. Add `_GROUND_OR_WATER_SOURCE_HEAT_PUMP_CODES` (Table 4a,
SAP 10.2 PDF p.176-177: ground 211/215/221/225 + warm-air 521/525; water
213/216/223/226 + warm-air 523/526) to the Unknown-meter off-peak triggers;
once dual, Rules 1-4 (Rule 3) resolve it to 10-hour.
AIR-source heat pumps (214/217/224/227, 524/527) are deliberately EXCLUDED —
the spec names only ground/water source. Verified the only Unknown-meter heat
pumps in the corpus are "3/10 Bedford House" (main 214 = AIR source), which
correctly KEEP STANDARD. 0 corpus certs carry a GSHP/WSHP on an Unknown meter,
so this is a spec-completeness forward guard (gauge unchanged 72.5% / 0.789),
same family as the Scotland-J wall / rafters-M roof 0-impact spec fixes.
Coverage gap noted in-code: a database-index heat pump without a 211/213-style
SAP code can't have its source type read from the code alone (rare).
Spec-pinned (test_unknown_meter_ground_or_water_source_heat_pump_triggers_off_
peak). Gates green: corpus 72.5%/0.789, batch worksheet 0 raised/0 diverge,
suite 2989 passed (2 known pre-existing fails). pyright not installed locally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4f208f472c
commit
fd0530159f
2 changed files with 40 additions and 1 deletions
|
|
@ -262,6 +262,19 @@ _RULE_3_TEN_HOUR_CODES: Final[frozenset[int]] = frozenset(
|
|||
+ [691, 692, 693, 694, 699] # electric room heaters (Table 4a)
|
||||
)
|
||||
|
||||
# §12 Unknown-meter exception: "main heating is ground source or water source
|
||||
# heat pump" makes the dwelling dual even though the same heat pump on a Single
|
||||
# meter stays standard. This is the GROUND/WATER-source subset of Table 4a
|
||||
# (SAP 10.2 PDF p.176-177): ground 211/215/221/225 + warm-air 521/525, water
|
||||
# 213/216/223/226 + warm-air 523/526. AIR-source (214/217/224/227, 524/527) is
|
||||
# DELIBERATELY EXCLUDED — the spec names only ground/water source. A heat pump
|
||||
# lodged via a PCDB database index without one of these SAP codes can't have
|
||||
# its source type read from the code alone (coverage gap: rare, 0 corpus certs).
|
||||
_GROUND_OR_WATER_SOURCE_HEAT_PUMP_CODES: Final[frozenset[int]] = frozenset(
|
||||
{211, 215, 221, 225, 521, 525} # ground source (radiator + warm-air)
|
||||
| {213, 216, 223, 226, 523, 526} # water source (radiator + warm-air)
|
||||
)
|
||||
|
||||
|
||||
def _meter_is_unknown(meter_type: object) -> bool:
|
||||
"""True when the meter is the RdSAP "Unknown" sentinel (code 3 / the
|
||||
|
|
@ -367,11 +380,18 @@ def rdsap_tariff_for_cert(
|
|||
# immersion); every other Unknown+dual-immersion cert already has a
|
||||
# storage main (Rule 2). Single-immersion 691 certs (Flat 7, Flat 2) and
|
||||
# whc-909 instantaneous certs correctly STAY standard — they carry no
|
||||
# text-box off-peak system. (GSHP/WSHP-main trigger: separate follow-up.)
|
||||
# text-box off-peak system. The §12 third exception bullet ("main heating
|
||||
# is ground source or water source heat pump") is the
|
||||
# `_GROUND_OR_WATER_SOURCE_HEAT_PUMP_CODES` check — AIR-source heat pumps
|
||||
# (214/224 etc.) are NOT a trigger and stay standard (e.g. corpus certs
|
||||
# "3/10 Bedford House", main 214 ASHP on Unknown meters — verified 2026-06-
|
||||
# 23 they keep STANDARD). No corpus cert carries a GSHP/WSHP on an Unknown
|
||||
# meter, so this trigger is a spec-completeness forward guard (0 impact).
|
||||
if _meter_is_unknown(meter_type):
|
||||
off_peak_evidence = (
|
||||
bool(main_codes & _RULE_1_CPSU_CODES)
|
||||
or bool(main_codes & _RULE_2_STORAGE_CODES)
|
||||
or bool(main_codes & _GROUND_OR_WATER_SOURCE_HEAT_PUMP_CODES)
|
||||
or water_is_off_peak_dual_immersion
|
||||
)
|
||||
if off_peak_evidence:
|
||||
|
|
|
|||
|
|
@ -106,6 +106,25 @@ def test_unknown_meter_dual_electric_immersion_triggers_off_peak_via_rules() ->
|
|||
) is Tariff.STANDARD
|
||||
|
||||
|
||||
def test_unknown_meter_ground_or_water_source_heat_pump_triggers_off_peak() -> None:
|
||||
# Arrange — RdSAP 10 §12 (PDF p.62) third Unknown-meter exception bullet:
|
||||
# "main heating is ground source or water source heat pump." Per SAP 10.2
|
||||
# Table 4a (PDF p.176-177) ground source = 211/215/221/225 (+ warm-air
|
||||
# 521/525), water source = 213/216/223/226 (+ warm-air 523/526); AIR
|
||||
# source (214/224 etc.) is NOT named, so it stays standard. Once the GSHP/
|
||||
# WSHP makes the meter dual, Rules 1-4 (Rule 3, heat pump 211-224) → 10h.
|
||||
# 0 corpus certs carry a GSHP/WSHP on an Unknown meter (the only Unknown-
|
||||
# meter HPs are 3/10 Bedford House, main 214 = AIR source) — this is a
|
||||
# spec-completeness forward guard.
|
||||
|
||||
# Act / Assert — ground/water source → 10-hour; air source → STANDARD.
|
||||
assert rdsap_tariff_for_cert(3, main_1_sap_code=211) is Tariff.TEN_HOUR
|
||||
assert rdsap_tariff_for_cert(3, main_1_sap_code=213) is Tariff.TEN_HOUR
|
||||
assert rdsap_tariff_for_cert(3, main_1_sap_code=521) is Tariff.TEN_HOUR
|
||||
assert rdsap_tariff_for_cert(3, main_1_sap_code=214) is Tariff.STANDARD
|
||||
assert rdsap_tariff_for_cert(3, main_1_sap_code=224) is Tariff.STANDARD
|
||||
|
||||
|
||||
def test_unknown_meter_with_non_electric_main_stays_standard() -> None:
|
||||
# Arrange — an "Unknown" meter on a GAS-heated dwelling (SAP 102) has
|
||||
# no off-peak evidence, so it must NOT pick up the Rule-4 Dual default
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue