mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
An Energy-Savings scenario prices packages at the live fuel rates 🟥
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
48d54675c3
commit
6b64104dc5
2 changed files with 56 additions and 1 deletions
|
|
@ -39,6 +39,7 @@ from orchestration.modelling_orchestrator import (
|
|||
_candidate_recommendations, # pyright: ignore[reportPrivateUsage]
|
||||
)
|
||||
from orchestration.property_baseline_orchestrator import PropertyBaselineOrchestrator
|
||||
from repositories.fuel_rates.fuel_rates_repository import FuelRatesRepository
|
||||
from repositories.fuel_rates.fuel_rates_static_file_repository import (
|
||||
FuelRatesStaticFileRepository,
|
||||
)
|
||||
|
|
@ -182,6 +183,7 @@ def run_modelling(
|
|||
considered_measures: Optional[frozenset[MeasureType]] = None,
|
||||
products: Optional[ProductRepository] = None,
|
||||
scenario: Optional[Scenario] = None,
|
||||
fuel_rates: Optional[FuelRatesRepository] = None,
|
||||
print_table: bool = True,
|
||||
) -> Plan:
|
||||
"""Run ONLY the Modelling stage over ``epc`` with no database — skipping
|
||||
|
|
@ -240,7 +242,7 @@ def run_modelling(
|
|||
ModellingOrchestrator(
|
||||
unit_of_work=lambda: unit,
|
||||
calculator=Sap10Calculator(),
|
||||
fuel_rates=FuelRatesStaticFileRepository(),
|
||||
fuel_rates=fuel_rates or FuelRatesStaticFileRepository(),
|
||||
).run(
|
||||
property_ids=[_PROPERTY_ID],
|
||||
scenario_ids=[scenario_id],
|
||||
|
|
|
|||
|
|
@ -9,11 +9,19 @@ carbon-optimal packages diverge at a £16,000 budget.
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
|
||||
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
||||
from domain.fuel_rates.fuel import Fuel
|
||||
from domain.fuel_rates.fuel_rates import FuelRate, FuelRates
|
||||
from domain.modelling.measure_type import MeasureType
|
||||
from domain.modelling.plan import Plan
|
||||
from domain.modelling.scenario import Scenario
|
||||
from harness.console import run_modelling
|
||||
from repositories.fuel_rates.fuel_rates_repository import FuelRatesRepository
|
||||
from repositories.fuel_rates.fuel_rates_static_file_repository import (
|
||||
FuelRatesStaticFileRepository,
|
||||
)
|
||||
from tests.domain.modelling._elmhurst_recommendation import (
|
||||
parse_recommendation_summary,
|
||||
)
|
||||
|
|
@ -57,3 +65,48 @@ def test_reducing_co2_scenario_buys_carbon_not_sap() -> None:
|
|||
)
|
||||
selected = {measure.measure_type for measure in carbon_led.measures}
|
||||
assert MeasureType.GAS_BOILER_UPGRADE not in selected
|
||||
|
||||
|
||||
class _FixedFuelRates(FuelRatesRepository):
|
||||
def __init__(self, rates: FuelRates) -> None:
|
||||
self._rates = rates
|
||||
|
||||
def get_current(self) -> FuelRates:
|
||||
return self._rates
|
||||
|
||||
|
||||
def _cheap_electricity_snapshot() -> FuelRates:
|
||||
"""The committed snapshot with electricity at 1p/kWh — a world where any
|
||||
electric heating out-bills gas, while SAP's internal price book (which the
|
||||
calculator rates against) is unmoved."""
|
||||
base = FuelRatesStaticFileRepository().get_current()
|
||||
rates = dict(base.rates)
|
||||
rates[Fuel.ELECTRICITY] = FuelRate(
|
||||
unit_rate_p_per_kwh=1.0,
|
||||
standing_charge_p_per_day=rates[Fuel.ELECTRICITY].standing_charge_p_per_day,
|
||||
)
|
||||
return dataclasses.replace(base, rates=rates)
|
||||
|
||||
|
||||
def test_energy_savings_scenario_prices_packages_at_the_live_fuel_rates() -> None:
|
||||
# Arrange — SAP is itself a cost metric, but it prices energy from its
|
||||
# internal tariff book. The Energy Savings goal must price at the *live*
|
||||
# Fuel Rates snapshot: with 1p/kWh electricity, electric heating slashes
|
||||
# the bill even though SAP still scores the gas boiler package higher.
|
||||
epc = _solid_brick_dwelling()
|
||||
|
||||
# Act
|
||||
plan: Plan = run_modelling(
|
||||
epc,
|
||||
scenario=_scenario("Energy Savings", budget=16000.0),
|
||||
fuel_rates=_FixedFuelRates(_cheap_electricity_snapshot()),
|
||||
print_table=False,
|
||||
)
|
||||
|
||||
# Assert — the bill objective abandons the boiler for electric heating.
|
||||
selected = {measure.measure_type for measure in plan.measures}
|
||||
assert MeasureType.GAS_BOILER_UPGRADE not in selected
|
||||
assert selected & {
|
||||
MeasureType.AIR_SOURCE_HEAT_PUMP,
|
||||
MeasureType.HIGH_HEAT_RETENTION_STORAGE_HEATERS,
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue