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:
Khalim Conn-Kowlessar 2026-07-09 12:54:47 +00:00
parent 6b64104dc5
commit 3576d05370

View file

@ -182,7 +182,7 @@ class ModellingOrchestrator:
# The Optimiser speaks the goal's currency (ADR-0062): group signals,
# dependency pricing and repair marginals are all measured by this
# objective — SAP by default, carbon reduction for a Reducing-CO2 goal.
objective: Callable[[Score], float] = _objective_for(scenario)
objective: Callable[[Score], float] = _objective_for(scenario, bill_derivation)
groups: list[list[ScoredOption]] = _scored_candidate_groups(
scorer,
effective_epc,
@ -443,12 +443,28 @@ def _carbon_reduction(score: Score) -> float:
return -score.co2_kg_per_yr
def _objective_for(scenario: Scenario) -> Callable[[Score], float]:
def _bill_saving(bill_derivation: BillDerivation) -> Callable[[Score], float]:
"""The Energy-Savings objective: the annual Bill at the current Fuel Rates
snapshot, negated so higher is better (a saved £ scores +1). Priced at the
live snapshot, not SAP's internal tariff book — that difference is the
point of the goal (ADR-0062)."""
def objective(score: Score) -> float:
return -_bill_for(bill_derivation, score).total_gbp
return objective
def _objective_for(
scenario: Scenario, bill_derivation: BillDerivation
) -> Callable[[Score], float]:
"""The metric the Scenario's goal maximises (ADR-0062), as an Optimiser
objective (higher is better). Goals without an aligned metric optimise
SAP, as every goal did before."""
if scenario.goal == _REDUCING_CO2_GOAL:
return _carbon_reduction
if scenario.goal == _ENERGY_SAVINGS_GOAL:
return _bill_saving(bill_derivation)
return sap_rating