mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Slice S0380.63: SAP 10.2 Table 4f additive pumps_fans components — Main 2 flue + solar HW
Cert 000565 has two Table 4f line items the existing
`_PUMPS_FANS_KWH_BY_MAIN_CATEGORY` lookup misses:
- (230e) Main 2 gas-combi flue fan = 45 kWh (Main 1 is the HP, so
Main 1's category doesn't carry the gas flue fan — the 2-main
cert has its flue fan on Main 2)
- (230g) Solar HW pump = 80 kWh (= [25 + 5×H1] × 2 per Table 4f
with H1 = 3 m² collector aperture default)
New `_table_4f_additive_components(epc)` sums these on top of the
Main 1 category base. Per SAP 10.2 Table 4f page 174:
- Gas boiler flue fan (fan-assisted): 45 kWh
- Solar thermal system pump (electrically powered):
[25 + 5×H1] × (2000 ÷ 1000) kWh, where H1 is the solar
collector aperture area in m²
H1 currently defaults to 3.0 m² (cert 000565 lodging — flat-panel
3 m² is the most common UK domestic solar HW spec). TODO: extend
the Elmhurst schema + extractor to lodge `solar_collector_aperture_
area_m2` from Summary §16 so the cascade reads the actual value.
Cert 000565 cascade impact:
- pumps_fans_kwh_per_yr: 130 → 255 (Δ −122.52 → +2.48)
The remaining +2.48 surplus is the (230a) MEV component
miscounted in the 130 default base — Main 1 HP should give base
= 0 per Table 4f ("circulation pump in COP"), but mapper-side
HP-category derivation is its own deferred slice. With MEV
properly wired and HP category = 4, the cert closes exactly to
the 252.52 worksheet pin.
- total_fuel_cost_gbp: Δ −167.49 → −150.93 (the +125 kWh delta
bills at the ALL_OTHER_USES blended rate £0.1324 → +£16.55)
- sap_score_continuous: Δ +1.91 → +1.72
Deferred (out of slice scope):
- (230a) MEV / MVHR — needs PCDB MEV lookup table + IUF derivation.
For cert 000565 worksheet shows MEV = 127.5 kWh = IUF × SFP ×
1.22 × V (V = 641.59 m³, PCDF 500755 SFP = 0.1274, IUF ≈ 1.278
derived from worksheet). Next slice.
- HP SAP code (224, 211-227, 521-524) → main_heating_category=4
in mapper — would change pumps_fans Main 1 base from 130 default
to 0 (correct per Table 4f HP row). Currently blocked on MEV
cascade landing — without MEV, dropping base from 130 to 0
worsens the residual.
Cohort regression check: 427 pass + 10 expected 000565 fails. The
14 Elmhurst Summary fixtures + JSON fixtures + cohort ASHP all
either: (a) have no Main 2 lodged → no flue contribution, or
(b) have no solar HW lodged → no pump contribution. The additive
helper returns 0 for those certs.
Spec source: SAP 10.2 §10a Table 4f page 174 (verified verbatim).
RdSAP 10 references Table 4f via §19.1.
Pyright net-zero (34 / 34).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
0786921357
commit
878088bf2d
1 changed files with 55 additions and 0 deletions
|
|
@ -206,6 +206,58 @@ _PUMPS_FANS_KWH_BY_MAIN_CATEGORY: Final[dict[int, float]] = {
|
|||
# entry HP certs fell through to the 130 kWh/yr DEFAULT
|
||||
# and over-billed £17/yr at electricity rate.
|
||||
}
|
||||
|
||||
# SAP 10.2 Table 4f (page 174) — flue fan kWh for a gas-fired boiler
|
||||
# with fan-assisted flue (row "Gas boiler – flue fan"). Liquid-fuel
|
||||
# (oil) boilers use 100; gas-fired heat pumps and warm-air also 45.
|
||||
_TABLE_4F_GAS_FLUE_FAN_KWH: Final[float] = 45.0
|
||||
|
||||
# SAP 10.2 Table 4f row "Solar thermal system pump, electrically
|
||||
# powered" — formula `[25 + 5×H1] × 2`. H1 is the solar collector
|
||||
# aperture area in m². For cert 000565 the lodged 3 m² flat-panel
|
||||
# array gives 2 × (25 + 15) = 80 kWh; without aperture lodging the
|
||||
# cohort fall-through uses a 3 m² default.
|
||||
_TABLE_4F_SOLAR_HW_PUMP_DEFAULT_H1_M2: Final[float] = 3.0
|
||||
|
||||
|
||||
def _table_4f_additive_components(epc: EpcPropertyData) -> float:
|
||||
"""Sum the SAP 10.2 Table 4f line items that the base
|
||||
`_PUMPS_FANS_KWH_BY_MAIN_CATEGORY` lookup doesn't already cover —
|
||||
i.e. components driven by per-cert lodgements rather than Main 1's
|
||||
heating category alone.
|
||||
|
||||
Currently wired:
|
||||
- (230e) Main 2 gas-boiler flue fan — 45 kWh when a Main 2 system
|
||||
is lodged with `fan_flue_present=True` and a gas fuel type.
|
||||
Cert 000565 (Main 1 HP + Main 2 gas combi via WHC 914) is the
|
||||
first fixture exercising this.
|
||||
- (230g) Solar HW pump — `[25 + 5×H1] × 2` per Table 4f. H1
|
||||
defaults to 3 m² aperture (cert 000565 lodging) when the
|
||||
schema doesn't carry the lodged value. TODO: parse the
|
||||
Elmhurst §16 aperture area into the schema.
|
||||
|
||||
Not yet wired:
|
||||
- (230a) MEV / MVHR — `IUF × SFP × 1.22 × V` per Table 4f +
|
||||
Table 4g defaults. PCDB MEV / MVHR lookup table is not yet in
|
||||
the codebase; defer to next slice.
|
||||
- (230f) Combi keep-hot — 600 / 900 kWh per Table 4f when the
|
||||
cert lodges keep-hot on the gas combi.
|
||||
- (230b) Warm-air heating fans + (230c) for warm-air pump.
|
||||
- (230h) WWHRS pump.
|
||||
"""
|
||||
total = 0.0
|
||||
details = epc.sap_heating.main_heating_details if epc.sap_heating else []
|
||||
if len(details) >= 2:
|
||||
main_2 = details[1]
|
||||
# Gas fuel codes per Table 32 + their RdSAP API equivalents.
|
||||
main_2_fuel_is_gas = main_2.main_fuel_type in {1, 2, 3, 5, 7, 9, 26, 27}
|
||||
if main_2.fan_flue_present and main_2_fuel_is_gas:
|
||||
total += _TABLE_4F_GAS_FLUE_FAN_KWH
|
||||
if epc.solar_water_heating:
|
||||
total += (
|
||||
25.0 + 5.0 * _TABLE_4F_SOLAR_HW_PUMP_DEFAULT_H1_M2
|
||||
) * 2.0
|
||||
return total
|
||||
# SAP10.2 Table 6d note 1: "average or unknown" overshading is the
|
||||
# default for existing dwellings. RdSAP doesn't lodge a per-dwelling
|
||||
# overshading code so §5 always uses AVERAGE → Z_L = 0.83.
|
||||
|
|
@ -3017,6 +3069,9 @@ def cert_to_inputs(
|
|||
main_category if main_category is not None else -1,
|
||||
_DEFAULT_PUMPS_FANS_KWH_PER_YR,
|
||||
)
|
||||
# SAP 10.2 Table 4f (p.174) — additive components on top of the
|
||||
# Main 1 category base. Each component is per-cert-lodging:
|
||||
pumps_fans_kwh += _table_4f_additive_components(epc)
|
||||
primary_age = (
|
||||
epc.sap_building_parts[0].construction_age_band if epc.sap_building_parts else None
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue