mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
feat(modelling): ASHP decommission cost by existing system
Slice 2 of ADR-0025 costing. _decommission maps the existing system to its Southern Housing line: gas/oil flat 720, LPG 960 (tank+fuel removal), electric-storage 570/840 by property-size band. Unmapped systems raise for now -- the no-system/electric-other/other fallbacks land in the next slice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
d23b84209d
commit
cf7c2e017d
2 changed files with 44 additions and 5 deletions
|
|
@ -29,6 +29,11 @@ _ASHP_MEASURE_TYPE = "air_source_heat_pump"
|
||||||
# Decommission an existing electric-storage system, by property size band.
|
# Decommission an existing electric-storage system, by property size band.
|
||||||
_DECOMMISSION_ELECTRIC_STORAGE_SMALL = 570.0
|
_DECOMMISSION_ELECTRIC_STORAGE_SMALL = 570.0
|
||||||
_DECOMMISSION_ELECTRIC_STORAGE_LARGE = 840.0
|
_DECOMMISSION_ELECTRIC_STORAGE_LARGE = 840.0
|
||||||
|
# Decommission an existing wet (boiler) system — flat across property size for
|
||||||
|
# gas and oil; LPG carries the extra tank/fuel removal (ECOHT06-08, 03-04).
|
||||||
|
_DECOMMISSION_GAS = 720.0
|
||||||
|
_DECOMMISSION_OIL = 720.0
|
||||||
|
_DECOMMISSION_LPG = 960.0
|
||||||
|
|
||||||
# Heat-pump install (MONOBLOC, brand-neutral), by kW size band — design heat
|
# Heat-pump install (MONOBLOC, brand-neutral), by kW size band — design heat
|
||||||
# loss is rounded up to the next band (ECOHT09-13).
|
# loss is rounded up to the next band (ECOHT09-13).
|
||||||
|
|
@ -112,11 +117,19 @@ class Products:
|
||||||
return _PUMP_TOP_PRICE
|
return _PUMP_TOP_PRICE
|
||||||
|
|
||||||
def _decommission(self, inputs: AshpCostInputs) -> float:
|
def _decommission(self, inputs: AshpCostInputs) -> float:
|
||||||
return (
|
if inputs.existing_system is AshpExistingSystem.ELECTRIC_STORAGE:
|
||||||
_DECOMMISSION_ELECTRIC_STORAGE_SMALL
|
return (
|
||||||
if inputs.is_small_property
|
_DECOMMISSION_ELECTRIC_STORAGE_SMALL
|
||||||
else _DECOMMISSION_ELECTRIC_STORAGE_LARGE
|
if inputs.is_small_property
|
||||||
)
|
else _DECOMMISSION_ELECTRIC_STORAGE_LARGE
|
||||||
|
)
|
||||||
|
if inputs.existing_system is AshpExistingSystem.GAS:
|
||||||
|
return _DECOMMISSION_GAS
|
||||||
|
if inputs.existing_system is AshpExistingSystem.OIL:
|
||||||
|
return _DECOMMISSION_OIL
|
||||||
|
if inputs.existing_system is AshpExistingSystem.LPG:
|
||||||
|
return _DECOMMISSION_LPG
|
||||||
|
raise ValueError(f"no decommission rate for {inputs.existing_system}")
|
||||||
|
|
||||||
def _distribution(self, inputs: AshpCostInputs) -> float:
|
def _distribution(self, inputs: AshpCostInputs) -> float:
|
||||||
radiators: int = max(_MIN_RADIATORS, min(_MAX_RADIATORS, inputs.radiator_count))
|
radiators: int = max(_MIN_RADIATORS, min(_MAX_RADIATORS, inputs.radiator_count))
|
||||||
|
|
|
||||||
|
|
@ -37,3 +37,29 @@ def test_ashp_bundle_cost_composes_an_electric_storage_full_distribution_dwellin
|
||||||
# (7 rads) 3618 = 16290.60, with the separate 25% ASHP contingency.
|
# (7 rads) 3618 = 16290.60, with the separate 25% ASHP contingency.
|
||||||
assert abs(cost.total - 16290.60) <= 1e-9
|
assert abs(cost.total - 16290.60) <= 1e-9
|
||||||
assert abs(cost.contingency_rate - 0.25) <= 1e-9
|
assert abs(cost.contingency_rate - 0.25) <= 1e-9
|
||||||
|
|
||||||
|
|
||||||
|
def _large_no_reuse(system: AshpExistingSystem) -> AshpCostInputs:
|
||||||
|
"""A large dwelling, 8 kW band, 8 radiators, no reusable wet system — so the
|
||||||
|
only thing varying with ``system`` is the decommission line."""
|
||||||
|
return AshpCostInputs(
|
||||||
|
existing_system=system,
|
||||||
|
is_small_property=False,
|
||||||
|
design_heat_loss_kw=8.0,
|
||||||
|
radiator_count=8,
|
||||||
|
has_reusable_wet_system=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_decommission_cost_varies_by_existing_system() -> None:
|
||||||
|
# Arrange — common: pump (8 kW) 9840 + cylinder 2382.60 + distribution (8
|
||||||
|
# rads) 4152 = 16374.60; only decommission differs by system.
|
||||||
|
products = Products()
|
||||||
|
common = 16374.60
|
||||||
|
|
||||||
|
# Act / Assert — gas and oil are flat 720; LPG 960; electric-storage large
|
||||||
|
# 840 (small 570 is pinned by the tracer above).
|
||||||
|
assert abs(products.ashp_bundle_cost(_large_no_reuse(AshpExistingSystem.GAS)).total - (common + 720.0)) <= 1e-9
|
||||||
|
assert abs(products.ashp_bundle_cost(_large_no_reuse(AshpExistingSystem.OIL)).total - (common + 720.0)) <= 1e-9
|
||||||
|
assert abs(products.ashp_bundle_cost(_large_no_reuse(AshpExistingSystem.LPG)).total - (common + 960.0)) <= 1e-9
|
||||||
|
assert abs(products.ashp_bundle_cost(_large_no_reuse(AshpExistingSystem.ELECTRIC_STORAGE)).total - (common + 840.0)) <= 1e-9
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue