diff --git a/applications/modelling_e2e/handler.py b/applications/modelling_e2e/handler.py index 95af5269..d45951e3 100644 --- a/applications/modelling_e2e/handler.py +++ b/applications/modelling_e2e/handler.py @@ -195,9 +195,7 @@ def handler(body: dict[str, Any], context: Any) -> None: ).fetchall() uprns: dict[int, int] = {int(row[0]): int(row[1]) for row in uprn_rows} - postcodes: dict[int, str] = { - int(row[0]): (row[1] or "") for row in postcode_rows - } + postcodes: dict[int, str] = {int(row[0]): (row[1] or "") for row in postcode_rows} overrides_reader = PropertyOverridesPostgresReader(lambda: Session(engine)) prediction_attrs_reader = OverrideBackedPredictionAttributesReader(overrides_reader) @@ -222,9 +220,7 @@ def handler(body: dict[str, Any], context: Any) -> None: try: uprn = uprns[property_id] postcode = postcodes.get(property_id, "") - logger.info( - f"property={property_id} uprn={uprn} postcode={postcode!r}" - ) + logger.info(f"property={property_id} uprn={uprn} postcode={postcode!r}") spatial = _spatial_for(geospatial, uprn) restrictions = ( @@ -283,16 +279,16 @@ def handler(body: dict[str, Any], context: Any) -> None: ).effective_epc solar_insights: Optional[dict[str, Any]] = ( - None - if no_solar - else _solar_insights_for(solar_client, spatial) + None if no_solar else _solar_insights_for(solar_client, spatial) ) # secondary_heating_removal is absent from the live material.type # enum; exclude unconditionally until the catalogue gap is resolved. - considered: Optional[frozenset[MeasureType]] = frozenset( - MeasureType - ) - {MeasureType.SECONDARY_HEATING_REMOVAL} + considered: Optional[frozenset[MeasureType]] = ( + frozenset(MeasureType) + - {MeasureType.SECONDARY_HEATING_REMOVAL} + - {MeasureType.SYSTEM_TUNE_UP_ZONED} + ) plan = run_modelling( effective_epc, diff --git a/applications/modelling_e2e/local_handler/invoke_local_lambda.py b/applications/modelling_e2e/local_handler/invoke_local_lambda.py index c667ffc6..b9a0d584 100644 --- a/applications/modelling_e2e/local_handler/invoke_local_lambda.py +++ b/applications/modelling_e2e/local_handler/invoke_local_lambda.py @@ -12,7 +12,7 @@ payload = { { "body": json.dumps( { - "property_ids": [709773, 709774], + "property_ids": [722473], "portfolio_id": 796, "scenario_id": 1268, "no_solar": False, diff --git a/domain/modelling/generators/heating_recommendation.py b/domain/modelling/generators/heating_recommendation.py index 475039df..9eae0353 100644 --- a/domain/modelling/generators/heating_recommendation.py +++ b/domain/modelling/generators/heating_recommendation.py @@ -284,6 +284,7 @@ def recommend_heating( epc: EpcPropertyData, products: ProductRepository, restrictions: PlanningRestrictions = PlanningRestrictions(), + considered_measures: Optional[frozenset[MeasureType]] = None, ) -> Optional[Recommendation]: """Return a "Heating & Hot Water" Recommendation of competing whole-system bundles for the dwelling, else None when no bundle is eligible. ASHP is @@ -302,7 +303,7 @@ def recommend_heating( if boiler_option is not None: options.append(boiler_option) - options.extend(_system_tune_up_options(epc, products)) + options.extend(_system_tune_up_options(epc, products, considered_measures)) if not options: return None @@ -310,7 +311,9 @@ def recommend_heating( def _system_tune_up_options( - epc: EpcPropertyData, products: ProductRepository + epc: EpcPropertyData, + products: ProductRepository, + considered_measures: Optional[frozenset[MeasureType]] = None, ) -> list[MeasureOption]: """The system tune-up options: keep the existing wet boiler but install better heating controls (standard 2106 and/or zone 2110, as competing @@ -338,7 +341,10 @@ def _system_tune_up_options( ), ) ) - if control_code not in _ZONE_CONTROL_CODES: + if control_code not in _ZONE_CONTROL_CODES and ( + considered_measures is None + or _SYSTEM_TUNE_UP_ZONED_MEASURE_TYPE in considered_measures + ): options.append( _tune_up_option( epc, diff --git a/orchestration/modelling_orchestrator.py b/orchestration/modelling_orchestrator.py index 55ae531d..e3180a4d 100644 --- a/orchestration/modelling_orchestrator.py +++ b/orchestration/modelling_orchestrator.py @@ -331,7 +331,7 @@ def _candidate_recommendations( MeasureType.SYSTEM_TUNE_UP, MeasureType.SYSTEM_TUNE_UP_ZONED, ), - lambda: recommend_heating(effective_epc, products, planning_restrictions), + lambda: recommend_heating(effective_epc, products, planning_restrictions, considered_measures), ), ( admitted(MeasureType.SECONDARY_HEATING_REMOVAL),