mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Slice S0380.71: Monthly Table 12d/12e cascade for STANDARD-tariff electric mains (ASHP cohort closure)
S0380.65 added the dual-rate Table 12a Grid 1 + Table 12d blend for the electric main_heating CO2 factor, but the STANDARD-tariff branch fell back to the annual Table 12 flat (code 30 = 0.136). Same gap existed on the PE side (no helper at all — line 3756 hardcoded `primary_energy_factor(main_fuel)` = 1.501 annual flat). For the 20-cert STANDARD-tariff ASHP cohort this hid a systematic +2.7 kWh/m² PE under-count on every cert. Per SAP 10.2 Table 12d header (p.195) and Table 12e header (p.196): "Where electricity is the fuel used, the relevant set of factors in the table below should be used to calculate the monthly [CO2 emissions / primary energy] instead the annual average factor given in Table 12." The spec rule applies regardless of tariff — only the high/low split is tariff-dependent. STANDARD-tariff electric mains still require the monthly cascade, just with single-code (30) factors. Cohort closure (PE residual vs lodged EPC PEUI): 9796: -4.18 → -1.36 4800: -3.83 → -0.59 2536: -3.48 → -1.02 ... 20 cluster certs mean: -3.10 → -0.66 Changes: - `_main_heating_co2_factor_kg_per_kwh` — drop STANDARD-tariff fallback; instead apply `_effective_monthly_co2_factor` with `_STANDARD_ELECTRICITY_FUEL_CODE` (30) for STANDARD-tariff electric mains. Dual-rate path unchanged. - NEW `_main_heating_primary_factor(main, tariff, monthly_kwh)` — PE-side mirror covering both STANDARD (single-code 30 monthly cascade) and dual-rate (Table 12a Grid 1 high/low blend over Table 12e high/low codes) paths. - `cert_to_inputs` `space_heating_primary_factor` field — routed through the new helper (was annual `primary_energy_factor`). Tests: - Updated `test_standard_meter_ashp_main_heating_co2_factor_…` (renamed `…_falls_back_to_annual_table_12` → `…_applies_monthly_table_12d_code_30`) to assert the monthly cascade > annual flat by the winter-weighting margin. - Added `test_standard_meter_ashp_main_heating_primary_factor_…` pinning the PE Table 12e analog. - Added `test_dual_meter_ashp_main_heating_primary_factor_…` pinning the dual-rate Table 12a Grid 1 PE blend. - `test_golden_fixtures.py`: 20 ASHP cluster cert pins updated to the post-S0380.71 residuals (mean PE residual -3.10 → -0.66 kWh/m²). Other certs unchanged. Baseline: 544 pass + 9 expected `test_sap_result_pin[000565-*]` cascade-gap fails. Pyright net-zero on every touched file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
fc68fb21f6
commit
3d6cf5ea17
3 changed files with 244 additions and 57 deletions
|
|
@ -1419,35 +1419,50 @@ def _main_heating_co2_factor_kg_per_kwh(
|
|||
tariff: Tariff,
|
||||
main_fuel_monthly_kwh: tuple[float, ...],
|
||||
) -> float:
|
||||
"""SAP 10.2 Table 12a Grid 1 (SH) + Table 12d (p.194) dual-rate
|
||||
monthly CO2 factor for electric mains on off-peak tariffs.
|
||||
"""SAP 10.2 Table 12a Grid 1 (SH) + Table 12d (p.195) dual-rate
|
||||
monthly CO2 factor for electric mains.
|
||||
|
||||
Mirrors `_space_heating_fuel_cost_gbp_per_kwh` on the CO2 side —
|
||||
cert 000565 worksheet line 261 shows the spec calculation:
|
||||
Per Table 12d header (p.195): "Where electricity is the fuel used,
|
||||
the relevant set of factors in the table below should be used to
|
||||
calculate the monthly CO2 emissions instead the annual average
|
||||
factor given in Table 12." Electric mains therefore route through
|
||||
the monthly cascade Σ(F_m × CO2_m) regardless of tariff:
|
||||
|
||||
Main heating CO2 = high_frac × Σ(F_m × CO2^high_m) / Σ F_m × F_total
|
||||
+ (1 - high_frac) × Σ(F_m × CO2^low_m) / Σ F_m × F_total
|
||||
- **STANDARD tariff** — single Table 12d code 30 (standard
|
||||
electricity) monthly factors weighted by the cert's
|
||||
main_fuel_monthly_kwh profile. For an ASHP STANDARD-tariff cert
|
||||
with a winter-peaked load this lands at ~0.151 vs the annual
|
||||
flat 0.136 (Δ ≈ +0.015, ≈ +30 kg/yr CO2 per typical ASHP).
|
||||
- **Dual-rate tariff** (off-peak / 10-hour / 18-hour / etc.) —
|
||||
Table 12a Grid 1 SH high-rate fraction blends Table 12d high-
|
||||
rate code + low-rate code monthly factors over the same profile.
|
||||
For TEN_HOUR + ASHP_OTHER (Grid 1 high_frac=0.6) the worksheet
|
||||
blends code 34 (10h high) and code 33 (10h low) → cert 000565
|
||||
worksheet line 261 lands at 0.1533 kg/kWh (was 0.136 pre-S0380.65).
|
||||
|
||||
blended as a single effective factor × annual fuel for the
|
||||
calculator's energy-rating output. For TEN_HOUR + ASHP_OTHER (Grid 1
|
||||
high_frac=0.6) the worksheet blends Table 12d code 34 (10h high)
|
||||
and code 33 (10h low) over the cert's main_1_fuel_monthly_kwh
|
||||
profile → 0.6 × 0.1581 + 0.4 × 0.1460 = 0.1533 kg/kWh, vs the pre-
|
||||
S0380.65 flat Table 12 code-30 annual factor 0.136 that hid ~579
|
||||
kg/yr of HP CO2 on a winter-peaked load.
|
||||
|
||||
Fallback to `_co2_factor_kg_per_kwh` (annual Table 12) for:
|
||||
- non-electric mains (gas, oil, LPG — pass-through)
|
||||
- STANDARD tariff (no dual-rate routing per RdSAP 10 §12)
|
||||
- mains without a Table 12a Grid 1 row yet (storage heaters, direct-
|
||||
acting electric — TODO mirrors the cost-helper coverage gap)
|
||||
- tariffs without a Table 12d split (EIGHTEEN_HOUR, TWENTY_FOUR_HOUR
|
||||
— both fall through to code 30 monthly factors in the table)
|
||||
Fallback to annual `_co2_factor_kg_per_kwh` for:
|
||||
- non-electric mains (gas, oil, LPG — Table 12d only covers
|
||||
electricity; non-electric uses the annual Table 12 factor per
|
||||
the Table 12d header's "Where electricity is the fuel used"
|
||||
scope restriction)
|
||||
- dual-rate electric mains without a Table 12a Grid 1 row (storage
|
||||
heaters, direct-acting electric — TODO mirrors the cost-helper
|
||||
coverage gap)
|
||||
- dual-rate tariffs without a Table 12d high/low split
|
||||
(EIGHTEEN_HOUR, TWENTY_FOUR_HOUR fall through to single-code 30
|
||||
via the STANDARD branch above)
|
||||
- zero-fuel cases (sum monthly_kwh == 0 → effective factor None;
|
||||
annual factor is the safe degenerate value)
|
||||
"""
|
||||
if not _is_electric_main(main) or tariff is Tariff.STANDARD:
|
||||
if not _is_electric_main(main):
|
||||
return _co2_factor_kg_per_kwh(main)
|
||||
if tariff is Tariff.STANDARD:
|
||||
monthly = _effective_monthly_co2_factor(
|
||||
main_fuel_monthly_kwh, _STANDARD_ELECTRICITY_FUEL_CODE,
|
||||
)
|
||||
if monthly is None:
|
||||
return _co2_factor_kg_per_kwh(main)
|
||||
return monthly
|
||||
system = _table_12a_system_for_main(main)
|
||||
if system is None:
|
||||
return _co2_factor_kg_per_kwh(main)
|
||||
|
|
@ -1466,6 +1481,63 @@ def _main_heating_co2_factor_kg_per_kwh(
|
|||
return high_frac * high_factor + (1.0 - high_frac) * low_factor
|
||||
|
||||
|
||||
def _main_heating_primary_factor(
|
||||
main: Optional[MainHeatingDetail],
|
||||
tariff: Tariff,
|
||||
main_fuel_monthly_kwh: tuple[float, ...],
|
||||
) -> float:
|
||||
"""SAP 10.2 Table 12a Grid 1 (SH) + Table 12e (p.196) primary
|
||||
energy factor for electric mains. PE-side mirror of
|
||||
`_main_heating_co2_factor_kg_per_kwh`.
|
||||
|
||||
Per Table 12e header (p.196): "Where electricity is the fuel used,
|
||||
the relevant set of factors in the table below should be used to
|
||||
calculate the monthly primary energy instead the annual average
|
||||
factor given in Table 12." Electric mains route through monthly
|
||||
Σ(F_m × PE_m) regardless of tariff:
|
||||
|
||||
- **STANDARD tariff** — single Table 12e code 30 monthly factors
|
||||
weighted by the cert's main_fuel_monthly_kwh. For a winter-
|
||||
peaked ASHP load this lands at ~1.57 vs annual flat 1.501
|
||||
(Δ ≈ +0.07, ≈ +2.7 kWh/m² PE per typical ASHP — closes the
|
||||
S0380.70 cohort cluster of 20 STANDARD-tariff ASHPs at PE
|
||||
residual −2.6 to −4.2 kWh/m²).
|
||||
- **Dual-rate tariff** — Table 12a Grid 1 SH high-rate fraction
|
||||
blends Table 12e high-rate / low-rate code monthly factors over
|
||||
the profile. Mirror of the dual-rate CO2 path landed in
|
||||
S0380.65 (cert 000565 ASHP+TEN_HOUR).
|
||||
|
||||
Fallback to annual `primary_energy_factor` for non-electric mains
|
||||
and the same edge cases as the CO2 helper (no Table 12a row,
|
||||
unknown dual-rate codes, zero-fuel)."""
|
||||
fuel = _main_fuel_code(main)
|
||||
if not _is_electric_main(main):
|
||||
return primary_energy_factor(fuel)
|
||||
if tariff is Tariff.STANDARD:
|
||||
monthly = _effective_monthly_pe_factor(
|
||||
main_fuel_monthly_kwh, _STANDARD_ELECTRICITY_FUEL_CODE,
|
||||
)
|
||||
if monthly is None:
|
||||
return primary_energy_factor(fuel)
|
||||
return monthly
|
||||
system = _table_12a_system_for_main(main)
|
||||
if system is None:
|
||||
return primary_energy_factor(fuel)
|
||||
try:
|
||||
high_frac = space_heating_high_rate_fraction(system, tariff)
|
||||
except NotImplementedError:
|
||||
return primary_energy_factor(fuel)
|
||||
codes = _TARIFF_HIGH_LOW_FUEL_CODES_TABLE_12.get(tariff)
|
||||
if codes is None:
|
||||
return primary_energy_factor(fuel)
|
||||
high_code, low_code = codes
|
||||
high_factor = _effective_monthly_pe_factor(main_fuel_monthly_kwh, high_code)
|
||||
low_factor = _effective_monthly_pe_factor(main_fuel_monthly_kwh, low_code)
|
||||
if high_factor is None or low_factor is None:
|
||||
return primary_energy_factor(fuel)
|
||||
return high_frac * high_factor + (1.0 - high_frac) * low_factor
|
||||
|
||||
|
||||
def _secondary_fuel_code(epc: EpcPropertyData) -> int:
|
||||
"""SAP 10.2 secondary fuel code, resolved through the API mapper's
|
||||
Appendix M Table 4a spec-fuel routing. When no `secondary_fuel_type`
|
||||
|
|
@ -3681,7 +3753,10 @@ def cert_to_inputs(
|
|||
secondary_heating_fuel_cost_gbp_per_kwh=_secondary_fuel_cost_gbp_per_kwh(
|
||||
epc.sap_heating, main, epc.sap_energy_source.meter_type, prices
|
||||
),
|
||||
space_heating_primary_factor=primary_energy_factor(main_fuel),
|
||||
space_heating_primary_factor=_main_heating_primary_factor(
|
||||
main, _rdsap_tariff(epc),
|
||||
energy_requirements_result.main_1_fuel_monthly_kwh,
|
||||
),
|
||||
hot_water_primary_factor=primary_energy_factor(
|
||||
_water_heating_fuel_code(epc)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -903,11 +903,18 @@ def test_dual_meter_ashp_main_heating_co2_factor_applies_table_12a_grid_1_split(
|
|||
)
|
||||
|
||||
|
||||
def test_standard_meter_ashp_main_heating_co2_factor_falls_back_to_annual_table_12() -> None:
|
||||
# Arrange — same ASHP, but meter_type=2 (Standard) → no §12
|
||||
# routing → no Table 12a Grid 1 split → annual Table 12 code-30
|
||||
# factor 0.136 (pass-through). Pre- and post-S0380.65 behave
|
||||
# identically for STANDARD tariff.
|
||||
def test_standard_meter_ashp_main_heating_co2_factor_applies_monthly_table_12d_code_30() -> None:
|
||||
# Arrange — same ASHP as the dual-rate test but meter_type=2
|
||||
# (Standard) → no Table 12a Grid 1 high/low split, but Table 12d
|
||||
# header (p.195) still mandates the monthly cascade for ALL
|
||||
# electric mains regardless of tariff: "Where electricity is the
|
||||
# fuel used, the relevant set of factors in the table below
|
||||
# should be used … instead the annual average factor given in
|
||||
# Table 12." Pre-S0380.71 the helper fell back to annual flat
|
||||
# 0.136 on STANDARD tariff — that masked ~+0.015 kg/kWh on the
|
||||
# ASHP cohort (~30 kg/yr per cert). S0380.71 drops the annual
|
||||
# fallback and applies monthly Table 12d code 30 (standard
|
||||
# electricity) weighted by main_1_fuel_monthly_kwh.
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=3,
|
||||
|
|
@ -938,8 +945,113 @@ def test_standard_meter_ashp_main_heating_co2_factor_falls_back_to_annual_table_
|
|||
# Act
|
||||
inputs = cert_to_inputs(epc)
|
||||
|
||||
# Assert — annual flat 0.136 (Table 12 code 30).
|
||||
assert inputs.main_heating_co2_factor_kg_per_kwh == 0.136
|
||||
# Assert — monthly Table 12d cascade weighted by a winter-peaked
|
||||
# HP load lands above the annual flat 0.136 (winter months 0.163
|
||||
# > summer 0.111). Tight bound: must be strictly greater than
|
||||
# annual flat by at least 0.005 (the winter weighting margin).
|
||||
factor = inputs.main_heating_co2_factor_kg_per_kwh
|
||||
assert factor is not None and factor > 0.136 + 0.005, (
|
||||
f"expected monthly cascade > 0.141; got {factor}"
|
||||
)
|
||||
|
||||
|
||||
def test_standard_meter_ashp_main_heating_primary_factor_applies_monthly_table_12e_code_30() -> None:
|
||||
# Arrange — same ASHP STANDARD-tariff cert as above. Table 12e
|
||||
# header (p.196) mirrors the Table 12d rubric: "Where electricity
|
||||
# is the fuel used, the relevant set of factors in the table
|
||||
# below should be used to calculate the monthly primary energy
|
||||
# instead the annual average factor given in Table 12." Pre-
|
||||
# S0380.71 the cascade hardcoded `primary_energy_factor(main_fuel)`
|
||||
# = 1.501 annual flat at cert_to_inputs.py:3756. S0380.71 routes
|
||||
# `space_heating_primary_factor` through `_main_heating_primary_
|
||||
# factor` so monthly Table 12e code 30 cascade applies for
|
||||
# STANDARD-tariff electric mains too — closes the 20-cert ASHP
|
||||
# cohort cluster from PE residual −2.6 to −4.2 kWh/m² (per-cert
|
||||
# +2.7 kWh/m² typical, sample cert 9796-3058-6205-0346-9200
|
||||
# closes −4.18 → −1.48).
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=3,
|
||||
region_code="1",
|
||||
dwelling_type="Detached bungalow",
|
||||
sap_building_parts=[
|
||||
make_building_part(
|
||||
floor_dimensions=[
|
||||
make_floor_dimension(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2, floor=0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
sap_heating=make_sap_heating(
|
||||
water_heating_fuel=29,
|
||||
main_heating_details=[
|
||||
MainHeatingDetail(
|
||||
has_fghrs=False, main_fuel_type=29, heat_emitter_type=1,
|
||||
emitter_temperature=1, main_heating_control=2106,
|
||||
main_heating_category=4, sap_main_heating_code=224,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
epc.sap_energy_source.meter_type = 2 # type: ignore[assignment] # Standard
|
||||
|
||||
# Act
|
||||
inputs = cert_to_inputs(epc)
|
||||
|
||||
# Assert — monthly Table 12e cascade weighted by a winter-peaked
|
||||
# HP load lands above the annual flat 1.501 (winter PE 1.602 >
|
||||
# summer 1.410). Tight bound: > 1.501 + 0.04 (winter weighting
|
||||
# margin for a meaningful HP load).
|
||||
factor = inputs.space_heating_primary_factor
|
||||
assert factor is not None and factor > 1.501 + 0.04, (
|
||||
f"expected monthly Table 12e cascade > 1.541; got {factor}"
|
||||
)
|
||||
|
||||
|
||||
def test_dual_meter_ashp_main_heating_primary_factor_applies_table_12a_grid_1_split() -> None:
|
||||
# Arrange — RdSAP 10 §12 page 62 Rule 1: HP without PCDB record →
|
||||
# TEN_HOUR tariff. Table 12a Grid 1 (SH) ASHP_OTHER + TEN_HOUR =
|
||||
# 0.6 high-rate fraction. Table 12e (PE) high-rate code 34 (10h
|
||||
# high) + low-rate code 33 (10h low) monthly factors blend by
|
||||
# main_1_fuel_monthly_kwh profile, mirroring the dual-rate CO2
|
||||
# path landed in S0380.65. The blend lands above annual flat
|
||||
# 1.501 by the high/low Table 12e differential.
|
||||
epc = make_minimal_sap10_epc(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2,
|
||||
habitable_rooms_count=3,
|
||||
region_code="1",
|
||||
dwelling_type="Detached bungalow",
|
||||
sap_building_parts=[
|
||||
make_building_part(
|
||||
floor_dimensions=[
|
||||
make_floor_dimension(
|
||||
total_floor_area_m2=_TYPICAL_TFA_M2, floor=0,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
sap_heating=make_sap_heating(
|
||||
water_heating_fuel=29,
|
||||
main_heating_details=[
|
||||
MainHeatingDetail(
|
||||
has_fghrs=False, main_fuel_type=29, heat_emitter_type=1,
|
||||
emitter_temperature=1, main_heating_control=2106,
|
||||
main_heating_category=4, sap_main_heating_code=224,
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
epc.sap_energy_source.meter_type = 1 # type: ignore[assignment] # Dual → TEN_HOUR
|
||||
|
||||
# Act
|
||||
inputs = cert_to_inputs(epc)
|
||||
|
||||
# Assert — dual-rate Table 12e blend above annual flat 1.501.
|
||||
factor = inputs.space_heating_primary_factor
|
||||
assert factor is not None and factor > 1.501 + 0.005, (
|
||||
f"expected dual-rate Table 12e blend > 1.506; got {factor}"
|
||||
)
|
||||
|
||||
|
||||
def test_house_coal_secondary_routes_to_annual_table_12_co2_and_pe_factors() -> None:
|
||||
|
|
|
|||
|
|
@ -261,8 +261,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="0380-2471-3250-2596-8761",
|
||||
actual_sap=89,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-2.9633,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0548,
|
||||
expected_pe_resid_kwh_per_m2=-0.1802,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0111,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, semi-detached bungalow "
|
||||
"TFA 60.43 age D, PV 3 kWp + 5 kWh battery. Worksheet SAP "
|
||||
|
|
@ -281,8 +281,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="0350-2968-2650-2796-5255",
|
||||
actual_sap=84,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-2.8973,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0864,
|
||||
expected_pe_resid_kwh_per_m2=-0.6985,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0345,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, ASHP cohort cert with "
|
||||
"PV + 5 kWh battery. Worksheet SAP 84.1367. Slice S0380.50 "
|
||||
|
|
@ -293,8 +293,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="2225-3062-8205-2856-7204",
|
||||
actual_sap=89,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-3.5393,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0726,
|
||||
expected_pe_resid_kwh_per_m2=-0.9922,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0179,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, ASHP cohort cert with "
|
||||
"PV + 5 kWh battery. Worksheet SAP 88.7921. Slice S0380.50 "
|
||||
|
|
@ -305,8 +305,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="2636-0525-2600-0401-2296",
|
||||
actual_sap=86,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-3.2775,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0601,
|
||||
expected_pe_resid_kwh_per_m2=-1.0590,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0126,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, ASHP cohort cert with "
|
||||
"PV + 5 kWh battery + 3.74 m² cantilever + 12.76 m² alt wall. "
|
||||
|
|
@ -318,8 +318,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="3800-8515-0922-3398-3563",
|
||||
actual_sap=86,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-3.1623,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0165,
|
||||
expected_pe_resid_kwh_per_m2=-0.7108,
|
||||
expected_co2_resid_tonnes_per_yr=+0.0354,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, ASHP cohort cert with "
|
||||
"PV + 5 kWh battery. Worksheet SAP 86.1458. Slice S0380.50 "
|
||||
|
|
@ -330,8 +330,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="9285-3062-0205-7766-7200",
|
||||
actual_sap=84,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-2.7361,
|
||||
expected_co2_resid_tonnes_per_yr=-0.1002,
|
||||
expected_pe_resid_kwh_per_m2=-0.5156,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0505,
|
||||
notes=(
|
||||
"Mitsubishi PUZ-WM50VHA PCDB 104568, ASHP cohort cert with "
|
||||
"PV + 5 kWh battery. Worksheet SAP 84.1369. Slice S0380.50 "
|
||||
|
|
@ -342,8 +342,8 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
cert_number="9418-3062-8205-3566-7200",
|
||||
actual_sap=85,
|
||||
expected_sap_resid=+0,
|
||||
expected_pe_resid_kwh_per_m2=-2.8890,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0483,
|
||||
expected_pe_resid_kwh_per_m2=-1.0927,
|
||||
expected_co2_resid_tonnes_per_yr=-0.0136,
|
||||
notes=(
|
||||
"Daikin Altherma EDLQ05CAV3 PCDB 102421 (heating_duration "
|
||||
"code '24' — continuous, all days at Th) + 5 kWh battery. "
|
||||
|
|
@ -368,13 +368,13 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
# `sap worksheets/Additional data with api/`.
|
||||
# ------------------------------------------------------------------
|
||||
_GoldenExpectation(cert_number="0036-6325-1100-0063-1226", actual_sap=63, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.4019, expected_co2_resid_tonnes_per_yr=+0.0255, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0100-5141-0522-4696-3463", actual_sap=86, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-2.3311, expected_co2_resid_tonnes_per_yr=-0.0314, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0100-5141-0522-4696-3463", actual_sap=86, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.0197, expected_co2_resid_tonnes_per_yr=+0.0223, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0200-3155-0122-2602-3563", actual_sap=81, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.9879, expected_co2_resid_tonnes_per_yr=-0.0097, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0300-2403-2650-2206-0235", actual_sap=77, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.5118, expected_co2_resid_tonnes_per_yr=+0.0442, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0310-2763-5450-2506-3501", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.4387, expected_co2_resid_tonnes_per_yr=+0.0149, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0320-2126-2150-2326-6161", actual_sap=72, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.2060, expected_co2_resid_tonnes_per_yr=+0.0128, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0320-2756-8640-2296-1101", actual_sap=90, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-2.9435, expected_co2_resid_tonnes_per_yr=-0.0363, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0330-2257-3640-2196-3145", actual_sap=85, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-2.6609, expected_co2_resid_tonnes_per_yr=-0.0218, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0320-2756-8640-2296-1101", actual_sap=90, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.7813, expected_co2_resid_tonnes_per_yr=+0.0221, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0330-2257-3640-2196-3145", actual_sap=85, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.2015, expected_co2_resid_tonnes_per_yr=+0.0298, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0360-2266-5650-2106-8285", actual_sap=80, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.2223, expected_co2_resid_tonnes_per_yr=-0.0171, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0380-2530-6150-2326-4161", actual_sap=66, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.0893, expected_co2_resid_tonnes_per_yr=-0.0315, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="0390-2066-4250-2026-4555", actual_sap=65, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.2522, expected_co2_resid_tonnes_per_yr=+0.0005, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
|
|
@ -396,25 +396,25 @@ _EXPECTATIONS: tuple[_GoldenExpectation, ...] = (
|
|||
# / CO2 +0.005 (lodged values are integer-rounded; rounding noise).
|
||||
_GoldenExpectation(cert_number="2102-3018-0205-7886-5204", actual_sap=64, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.1961, expected_co2_resid_tonnes_per_yr=+0.0048, notes="Cohort-2 baseline pin. House coal secondary — S0380.70 routed CO2/PE through `secondary_fuel_type` per SAP 10.2 Table 12d/12e headers, closed PE +20.36 → +0.20 and CO2 -0.79 → +0.005 (lodged values integer-rounded)."),
|
||||
_GoldenExpectation(cert_number="2130-3018-4205-4686-5204", actual_sap=71, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.4083, expected_co2_resid_tonnes_per_yr=-0.0357, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2336-3124-3600-0517-1292", actual_sap=83, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-2.7961, expected_co2_resid_tonnes_per_yr=-0.0981, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2536-2525-0600-0788-2292", actual_sap=80, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.4839, expected_co2_resid_tonnes_per_yr=-0.0582, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2336-3124-3600-0517-1292", actual_sap=83, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.3366, expected_co2_resid_tonnes_per_yr=-0.0465, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2536-2525-0600-0788-2292", actual_sap=80, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-1.0235, expected_co2_resid_tonnes_per_yr=-0.0290, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2590-3025-7205-9066-0200", actual_sap=66, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.1309, expected_co2_resid_tonnes_per_yr=-0.0036, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2699-3025-5205-8066-0200", actual_sap=69, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.4755, expected_co2_resid_tonnes_per_yr=-0.0016, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2800-7999-0322-4594-3563", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.4448, expected_co2_resid_tonnes_per_yr=-0.0473, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="2800-7999-0322-4594-3563", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.2402, expected_co2_resid_tonnes_per_yr=-0.0082, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="3136-7925-4500-0246-6202", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.2521, expected_co2_resid_tonnes_per_yr=-0.0486, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="3336-2825-9400-0512-8292", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.4645, expected_co2_resid_tonnes_per_yr=-0.0877, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="4536-5424-8600-0109-1226", actual_sap=82, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.2123, expected_co2_resid_tonnes_per_yr=-0.0684, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="3336-2825-9400-0512-8292", actual_sap=78, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.5933, expected_co2_resid_tonnes_per_yr=-0.0453, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="4536-5424-8600-0109-1226", actual_sap=82, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.5517, expected_co2_resid_tonnes_per_yr=-0.0106, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="4536-8325-3100-0409-1222", actual_sap=66, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.2794, expected_co2_resid_tonnes_per_yr=+0.0093, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="4800-3992-0422-0599-3563", actual_sap=87, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.8280, expected_co2_resid_tonnes_per_yr=-0.0848, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="4800-3992-0422-0599-3563", actual_sap=87, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.5884, expected_co2_resid_tonnes_per_yr=-0.0453, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="6835-3920-2509-0933-5226", actual_sap=80, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.1246, expected_co2_resid_tonnes_per_yr=-0.0238, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="7700-3362-0922-7022-3563", actual_sap=63, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.4141, expected_co2_resid_tonnes_per_yr=+0.0216, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="7800-1501-0922-7127-3563", actual_sap=65, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.0594, expected_co2_resid_tonnes_per_yr=+0.0440, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="7836-3125-0600-0526-2202", actual_sap=80, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.3469, expected_co2_resid_tonnes_per_yr=+0.0164, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9036-0824-3500-0420-8222", actual_sap=84, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.0984, expected_co2_resid_tonnes_per_yr=-0.0220, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9370-3060-1205-3546-4204", actual_sap=88, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-2.7546, expected_co2_resid_tonnes_per_yr=-0.0749, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9036-0824-3500-0420-8222", actual_sap=84, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.7641, expected_co2_resid_tonnes_per_yr=+0.0284, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9370-3060-1205-3546-4204", actual_sap=88, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.4107, expected_co2_resid_tonnes_per_yr=-0.0115, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9380-2957-7490-2595-3141", actual_sap=75, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=+0.4794, expected_co2_resid_tonnes_per_yr=-0.0245, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9421-3045-3205-1646-6200", actual_sap=87, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-3.3687, expected_co2_resid_tonnes_per_yr=-0.0432, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9796-3058-6205-0346-9200", actual_sap=90, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-4.1762, expected_co2_resid_tonnes_per_yr=-0.0391, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9421-3045-3205-1646-6200", actual_sap=87, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-1.0893, expected_co2_resid_tonnes_per_yr=-0.0096, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9796-3058-6205-0346-9200", actual_sap=90, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-1.3613, expected_co2_resid_tonnes_per_yr=-0.0048, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
_GoldenExpectation(cert_number="9836-7525-9500-0575-1202", actual_sap=75, expected_sap_resid=+0, expected_pe_resid_kwh_per_m2=-0.5524, expected_co2_resid_tonnes_per_yr=+0.0010, notes="Cohort-2 baseline pin captured by S0380.69."),
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue