mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
P2.4: correct table_12 CO2 factors to SAP 10.2 (14-03-2025); P2 complete
ADR-0010 §1: the file was a SAP 10.2 prices + SAP 10.3 CO2 hybrid,
incorrectly labelled "SAP 10.3" throughout. Realigns the CO2 column
to SAP 10.2 PDF page 189 — the table the calculator's Validation
Cohort certs were emitted against.
CO2 corrections (kg CO2e per kWh delivered):
- Mains gas: 0.214 → 0.210
- LPG (2, 3, 5, 9): 0.24 → 0.241 (precision restore)
- Biogas (7): 0.029 → 0.024
- HVO (71): 0.041 → 0.036
- FAME (73): 0.058 → 0.018
- B30K (75): 0.226 → 0.214
- Bioethanol (76): 0.072 → 0.105
- Coal / anthracite (11, 15): 0.398 → 0.395
- Smokeless (12): 0.398 → 0.366
- Wood logs (20): 0.023 → 0.028
- Wood pellets (22, 23): 0.048 → 0.053
- Wood chips (21): 0.018 → 0.023
- Dual fuel (10): 0.084 → 0.087
- Standard electricity (all grid tariffs):
0.086 → 0.136 (biggest swing — the
annual-average factor changes between
SAP 10.2 and 10.3 by -37%)
- Heat-network variants realigned to match their parent fuels
- _DEFAULT_CO2_KG_PER_KWH: 0.214 → 0.210
Header docstring rewritten:
- Re-labelled "SAP 10.2 (14-03-2025 amendment)"
- Dropped the misleading "+25% shift from SAP 10.2" block — those
13.19 → 16.49 figures were SAP 10.1 → SAP 10.2, not 10.2 → 10.3
- Notes the SAP 10.3 re-pointing trigger (corpus migration)
New test file packages/domain/src/domain/sap/tests/test_table_12.py
locks SAP 10.2 values for mains gas, standard electricity, 7h low,
24h heating, bulk LPG, heating oil, default, plus sanity checks
on the unchanged unit price + PE factor columns.
All 161 SAP + ml_training_data tests pass. CO2 corrections don't
affect SAP score (cost-driven) or PEUI (PEF-driven), so golden
fixtures and probe pinned values remain green.
P2 complete:
P2.1 (ac1aa56a) — probe swap to spec prices
P2.2 (28e9dd38) — golden fixtures migrated to loose smoke test
P2.3 (cd6ac9b1) — cert-cal file deleted
P2.4 (this) — CO2 factors corrected
Next: P1 (parquet re-extract with inspection_date) + P3 (Validation
Cohort filter) unblock the cohort-clean probe baseline.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
cd6ac9b16d
commit
62289ec6f6
2 changed files with 112 additions and 29 deletions
|
|
@ -1,17 +1,17 @@
|
|||
"""SAP 10.3 Table 12 — fuel prices, CO2 emission factors, primary energy
|
||||
factors.
|
||||
"""SAP 10.2 (14-03-2025 amendment) Table 12 — fuel prices, CO2 emission
|
||||
factors, primary energy factors.
|
||||
|
||||
Sourced verbatim from BRE, *The Government's Standard Assessment
|
||||
Procedure for Energy Rating of Dwellings, SAP 10.3* (13-01-2026), page
|
||||
190 (Table 12). Keys are the SAP 10.2/10.3 fuel code numbers — they
|
||||
remained stable across the 10.2 → 10.3 jump, only the values changed.
|
||||
Procedure for Energy Rating of Dwellings, SAP 10.2* (14-03-2025), page
|
||||
189 (Table 12). Keys are the SAP 10.2/10.3 fuel code numbers — they
|
||||
remained stable across the 10.2 → 10.3 jump.
|
||||
|
||||
Notable shifts from SAP 10.2 (used by `domain.ml.sap_efficiencies`):
|
||||
- Standard electricity: 13.19 → 16.49 p/kWh (+25%)
|
||||
- 7h low (off-peak): 5.50 → 9.40 p/kWh (+71%)
|
||||
- 24h heating: 6.61 → 14.04 p/kWh (+112%)
|
||||
- Mains gas: 3.48 → 3.64 p/kWh (+5%)
|
||||
- Grid electricity CO2: 0.136 → 0.086 kg/kWh (-37%)
|
||||
The calculator targets SAP 10.2 per ADR-0010 because no SAP-10.3-lodged
|
||||
certs exist in the corpus to validate against. SAP 10.3 differs from
|
||||
SAP 10.2 mainly on CO2 factors (grid electricity 0.136 → 0.086 kg/kWh,
|
||||
−37%; mains gas 0.210 → 0.214 kg/kWh, +2%); prices and primary energy
|
||||
factors are largely unchanged. When the corpus migrates to SAP 10.3
|
||||
this module re-points to those values.
|
||||
|
||||
The Energy Cost Deflator stays at 0.36 (used in ECF — see
|
||||
`domain.sap.worksheet.rating`).
|
||||
|
|
@ -77,33 +77,34 @@ UNIT_PRICE_P_PER_KWH: Final[dict[int, float]] = {
|
|||
_DEFAULT_P_PER_KWH: Final[float] = 3.64 # fall back to mains gas
|
||||
|
||||
|
||||
# SAP 10.3 Table 12 — CO2 emission factor in kg CO2-equivalent per kWh
|
||||
# of delivered energy. Grid electricity uses the annual-average 0.086;
|
||||
# the monthly factors in Table 12d are for comparison only per note (s).
|
||||
# SAP 10.2 Table 12 — CO2 emission factor in kg CO2-equivalent per kWh
|
||||
# of delivered energy. Grid electricity uses the annual-average 0.136
|
||||
# kg/kWh; the monthly factors in Table 12d are for comparison only per
|
||||
# note (s).
|
||||
CO2_KG_PER_KWH: Final[dict[int, float]] = {
|
||||
# Gas fuels
|
||||
1: 0.214,
|
||||
2: 0.24, 3: 0.24, 5: 0.24, 9: 0.24,
|
||||
7: 0.029,
|
||||
1: 0.210,
|
||||
2: 0.241, 3: 0.241, 5: 0.241, 9: 0.241,
|
||||
7: 0.024,
|
||||
# Liquid fuels
|
||||
4: 0.298,
|
||||
71: 0.041, 73: 0.058,
|
||||
75: 0.226, 76: 0.072,
|
||||
71: 0.036, 73: 0.018,
|
||||
75: 0.214, 76: 0.105,
|
||||
# Solid fuels
|
||||
11: 0.398, 15: 0.398, 12: 0.398,
|
||||
20: 0.023, 22: 0.048, 23: 0.048, 21: 0.018,
|
||||
10: 0.084,
|
||||
11: 0.395, 15: 0.395, 12: 0.366,
|
||||
20: 0.028, 22: 0.053, 23: 0.053, 21: 0.023,
|
||||
10: 0.087,
|
||||
# Electricity — all grid tariffs use the same annual-average CO2 factor.
|
||||
30: 0.086, 31: 0.086, 32: 0.086, 33: 0.086, 34: 0.086, 35: 0.086,
|
||||
38: 0.086, 40: 0.086, 39: 0.086, 60: 0.086, 36: 0.086,
|
||||
30: 0.136, 31: 0.136, 32: 0.136, 33: 0.136, 34: 0.136, 35: 0.136,
|
||||
38: 0.136, 40: 0.136, 39: 0.136, 60: 0.136, 36: 0.136,
|
||||
# Heat networks
|
||||
51: 0.214, 52: 0.24, 53: 0.298, 54: 0.398, 55: 0.298,
|
||||
56: 0.298, 57: 0.041, 58: 0.058,
|
||||
41: 0.086, 42: 0.010, 43: 0.029, 44: 0.029,
|
||||
45: 0.007, 46: 0.007, 47: 0.010, 48: 0.086, 49: 0.086,
|
||||
51: 0.210, 52: 0.241, 53: 0.298, 54: 0.375, 55: 0.269,
|
||||
56: 0.298, 57: 0.036, 58: 0.018,
|
||||
41: 0.136, 42: 0.015, 43: 0.029, 44: 0.024,
|
||||
45: 0.015, 46: 0.011, 47: 0.011, 48: 0.136, 49: 0.136,
|
||||
50: 0.0,
|
||||
}
|
||||
_DEFAULT_CO2_KG_PER_KWH: Final[float] = 0.214 # mains gas baseline
|
||||
_DEFAULT_CO2_KG_PER_KWH: Final[float] = 0.210 # mains gas baseline
|
||||
|
||||
|
||||
# Gov EPC API main_fuel_type → SAP 10.3 Table 12 fuel code. Lifted from
|
||||
|
|
|
|||
82
packages/domain/src/domain/sap/tests/test_table_12.py
Normal file
82
packages/domain/src/domain/sap/tests/test_table_12.py
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
"""SAP 10.2 (14-03-2025 amendment) Table 12 value-correctness tests.
|
||||
|
||||
Locks the CO2 emission factors and primary energy factors against the
|
||||
published SAP 10.2 specification at
|
||||
`docs/sap-spec/sap-10-2-full-specification-2025-03-14.pdf`, page 189.
|
||||
|
||||
The price column (`UNIT_PRICE_P_PER_KWH`) was already SAP 10.2-correct
|
||||
when the calculator code was authored; the CO2 column was authored
|
||||
against SAP 10.3 (13-01-2026) values by mistake. ADR-0010 retargets the
|
||||
calculator to SAP 10.2 (14-03-2025) until the corpus migrates, so the
|
||||
CO2 column was corrected during P2.4. These tests lock the corrected
|
||||
values.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from domain.sap.tables.table_12 import (
|
||||
co2_factor_kg_per_kwh,
|
||||
primary_energy_factor,
|
||||
unit_price_p_per_kwh,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"fuel_code, expected_co2_kg_per_kwh, fuel_name",
|
||||
[
|
||||
# Most-common cases first — gas + electricity dominate the corpus.
|
||||
(1, 0.210, "mains gas"),
|
||||
(30, 0.136, "standard tariff electricity"),
|
||||
# Sanity: heating oil is unchanged between SAP 10.2 and SAP 10.3.
|
||||
(4, 0.298, "heating oil"),
|
||||
# Off-peak electricity tariffs all share the annual-average factor.
|
||||
(31, 0.136, "7-hour low rate electricity"),
|
||||
(35, 0.136, "24-hour heating tariff"),
|
||||
# Bulk LPG — SAP 10.2 says 0.241 (file had 0.24 rounded).
|
||||
(2, 0.241, "bulk LPG"),
|
||||
],
|
||||
)
|
||||
def test_co2_factor_matches_sap_10_2_table_12(
|
||||
fuel_code: int, expected_co2_kg_per_kwh: float, fuel_name: str
|
||||
) -> None:
|
||||
# Arrange — table_12.co2_factor_kg_per_kwh is the only CO2 source
|
||||
# in the calculator pipeline (see cert_to_inputs._co2_factor_kg_per_kwh).
|
||||
# Act
|
||||
actual = co2_factor_kg_per_kwh(fuel_code)
|
||||
|
||||
# Assert
|
||||
assert actual == pytest.approx(expected_co2_kg_per_kwh, abs=1e-6), (
|
||||
f"{fuel_name} (code {fuel_code}): expected SAP 10.2 CO2 factor "
|
||||
f"{expected_co2_kg_per_kwh}, got {actual}. See SAP 10.2 PDF p.189."
|
||||
)
|
||||
|
||||
|
||||
def test_default_co2_factor_is_mains_gas_baseline() -> None:
|
||||
# Arrange — unknown fuel codes fall back to mains gas (the SAP 10.2
|
||||
# convention; see table_12._DEFAULT_CO2_KG_PER_KWH).
|
||||
# Act
|
||||
actual = co2_factor_kg_per_kwh(None)
|
||||
|
||||
# Assert
|
||||
assert actual == pytest.approx(0.210, abs=1e-6)
|
||||
|
||||
|
||||
def test_mains_gas_unit_price_unchanged_at_sap_10_2_value() -> None:
|
||||
# Arrange — sanity: prices were already SAP 10.2-correct before P2.4.
|
||||
# This locks that we didn't accidentally regress them while fixing CO2.
|
||||
# Act
|
||||
actual = unit_price_p_per_kwh(1)
|
||||
|
||||
# Assert
|
||||
assert actual == pytest.approx(3.64, abs=1e-6)
|
||||
|
||||
|
||||
def test_standard_electricity_primary_energy_factor_unchanged() -> None:
|
||||
# Arrange — sanity: PE factor for electricity is 1.501 in both SAP
|
||||
# 10.2 and SAP 10.3; locks that P2.4 didn't touch the PEF column.
|
||||
# Act
|
||||
actual = primary_energy_factor(30)
|
||||
|
||||
# Assert
|
||||
assert actual == pytest.approx(1.501, abs=1e-6)
|
||||
Loading…
Add table
Reference in a new issue