diff --git a/etl/customers/peabody/Nov 2025 Consulting Project/n_fixing_already_installed_bug.py b/etl/customers/peabody/Nov 2025 Consulting Project/n_fixing_already_installed_bug.py index e69de29b..5a3aad3f 100644 --- a/etl/customers/peabody/Nov 2025 Consulting Project/n_fixing_already_installed_bug.py +++ b/etl/customers/peabody/Nov 2025 Consulting Project/n_fixing_already_installed_bug.py @@ -0,0 +1,81 @@ +# 1) Need to get all already installed measures +# 2) get the unique uprns for these properties +# 3) Create a re-fresh SAL for these properties +# 4) re-trigger EPC C w/o EWI/IWI + the EPC B scenario + +from backend.app.db.models.recommendations import InstalledMeasure +from backend.app.db.connection import db_session +from etl.customers.cambridge.surveys import current_epc + +# Get all installed measures from the installedMeasure table +with db_session() as session: + # We need installed measures, where the measure type is ewi or iwi + installed_measures = session.query(InstalledMeasure).filter( + InstalledMeasure.measure_type.in_(["external_wall_insulation", "internal_wall_insulation"]) + ).all() + # Get the uprns + installed_uprns = [x.uprn for x in installed_measures] + +installed_uprns = list(set(installed_uprns)) + +# This is 21425 properties. +# We then create a portfolio of properties we need to re-run +import pandas as pd + +sal = pd.read_excel( + "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/20260113 - " + "final asset list.xlsx", + sheet_name="Standardised Asset List" +) + +needing_retry = sal[sal["epc_os_uprn"].isin(installed_uprns)] + +# Store +needing_retry.to_excel( + "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final " + "SAL/properties_needing_retry_20260115.xlsx", + sheet_name="Standardised Asset List", + index=False +) + +#### Testing +with_ewi = pd.read_excel( + "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no " + "solid floor, ashp 3.0 - 20250113 final.xlsx" +) +without_ewi = pd.read_excel( + "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no " + "solid floor, no EWI or IWI, ashp 3.0 - 20250113 final.xlsx" +) + +comparison = with_ewi.merge( + without_ewi, + left_on="uprn", + right_on="uprn", + suffixes=("_with_ewi", "_without_ewi") +) + +with_ewi = comparison[comparison["total_retrofit_cost_with_ewi"] > 0] +with_ewi["current_epc_rating_with_ewi"].value_counts() +with_ewi["current_epc_rating_with_ewi"].value_counts() + +without_ewi = comparison[comparison["total_retrofit_cost_without_ewi"] > 0] +with_ewi = comparison[comparison["total_retrofit_cost_with_ewi"] > 0] + +with_ewi[with_ewi["current_epc_rating_with_ewi"] == "Epc.C"]["uprn"] + +to_fix = with_ewi[with_ewi["current_epc_rating_with_ewi"] == "Epc.C"] +to_fix = to_fix[["uprn", "address_with_ewi", "postcode_with_ewi", "property_type_with_ewi"]].rename( + columns={ + "address_with_ewi": "address", + "postcode_with_ewi": "postcode", + "property_type_with_ewi": "property_type" + } +).merge( + sal[["epc_os_uprn", "landlord_built_form"]], + left_on="uprn", + right_on="epc_os_uprn", + how="left" +).drop(columns=["epc_os_uprn"]) + +to_fix = to_fix.to_dict("records") diff --git a/recommendations/VentilationRecommendations.py b/recommendations/VentilationRecommendations.py index a8aa0ca3..ed2f50e2 100644 --- a/recommendations/VentilationRecommendations.py +++ b/recommendations/VentilationRecommendations.py @@ -39,7 +39,7 @@ class VentilationRecommendations(Definitions): parts = self.mechanical_ventilation_materials.copy() - already_installed = "cavity_wall_insulation" in self.property.already_installed + already_installed = "mechanical_ventilation" in self.property.already_installed # TODO: We now have multiple ventilation options - we default to selecting the cheapest option part = min(parts, key=lambda x: x['total_cost']) diff --git a/recommendations/optimiser/optimiser_functions.py b/recommendations/optimiser/optimiser_functions.py index ca48d26d..a4543dbf 100644 --- a/recommendations/optimiser/optimiser_functions.py +++ b/recommendations/optimiser/optimiser_functions.py @@ -241,7 +241,8 @@ def calculate_gain( else epc_to_sap_lower_bound(body.goal_value) ) - if target_sap == current_sap: + if target_sap <= current_sap: + # We've already met or exceeded the target EPC return 0 gain = CostOptimiser.calculate_sap_gain_with_slack( diff --git a/sfr/principal_pitch/2_export_data.py b/sfr/principal_pitch/2_export_data.py index a3042a56..f12eb85d 100644 --- a/sfr/principal_pitch/2_export_data.py +++ b/sfr/principal_pitch/2_export_data.py @@ -16,13 +16,13 @@ from collections import defaultdict # SCENARIOS = [389] PORTFOLIO_ID = 435 # Peabody SCENARIOS = [ - # 908, - # 909, + 908, + 909, 910, ] scenario_names = { - # 908: "EPC C - no solid floor, ashp 3.0", - # 909: "EPC C - no solid floor, no EWI or IWI, ashp 3.0", + 908: "EPC C - no solid floor, ashp 3.0", + 909: "EPC C - no solid floor, no EWI or IWI, ashp 3.0", 910: "EPC B - no solid floor, no EWI, ashp 3.0" }