mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
S0380.182: community-heating CHP+boilers CO2/PE credit (§12b/13b) — closes CH2/CH4 CO2+PE
SAP 10.2 worksheet block 12b (CO2) / 13b (PE) for community heating
"CHP and boilers" (SAP code 302). Per unit of network heat fuel
H = (307)+(310) the effective generation factor is:
chp×100/(362)×f_fuel − chp×(361)/(362)×f_disp + (1−chp)×100/(367)×f_fuel
(363)/(463) CHP fuel = chp_frac × 100/heat_eff × f_fuel
(364)/(464) less credit = −chp_frac × elec_eff/heat_eff × f_disp
(368)/(468) boiler fuel = (1−chp_frac) × 100/boiler_eff × f_fuel
f_fuel = Table 12 heat-network fuel factor (the CHP unit and the back-up
boilers burn the same community fuel — verified vs CH2 gas / CH4 oil /
CH6 coal worksheets (363)/(368)); f_disp = Table 12f (PDF p.196) credit
for the CHP-generated electricity. RdSAP 10 §C (p.58) defaults: heat eff
50% (362), electrical eff 25% (361), boiler eff 80% (367); CHP heat frac
0.35 per-cert via community_heating_chp_fraction.
New `_heat_network_code_302_effective_factor` + Table 12f flexible
constants (0.420 CO2 / 2.369 PE) + RdSAP §C efficiency constants, wired
into all four factor helpers (main + HW, CO2 + PE) ahead of the existing
single-fuel / 1-over-heat-source-eff path. The worksheet (368)/(468)
boiler emissions DISPLAY rounded/mis-aligned in the PDF, but the
(373)/(473)/(386)/(486) totals reconcile only with the boiler at the
full Table 12 factor — verified EXACT.
Two spec citations applied:
- Table 12f flexible-operation default for RdSAP community CHP is an
Elmhurst engine choice (Table 12f notes make "standard" the default);
mirrored per [[feedback-software-no-special-handling]] and documented
in SAP_CALCULATOR.md §8.3.
- Table 12 heat-network oil/biodiesel CO2 (codes 53/56) corrected
0.298 → 0.335 per Table 12 (p.189) "assumes 'gas oil'"; the code-302
oil cascade (CH4) was the first to exercise it. PE 1.180 was already
correct. No other variant uses these codes (no regression).
Closures (CO2 + PE only — the CHP credit does not touch cost/SAP):
CH2 (CHP/Gas) CO2 −1411.49→+0.0000, PE +1331.23→+0.0000 EXACT
CH4 (CHP/Oil) CO2 −4378.24→−0.0000, PE +319.81→−0.0000 EXACT
CH6 (CHP/Coal) CO2/PE re-pinned (+2411.54 / +5023.48) — its worksheet
lodges a manual DLF=1.0 the Summary doesn't carry, so
cascade DLF=1.45 over-scales H; same root as the CH6
SAP −7.49 / cost +£172 (separate DLF front).
CH2/CH4 are now CO2+PE-exact but still carry the heat-network cost/SAP
residual (+0.5277 SAP / −£12.16 cost, exposed by S0380.175 — cost-side,
untouched here). CH3 unchanged (code 304 community-HP COP front).
Corpus state: 37 variants EXACT on all four metrics (incl. CH1);
remaining residuals are CH2/CH4 cost+SAP, CH3 CO2+PE (HP COP), CH6
all-metric (DLF quirk). 2223 pass + 1 skip + 0 fail (tolerances 1e-4 all
metrics per S0380.181); pyright net-zero 43→43.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
3bbb9aa1a2
commit
035303e9f8
5 changed files with 241 additions and 5 deletions
|
|
@ -695,11 +695,32 @@ _EXPECTATIONS: tuple[_CorpusExpectation, ...] = (
|
|||
# for the next slice. Elmhurst DISPLAYS the (372) energy column as
|
||||
# 0.01 × (307) (space only) but computes emissions on 0.01 ×
|
||||
# (307+310) per the §C3.2 text — verified EXACT line-by-line.
|
||||
#
|
||||
# Slice S0380.182 wired the SAP 10.2 §12b/13b community-heating
|
||||
# "CHP and boilers" (SAP code 302) CO2/PE cascade: per unit of
|
||||
# network heat fuel H = (307)+(310), the effective generation factor
|
||||
# = chp_frac × 100/(362) × f_fuel − chp_frac × (361)/(362) × f_disp
|
||||
# + (1−chp_frac) × 100/(367) × f_fuel, where f_fuel is the Table 12
|
||||
# heat-network fuel factor (CHP + back-up boilers burn the same
|
||||
# community fuel) and f_disp is the Table 12f credit factor for the
|
||||
# CHP-generated electricity (Elmhurst uses "flexible operation"
|
||||
# 0.420 CO2 / 2.369 PE). RdSAP 10 §C (p.58) defaults: heat eff 50% /
|
||||
# electrical eff 25% / boiler eff 80%; CHP frac 0.35 per-cert. Also
|
||||
# fixed Table 12 heat-network-oil CO2 (codes 53/56 0.298→0.335 per
|
||||
# Table 12 p.189 — the code-302 oil cascade was the first to use it).
|
||||
# CH2 (gas) + CH4 (oil) CO2 + PE now EXACT (<1e-4). CH6 (coal) CO2/PE
|
||||
# shift sign: its worksheet lodges a manual DLF=1.0 (two adjoining
|
||||
# dwellings) the Summary doesn't carry, so the cascade's DLF=1.45
|
||||
# over-scales H — pin + the CH6 SAP −7.49 / cost +£172 are the same
|
||||
# DLF quirk (separate front, likely pin-forever). CH2/CH4 SAP +0.5277
|
||||
# / cost −£12.16 is the heat-network cost/standing residual exposed
|
||||
# by S0380.175 (cost-side, untouched by this CO2/PE slice). CH3
|
||||
# unchanged (code 304 community-HP COP front).
|
||||
_CorpusExpectation(variant='community heating 1', block='11b', expected_sap_resid=+0.0000, expected_cost_resid_gbp=-0.0000, expected_co2_resid_kg=-0.0000, expected_pe_resid_kwh=+0.0000),
|
||||
_CorpusExpectation(variant='community heating 2', block='11b', expected_sap_resid=+0.5277, expected_cost_resid_gbp=-12.1598, expected_co2_resid_kg=-1411.4867, expected_pe_resid_kwh=+1331.2330),
|
||||
_CorpusExpectation(variant='community heating 2', block='11b', expected_sap_resid=+0.5277, expected_cost_resid_gbp=-12.1598, expected_co2_resid_kg=+0.0000, expected_pe_resid_kwh=+0.0000),
|
||||
_CorpusExpectation(variant='community heating 3', block='11b', expected_sap_resid=+0.0000, expected_cost_resid_gbp=-0.0000, expected_co2_resid_kg=-75.3228, expected_pe_resid_kwh=-249.3161),
|
||||
_CorpusExpectation(variant='community heating 4', block='11b', expected_sap_resid=+0.5277, expected_cost_resid_gbp=-12.1598, expected_co2_resid_kg=-4378.2449, expected_pe_resid_kwh=+319.8065),
|
||||
_CorpusExpectation(variant='community heating 6', block='11b', expected_sap_resid=-7.4942, expected_cost_resid_gbp=+172.6778, expected_co2_resid_kg=-2916.0676, expected_pe_resid_kwh=+7689.7925),
|
||||
_CorpusExpectation(variant='community heating 4', block='11b', expected_sap_resid=+0.5277, expected_cost_resid_gbp=-12.1598, expected_co2_resid_kg=-0.0000, expected_pe_resid_kwh=-0.0000),
|
||||
_CorpusExpectation(variant='community heating 6', block='11b', expected_sap_resid=-7.4942, expected_cost_resid_gbp=+172.6778, expected_co2_resid_kg=+2411.5399, expected_pe_resid_kwh=+5023.4766),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -495,3 +495,34 @@ shape (Table 12 annual where spec literal says monthly), so the gate
|
|||
is implemented under the same `dual-rate → annual on top of monthly`
|
||||
discipline. If a second §12.4.4-eligible cert worksheet diverges from
|
||||
this rule it should be raised against this row before re-tuning.
|
||||
|
||||
### 8.3 Community-heating CHP uses Table 12f "flexible operation" by default
|
||||
|
||||
**Slice S0380.182.** For RdSAP-defaulted community heating with CHP
|
||||
(SAP code 302) that is **not** in the PCDB, the displaced-electricity
|
||||
credit (worksheet (364)/(366) CO2 and (464)/(466) PE) needs a Table 12f
|
||||
(PDF p.196) "fuel factor for electricity generated by CHP". Table 12f
|
||||
offers three regimes per CHP vintage:
|
||||
|
||||
| Regime | CO2 kg/kWh | PE | Note |
|
||||
|---|---|---|---|
|
||||
| export only | 0.394 | 2.345 | |
|
||||
| **flexible operation** | **0.420** | **2.369** | needs assessor evidence |
|
||||
| standard | 0.348 | 2.149 | "all other operating regimes" |
|
||||
|
||||
Table 12f's own notes make **standard** the default ("Standard ... should
|
||||
be used for all other operating regimes of gas CHP plants") and require
|
||||
submitted evidence for **flexible**. Yet the BRE-approved Elmhurst rdSAP
|
||||
engine emits **0.420 / 2.369 (flexible)** for these RdSAP-defaulted
|
||||
community-CHP certs — verified line-by-line against the CH2 (gas) / CH4
|
||||
(oil) / CH6 (coal) corpus worksheets (364)/(366)/(464)/(466), all of
|
||||
which carry 0.4200 CO2 and 2.3690 PE regardless of the community fuel.
|
||||
RdSAP 10 §C (p.58) is silent on the Table 12f regime, so this is an
|
||||
engine default not derivable from the spec text.
|
||||
|
||||
Per [[feedback-software-no-special-handling]] / [[feedback-worksheet-not-api-reference]]
|
||||
we mirror the engine: `_TABLE_12F_CHP_FLEXIBLE_{CO2,PE}` in
|
||||
`cert_to_inputs`. CH2 + CH4 close to <1e-4 on both CO2 and PE with this
|
||||
factor; "standard" (0.348/2.149) would leave a residual. If a future
|
||||
PCDB-listed or evidence-backed CHP cert diverges, raise it against this
|
||||
row before re-tuning.
|
||||
|
|
|
|||
|
|
@ -984,6 +984,97 @@ def _heat_network_distribution_electricity(
|
|||
return (energy_kwh, co2_factor, pe_factor)
|
||||
|
||||
|
||||
# SAP 10.2 Table 12 fuel code 302's worksheet path. Community heating
|
||||
# "CHP and boilers" (Table 4a code 302).
|
||||
_SAP_CODE_COMMUNITY_CHP_AND_BOILERS: Final[int] = 302
|
||||
|
||||
# SAP 10.2 Table 12f (PDF p.196) — fuel factors for the electricity
|
||||
# GENERATED BY CHP (the displaced-grid credit, worksheet (364)/(464)).
|
||||
# The BRE-approved Elmhurst rdSAP engine applies the "flexible
|
||||
# operation" row (0.420 kg CO2/kWh, 2.369 PE) to RdSAP-defaulted
|
||||
# community CHP that is not in the PCDB — verified line-by-line against
|
||||
# the CH2/CH4/CH6 corpus worksheets (363)..(366) / (463)..(466). Table
|
||||
# 12f's own notes make "standard" (0.348 / 2.149) the default and
|
||||
# require assessor evidence for "flexible"; we mirror the certified
|
||||
# engine per [[feedback-software-no-special-handling]] (documented as a
|
||||
# spec divergence in SAP_CALCULATOR.md §8).
|
||||
_TABLE_12F_CHP_FLEXIBLE_CO2_KG_PER_KWH: Final[float] = 0.420
|
||||
_TABLE_12F_CHP_FLEXIBLE_PE_KWH_PER_KWH: Final[float] = 2.369
|
||||
|
||||
# RdSAP 10 §C (PDF p.58) heat-network CHP defaults when the network is
|
||||
# not in the PCDB: CHP overall efficiency 75% with heat-to-power ratio
|
||||
# 2.0 → heat efficiency 50% (worksheet (362)) + electrical efficiency
|
||||
# 25% (worksheet (361)); back-up boiler efficiency 80% (worksheet
|
||||
# (367)). The CHP heat fraction (0.35 default) is per-cert via
|
||||
# `community_heating_chp_fraction`.
|
||||
_HEAT_NETWORK_CHP_HEAT_EFFICIENCY: Final[float] = 0.50
|
||||
_HEAT_NETWORK_CHP_ELECTRICAL_EFFICIENCY: Final[float] = 0.25
|
||||
_HEAT_NETWORK_CHP_BOILER_EFFICIENCY: Final[float] = 0.80
|
||||
|
||||
|
||||
def _heat_network_code_302_effective_factor(
|
||||
main: Optional[MainHeatingDetail],
|
||||
*,
|
||||
primary_energy: bool,
|
||||
) -> Optional[float]:
|
||||
"""SAP 10.2 worksheet block 12b (CO2) / 13b (PE) for community
|
||||
heating "CHP and boilers" (SAP code 302) — the effective per-kWh
|
||||
factor to apply to the network heat fuel [(307) + (310)].
|
||||
|
||||
Per unit of network heat fuel H = (307) + (310), the worksheet sums:
|
||||
|
||||
CHP fuel (363)/(463) = chp_frac × 100/(362) × f_fuel
|
||||
less credit (364)/(464) = −chp_frac × (361)/(362) × f_disp
|
||||
boiler fuel (368)/(468) = (1−chp_frac) × 100/(367) × f_fuel
|
||||
|
||||
where f_fuel is the Table 12 heat-network fuel factor (the CHP unit
|
||||
and the back-up boilers burn the same community fuel — verified vs
|
||||
CH2 gas / CH4 oil / CH6 coal worksheets) and f_disp is the Table 12f
|
||||
credit factor for the electricity the CHP generates. RdSAP 10 §C
|
||||
defaults: (362) heat eff 50%, (361) electrical eff 25%, (367) boiler
|
||||
eff 80%.
|
||||
|
||||
Returns the blended factor for code-302 mains with the CHP-split
|
||||
fields populated; None otherwise so callers fall through to the
|
||||
existing single-fuel / heat-source-efficiency-scaling path.
|
||||
|
||||
NB the worksheet PDF DISPLAYS the (368)/(468) boiler emissions
|
||||
rounded/mis-aligned, but the (373)/(473)/(386)/(486) totals
|
||||
reconcile only with the boiler at the FULL Table 12 fuel factor —
|
||||
verified EXACT.
|
||||
"""
|
||||
if (
|
||||
main is None
|
||||
or main.sap_main_heating_code != _SAP_CODE_COMMUNITY_CHP_AND_BOILERS
|
||||
):
|
||||
return None
|
||||
chp_fraction = main.community_heating_chp_fraction
|
||||
boiler_fuel_code = main.community_heating_boiler_fuel_type
|
||||
if chp_fraction is None or boiler_fuel_code is None:
|
||||
return None
|
||||
if primary_energy:
|
||||
fuel_factor = primary_energy_factor(boiler_fuel_code)
|
||||
displaced_factor = _TABLE_12F_CHP_FLEXIBLE_PE_KWH_PER_KWH
|
||||
else:
|
||||
fuel_factor = co2_factor_kg_per_kwh(boiler_fuel_code)
|
||||
displaced_factor = _TABLE_12F_CHP_FLEXIBLE_CO2_KG_PER_KWH
|
||||
boiler_fraction = 1.0 - chp_fraction
|
||||
return (
|
||||
chp_fraction
|
||||
* (1.0 / _HEAT_NETWORK_CHP_HEAT_EFFICIENCY)
|
||||
* fuel_factor
|
||||
- chp_fraction
|
||||
* (
|
||||
_HEAT_NETWORK_CHP_ELECTRICAL_EFFICIENCY
|
||||
/ _HEAT_NETWORK_CHP_HEAT_EFFICIENCY
|
||||
)
|
||||
* displaced_factor
|
||||
+ boiler_fraction
|
||||
* (1.0 / _HEAT_NETWORK_CHP_BOILER_EFFICIENCY)
|
||||
* fuel_factor
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PriceTable:
|
||||
"""Seam between the spec-correct SAP 10.2/10.3 Table 12 prices and
|
||||
|
|
@ -2606,6 +2697,13 @@ def _main_heating_co2_factor_kg_per_kwh(
|
|||
- zero-fuel cases (sum monthly_kwh == 0 → effective factor None;
|
||||
annual factor is the safe degenerate value)
|
||||
"""
|
||||
# SAP 10.2 §12b — community-heating CHP+boilers (code 302): the
|
||||
# blended CHP-credit + boiler generation CO2 factor (S0380.182).
|
||||
code_302_co2 = _heat_network_code_302_effective_factor(
|
||||
main, primary_energy=False,
|
||||
)
|
||||
if code_302_co2 is not None:
|
||||
return code_302_co2
|
||||
if not _is_electric_main(main):
|
||||
# Heat-network mains (SAP codes 301 / 304) are non-electric per
|
||||
# `_is_electric_main` but require a heat-source-efficiency scaling
|
||||
|
|
@ -2671,6 +2769,13 @@ def _main_heating_primary_factor(
|
|||
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)."""
|
||||
# SAP 10.2 §13b — community-heating CHP+boilers (code 302): the
|
||||
# blended CHP-credit + boiler generation PE factor (S0380.182).
|
||||
code_302_pe = _heat_network_code_302_effective_factor(
|
||||
main, primary_energy=True,
|
||||
)
|
||||
if code_302_pe is not None:
|
||||
return code_302_pe
|
||||
fuel = _main_fuel_code(main)
|
||||
if not _is_electric_main(main):
|
||||
# PE-side mirror of `_main_heating_co2_factor_kg_per_kwh`
|
||||
|
|
@ -2929,6 +3034,16 @@ def _hot_water_co2_factor_kg_per_kwh(
|
|||
monthly HW fuel kWh — the calculator uses an annual-flat HW
|
||||
efficiency so the SHAPE of fuel monthly is identical to demand
|
||||
monthly, and `_effective_monthly_co2_factor` is shape-only)."""
|
||||
# SAP 10.2 §12b — community-heating CHP+boilers (code 302) HW from
|
||||
# main: the same blended CHP-credit + boiler generation CO2 factor
|
||||
# as SH (S0380.182). Gated on WHC ∈ {901, 902, 914} so immersion-
|
||||
# heated DHW on a CHP network keeps the lodged electric factor.
|
||||
if epc.sap_heating.water_heating_code in _WATER_INHERIT_FROM_MAIN_CODES:
|
||||
code_302_co2 = _heat_network_code_302_effective_factor(
|
||||
_water_heating_main(epc), primary_energy=False,
|
||||
)
|
||||
if code_302_co2 is not None:
|
||||
return code_302_co2
|
||||
# Community heating + WHC ∈ {901, 902, 914}: HW heat is delivered
|
||||
# through the heat-network main, so HW CO2 must read the same
|
||||
# Table 12 heat-network code factor as SH, scaled by 1/heat_source_
|
||||
|
|
@ -2977,6 +3092,15 @@ def _hot_water_primary_factor(
|
|||
exactly to match the Elmhurst worksheet's (278) annual factor.
|
||||
The 41-variant heating-systems corpus closes its HW PE residual
|
||||
+25/+48 → 0 with this gate."""
|
||||
# SAP 10.2 §13b — community-heating CHP+boilers (code 302) HW from
|
||||
# main: same blended CHP-credit + boiler generation PE factor as SH
|
||||
# (S0380.182). Gated on WHC ∈ {901, 902, 914}.
|
||||
if epc.sap_heating.water_heating_code in _WATER_INHERIT_FROM_MAIN_CODES:
|
||||
code_302_pe = _heat_network_code_302_effective_factor(
|
||||
_water_heating_main(epc), primary_energy=True,
|
||||
)
|
||||
if code_302_pe is not None:
|
||||
return code_302_pe
|
||||
# Mirror of `_hot_water_co2_factor_kg_per_kwh` community-heating
|
||||
# branch (S0380.173): WHC ∈ {901, 902, 914} on a heat-network main
|
||||
# routes HW PE through the same Table 12 heat-network code as SH,
|
||||
|
|
|
|||
|
|
@ -192,8 +192,14 @@ CO2_KG_PER_KWH: Final[dict[int, float]] = {
|
|||
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.210, 52: 0.241, 53: 0.298, 54: 0.375, 55: 0.269,
|
||||
56: 0.298, 57: 0.036, 58: 0.018,
|
||||
# Heat-network oil (code 53 "assumes 'gas oil'") and mineral-oil/
|
||||
# biodiesel boilers (code 56) carry 0.335 kg CO2/kWh per SAP 10.2
|
||||
# Table 12 (p.189) — NOT the individual-appliance heating-oil factor
|
||||
# (code 4 = 0.298). (Fixed in S0380.182 when the code-302 CHP CO2
|
||||
# cascade first exercised heat-network oil; PE 1.180 was already
|
||||
# correct.)
|
||||
51: 0.210, 52: 0.241, 53: 0.335, 54: 0.375, 55: 0.269,
|
||||
56: 0.335, 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,
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ from domain.sap10_calculator.exceptions import (
|
|||
from domain.sap10_calculator.rdsap.cert_to_inputs import (
|
||||
SAP_10_2_SPEC_PRICES,
|
||||
_has_suspended_timber_floor_per_spec, # pyright: ignore[reportPrivateUsage]
|
||||
_heat_network_code_302_effective_factor, # pyright: ignore[reportPrivateUsage]
|
||||
_heat_network_distribution_electricity, # pyright: ignore[reportPrivateUsage]
|
||||
_heat_network_dlf, # pyright: ignore[reportPrivateUsage]
|
||||
_is_electric_main, # pyright: ignore[reportPrivateUsage]
|
||||
|
|
@ -209,6 +210,59 @@ def test_heat_network_distribution_electricity_per_sap_10_2_appendix_c_3_2() ->
|
|||
assert abs(pe_factor - expected_pe_factor) <= 1e-9
|
||||
|
||||
|
||||
def test_heat_network_code_302_chp_effective_factor_per_sap_10_2_block_12b_13b() -> None:
|
||||
# Arrange — community heating "CHP and boilers" (SAP code 302) on
|
||||
# the RdSAP 10 §C (PDF p.58) defaults: CHP heat frac 0.35, heat eff
|
||||
# 50% / electrical eff 25%, boiler eff 80%. CH2-style gas network
|
||||
# (community_heating_boiler_fuel_type = 51 → Table 12 gas 0.210 CO2
|
||||
# / 1.130 PE). SAP 10.2 §12b/13b effective generation factor:
|
||||
# chp×100/(362)×f − chp×(361)/(362)×f_disp + (1−chp)×100/(367)×f
|
||||
# with f_disp = Table 12f flexible operation (0.420 CO2 / 2.369 PE).
|
||||
main = MainHeatingDetail(
|
||||
has_fghrs=False,
|
||||
main_fuel_type=20,
|
||||
heat_emitter_type=1,
|
||||
emitter_temperature=1,
|
||||
main_heating_control=2306,
|
||||
main_heating_category=6,
|
||||
sap_main_heating_code=302,
|
||||
community_heating_chp_fraction=0.35,
|
||||
community_heating_boiler_fuel_type=51,
|
||||
)
|
||||
|
||||
# Act
|
||||
co2 = _heat_network_code_302_effective_factor(main, primary_energy=False)
|
||||
pe = _heat_network_code_302_effective_factor(main, primary_energy=True)
|
||||
|
||||
# Assert — gas: 0.35×2.0×0.210 − 0.35×0.5×0.420 + 0.65×1.25×0.210
|
||||
# = 0.147 − 0.0735 + 0.170625 = 0.244125 (matches the
|
||||
# CH2 worksheet (386) generation factor); PE mirror with 1.130 /
|
||||
# 2.369 = 1.29455.
|
||||
assert co2 is not None
|
||||
assert pe is not None
|
||||
assert abs(co2 - 0.244125) <= 1e-9
|
||||
assert abs(pe - 1.29455) <= 1e-9
|
||||
|
||||
|
||||
def test_heat_network_code_302_effective_factor_none_for_non_302_main() -> None:
|
||||
# Arrange — a code-301 heat-network boiler main (no CHP split). The
|
||||
# §12b/13b CHP+boilers blend applies only to code 302; code 301
|
||||
# routes through the 1/heat-source-eff scaling path instead.
|
||||
main = MainHeatingDetail(
|
||||
has_fghrs=False,
|
||||
main_fuel_type=20,
|
||||
heat_emitter_type=1,
|
||||
emitter_temperature=1,
|
||||
main_heating_control=2306,
|
||||
main_heating_category=6,
|
||||
sap_main_heating_code=301,
|
||||
)
|
||||
|
||||
# Act / Assert
|
||||
assert _heat_network_code_302_effective_factor(main, primary_energy=False) is None
|
||||
assert _heat_network_code_302_effective_factor(main, primary_energy=True) is None
|
||||
|
||||
|
||||
def test_heat_network_distribution_electricity_none_for_individual_main() -> None:
|
||||
# Arrange — an individually-heated gas-boiler main (category 2, no
|
||||
# heat-network SAP code). §C3.2 pumping electricity applies only to
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue