mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
feat(modelling): price sloping-ceiling + flat-roof measures in the catalogue
Slice 4 (ADR-0021). The roof dispatcher can now emit sloping_ceiling_insulation and flat_roof_insulation, so wire both into contingencies and the sample catalogue; the forcing-function test now asserts every generator measure type is both priced and has a contingency rate, so an offline/live run over a sloping or flat roof never dies on a missing entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
13b18ce9fb
commit
1a807a4c4c
3 changed files with 11 additions and 2 deletions
|
|
@ -8,6 +8,8 @@ extended as each measure type lands.
|
|||
_CONTINGENCY_RATES: dict[str, float] = {
|
||||
"cavity_wall_insulation": 0.10,
|
||||
"loft_insulation": 0.10,
|
||||
"sloping_ceiling_insulation": 0.10,
|
||||
"flat_roof_insulation": 0.10,
|
||||
"suspended_floor_insulation": 0.20,
|
||||
"solid_floor_insulation": 0.26,
|
||||
"mechanical_ventilation": 0.26,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
{
|
||||
"cavity_wall_insulation": { "unit_cost_per_m2": 18.5 },
|
||||
"loft_insulation": { "unit_cost_per_m2": 12.0 },
|
||||
"sloping_ceiling_insulation": { "unit_cost_per_m2": 40.0 },
|
||||
"flat_roof_insulation": { "unit_cost_per_m2": 60.0 },
|
||||
"suspended_floor_insulation": { "unit_cost_per_m2": 25.0 },
|
||||
"solid_floor_insulation": { "unit_cost_per_m2": 45.0 },
|
||||
"mechanical_ventilation": { "unit_cost_per_m2": 450.0 },
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import pytest
|
|||
from datatypes.epc.domain.epc import Epc
|
||||
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
||||
from domain.geospatial.planning_restrictions import PlanningRestrictions
|
||||
from domain.modelling.contingencies import contingency_rate
|
||||
from harness.console import DEFAULT_CATALOGUE, run_modelling, run_one
|
||||
from repositories.product.product_json_repository import ProductJsonRepository
|
||||
from tests.domain.modelling._elmhurst_recommendation import (
|
||||
|
|
@ -25,6 +26,8 @@ _GENERATOR_MEASURE_TYPES = (
|
|||
"external_wall_insulation",
|
||||
"internal_wall_insulation",
|
||||
"loft_insulation",
|
||||
"sloping_ceiling_insulation",
|
||||
"flat_roof_insulation",
|
||||
"suspended_floor_insulation",
|
||||
"solid_floor_insulation",
|
||||
"mechanical_ventilation",
|
||||
|
|
@ -113,10 +116,12 @@ def test_sample_catalogue_prices_every_generator_measure_type() -> None:
|
|||
# Arrange — the default offline catalogue.
|
||||
products: ProductJsonRepository = ProductJsonRepository(DEFAULT_CATALOGUE)
|
||||
|
||||
# Act / Assert — get() raises if a Measure Type is unpriced, so an offline
|
||||
# run over arbitrary EPCs never dies on a missing catalogue entry.
|
||||
# Act / Assert — get() and contingency_rate() each raise on a missing
|
||||
# Measure Type, so an offline run over arbitrary EPCs never dies on a
|
||||
# missing catalogue or contingency entry.
|
||||
for measure_type in _GENERATOR_MEASURE_TYPES:
|
||||
products.get(measure_type)
|
||||
contingency_rate(measure_type)
|
||||
|
||||
|
||||
def test_run_one_threads_a_current_market_value_onto_the_plan() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue