diff --git a/backend/Property.py b/backend/Property.py index 2892b86e..a8ed9129 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -61,7 +61,7 @@ class Property: n_bedrooms = None def __init__( - self, id, postcode, address, epc_record, override=None, **kwargs + self, id, postcode, address, epc_record, already_installed=None, **kwargs ): self.epc_record = epc_record @@ -79,7 +79,7 @@ class Property: # of the non-invasive surveys. We reflect that this has been installed in the recommendations, but remove the # cost and instead, provide a message that the measure has already been installed - self.override = ast.literal_eval(override['overrides']) if override else [] + self.already_installed = ast.literal_eval(already_installed['already_installed']) if already_installed else [] self.uprn = epc_record.get("uprn") self.full_sap_epc = epc_record.get("full_sap_epc") diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index 08ce0dcc..49e14872 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -74,7 +74,7 @@ async def trigger_plan(body: PlanTriggerRequest): # TODO: We should store the trigger file path in the database with the plan so we can track the file that # triggered the plan - # TODO: Create the ability to congigure/switch off certain measures + # TODO: if the measure is already installed, it should actually be the very first phase try: session.begin() @@ -85,10 +85,10 @@ async def trigger_plan(body: PlanTriggerRequest): if body.patches_file_path: patches = read_csv_from_s3(bucket_name=get_settings().PLAN_TRIGGER_BUCKET, filepath=body.patches_file_path) - overrides = [] - if body.overrides_file_path: - overrides = read_csv_from_s3( - bucket_name=get_settings().PLAN_TRIGGER_BUCKET, filepath=body.overrides_file_path + already_installed = [] + if body.already_installed_file_path: + already_installed = read_csv_from_s3( + bucket_name=get_settings().PLAN_TRIGGER_BUCKET, filepath=body.already_installed_file_path ) cleaning_data = read_dataframe_from_s3_parquet( @@ -142,8 +142,9 @@ async def trigger_plan(body: PlanTriggerRequest): cleaning_data=cleaning_data ) - override = next(( - x for x in overrides if (x["address"] == config["address"]) and (x["postcode"] == config["postcode"]) + property_already_installed = next(( + x for x in already_installed if + (x["address"] == config["address"]) and (x["postcode"] == config["postcode"]) ), {}) input_properties.append( Property( @@ -151,7 +152,7 @@ async def trigger_plan(body: PlanTriggerRequest): address=epc_searcher.address_clean, postcode=epc_searcher.postcode_clean, epc_record=prepared_epc, - override=override, + already_installed=property_already_installed, **Property.extract_kwargs(config) ) ) diff --git a/backend/app/plan/schemas.py b/backend/app/plan/schemas.py index ec49e41e..76eb49d2 100644 --- a/backend/app/plan/schemas.py +++ b/backend/app/plan/schemas.py @@ -9,7 +9,7 @@ class PlanTriggerRequest(BaseModel): goal_value: str portfolio_id: int trigger_file_path: str - overrides_file_path: Optional[str] = None + already_installed_file_path: Optional[str] = None patches_file_path: Optional[str] = None exclusions: Optional[conlist(str, min_items=1)] = None diff --git a/recommendations/FireplaceRecommendations.py b/recommendations/FireplaceRecommendations.py index c1114f31..601a8eb0 100644 --- a/recommendations/FireplaceRecommendations.py +++ b/recommendations/FireplaceRecommendations.py @@ -32,8 +32,8 @@ class FireplaceRecommendations(Definitions): if number_open_fireplaces == 0: return - is_override = "sealing_open_fireplace" in self.property.override - estimated_cost = number_open_fireplaces * self.COST_OF_WORK if not is_override else 0 + already_installed = "sealing_open_fireplace" in self.property.already_installed + estimated_cost = number_open_fireplaces * self.COST_OF_WORK if not already_installed else 0 # We recommend installing two mechanical ventilation systems self.recommendation = [ @@ -45,7 +45,7 @@ class FireplaceRecommendations(Definitions): "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, "total": estimated_cost, # Take a very basic estimate of 6 hours, multipled by the number of open fireplaces to seal "labour_hours": 6 * number_open_fireplaces, diff --git a/recommendations/FloorRecommendations.py b/recommendations/FloorRecommendations.py index b7bd370c..3f764d83 100644 --- a/recommendations/FloorRecommendations.py +++ b/recommendations/FloorRecommendations.py @@ -193,8 +193,8 @@ class FloorRecommendations(Definitions): non_insulation_materials=non_insulation_materials ) - is_override = "suspended_floor_insulation" in self.property.override - if is_override: + already_installed = "suspended_floor_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) elif material["type"] == "solid_floor_insulation": @@ -204,8 +204,8 @@ class FloorRecommendations(Definitions): non_insulation_materials=non_insulation_materials ) - is_override = "solid_floor_insulation" in self.property.override - if is_override: + already_installed = "solid_floor_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) else: raise NotImplementedError("Implement me!") @@ -226,7 +226,7 @@ class FloorRecommendations(Definitions): "starting_u_value": u_value, "new_u_value": new_u_value, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **cost_result } ) diff --git a/recommendations/HeatingControlRecommender.py b/recommendations/HeatingControlRecommender.py index 63218163..d24ad811 100644 --- a/recommendations/HeatingControlRecommender.py +++ b/recommendations/HeatingControlRecommender.py @@ -168,8 +168,8 @@ class HeatingControlRecommender: description = "upgrade heating controls to Room thermostat, programmer and TRVs" - is_override = "heating_control" in self.property.override - if is_override: + already_installed = "heating_control" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) description = "Heating controls have already been upgraded, no further action needed." @@ -182,7 +182,7 @@ class HeatingControlRecommender: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, "simulation_config": simulation_config } ) @@ -228,8 +228,8 @@ class HeatingControlRecommender: description = ("Upgrade heating controls to Smart Thermostats, room sensors and smart radiator valves (time & " "temperature zone control)") - is_override = "heating_control" in self.property.override - if is_override: + already_installed = "heating_control" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) description = "Heating controls have already been upgraded, no further action needed." @@ -242,7 +242,7 @@ class HeatingControlRecommender: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, "simulation_config": simulation_config } ) diff --git a/recommendations/HeatingRecommender.py b/recommendations/HeatingRecommender.py index d83b755e..432dc6a6 100644 --- a/recommendations/HeatingRecommender.py +++ b/recommendations/HeatingRecommender.py @@ -144,8 +144,8 @@ class HeatingRecommender: recommendation_description = f"{description} and {controls_description}" - is_override = "cavity_wall_insulation" in self.property.override - if is_override: + already_installed = "cavity_wall_insulation" in self.property.already_installed + if already_installed: total_costs = override_costs(total_costs) recommendation_description = "Heating system has already been upgraded, no further action needed." @@ -159,7 +159,7 @@ class HeatingRecommender: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **total_costs, "simulation_config": recommendation_simulation_config } @@ -371,8 +371,8 @@ class HeatingRecommender: n_rooms=self.property.number_of_rooms ) - is_override = "heating" in self.property.override - if is_override: + already_installed = "heating" in self.property.already_installed + if already_installed: boiler_costs = override_costs(boiler_costs) description = "Heating system has already been upgraded, no further action needed." @@ -386,7 +386,7 @@ class HeatingRecommender: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, "simulation_config": simulation_config, **boiler_costs } diff --git a/recommendations/HotwaterRecommendations.py b/recommendations/HotwaterRecommendations.py index 88cfa932..9c5c7045 100644 --- a/recommendations/HotwaterRecommendations.py +++ b/recommendations/HotwaterRecommendations.py @@ -42,8 +42,8 @@ class HotwaterRecommendations: recommendation_cost = self.costs.hot_water_tank_insulation() - is_override = "hot_water_tank_insulation" in self.property.override - if is_override: + already_installed = "hot_water_tank_insulation" in self.property.already_installed + if already_installed: recommendation_cost = override_costs(recommendation_cost) description = "Insulation tank has already been insulated, no further action required" else: @@ -60,7 +60,7 @@ class HotwaterRecommendations: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **recommendation_cost, "simulation_config": {"hot_water_energy_eff_ending": "Average"} } diff --git a/recommendations/LightingRecommendations.py b/recommendations/LightingRecommendations.py index 9e4c8e43..31720579 100644 --- a/recommendations/LightingRecommendations.py +++ b/recommendations/LightingRecommendations.py @@ -92,8 +92,8 @@ class LightingRecommendations: heat_demand_change, carbon_change = self.estimate_lighting_impact(number_non_lel_outlets) - is_override = "low_energy_lighting" in self.property.override - if is_override: + already_installed = "low_energy_lighting" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) description = "Low energy lighting has already been installed, no further action required" @@ -105,7 +105,7 @@ class LightingRecommendations: "description": description, "starting_u_value": None, "new_u_value": None, - "is_override": is_override, + "already_installed": already_installed, # For SAP points, we use the fact that lighting is usually worth 2 points and we scale this to # the proportion of lights that will be set to low energy "sap_points": round(2 * (number_non_lel_outlets / number_lighting_outlets), 2), diff --git a/recommendations/RoofRecommendations.py b/recommendations/RoofRecommendations.py index 5ba7e82e..dc5ee7db 100644 --- a/recommendations/RoofRecommendations.py +++ b/recommendations/RoofRecommendations.py @@ -207,8 +207,8 @@ class RoofRecommendations: floor_area=self.property.insulation_floor_area, material=material ) - is_override = "loft_insulation" in self.property.override - if is_override: + already_installed = "loft_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) elif material["type"] == "flat_roof_insulation": cost_result = self.costs.flat_roof_insulation( @@ -216,8 +216,8 @@ class RoofRecommendations: material=material, non_insulation_materials=non_insulation_materials ) - is_override = "flat_roof_insulation" in self.property.override - if is_override: + already_installed = "flat_roof_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) else: raise ValueError("Invalid material type") @@ -238,7 +238,7 @@ class RoofRecommendations: "starting_u_value": u_value, "new_u_value": new_u_value, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **cost_result } ) diff --git a/recommendations/SecondaryHeating.py b/recommendations/SecondaryHeating.py index e426977e..5d763510 100644 --- a/recommendations/SecondaryHeating.py +++ b/recommendations/SecondaryHeating.py @@ -40,8 +40,8 @@ class SecondaryHeating: costs = self.costs.heater_removal(n_rooms=n_rooms) - is_override = "secondary_heating" in self.property.override - if is_override: + already_installed = "secondary_heating" in self.property.already_installed + if already_installed: costs = override_costs(costs) description = "Secondary heating system has already been removed, no further action required" else: @@ -56,7 +56,7 @@ class SecondaryHeating: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **costs, "simulation_config": { "secondheat_description_ending": "None" diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index 72fcdf4b..58cf9735 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -111,8 +111,8 @@ class SolarPvRecommendations: description = (f"Install a {kw} kilowatt-peak (kWp) solar photovoltaic (PV) p" f"anel system on {round(roof_coverage_percent)}% the roof.") - is_override = "solar_pv" in self.property.override - if is_override: + already_installed = "solar_pv" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) self.recommendation.append( @@ -124,7 +124,7 @@ class SolarPvRecommendations: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **cost_result, # This is required for simulating the SAP impact. solar_pv_percentage is between 0 & 1 so we scale # back up here diff --git a/recommendations/VentilationRecommendations.py b/recommendations/VentilationRecommendations.py index 7ffcda08..5b36bd9c 100644 --- a/recommendations/VentilationRecommendations.py +++ b/recommendations/VentilationRecommendations.py @@ -50,11 +50,11 @@ class VentilationRecommendations(Definitions): part = self.materials.copy() - is_override = "cavity_wall_insulation" in self.property.override + already_installed = "cavity_wall_insulation" in self.property.already_installed - estimated_cost = n_units * part[0]["cost"] if not is_override else 0 - labour_hours = 4 * n_units if not is_override else 0 - labour_days = 4 * n_units / 8.0 if not is_override else 0 + estimated_cost = n_units * part[0]["cost"] if not already_installed else 0 + labour_hours = 4 * n_units if not already_installed else 0 + labour_days = 4 * n_units / 8.0 if not already_installed else 0 part[0]["total"] = estimated_cost part[0]["quantity"] = n_units @@ -69,7 +69,7 @@ class VentilationRecommendations(Definitions): "description": f"Install {n_units} {part[0]['description']} units", "starting_u_value": None, "new_u_value": None, - "is_override": is_override, + "already_installed": already_installed, "sap_points": 0, "heat_demand": 0, "adjusted_heat_demand": 0, diff --git a/recommendations/WallRecommendations.py b/recommendations/WallRecommendations.py index 471a62cb..feb2620b 100644 --- a/recommendations/WallRecommendations.py +++ b/recommendations/WallRecommendations.py @@ -221,8 +221,8 @@ class WallRecommendations(Definitions): material=material.to_dict(), ) - is_override = "cavity_wall_insulation" in self.property.override - if is_override: + already_installed = "cavity_wall_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) recommendations.append( @@ -241,7 +241,7 @@ class WallRecommendations(Definitions): "starting_u_value": u_value, "new_u_value": new_u_value, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **cost_result } ) @@ -282,8 +282,8 @@ class WallRecommendations(Definitions): material=material.to_dict(), non_insulation_materials=non_insulation_materials ) - is_override = "internal_wall_insulation" in self.property.override - if is_override: + already_installed = "internal_wall_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) elif material["type"] == "external_wall_insulation": @@ -292,8 +292,8 @@ class WallRecommendations(Definitions): material=material.to_dict(), non_insulation_materials=non_insulation_materials ) - is_override = "external_wall_insulation" in self.property.override - if is_override: + already_installed = "external_wall_insulation" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) else: raise ValueError("Invalid material type") @@ -313,7 +313,7 @@ class WallRecommendations(Definitions): "description": self._make_description(material), "starting_u_value": u_value, "new_u_value": new_u_value, - "is_override": is_override, + "already_installed": already_installed, "sap_points": None, **cost_result } diff --git a/recommendations/WindowsRecommendations.py b/recommendations/WindowsRecommendations.py index b2fe20a6..b7c2823a 100644 --- a/recommendations/WindowsRecommendations.py +++ b/recommendations/WindowsRecommendations.py @@ -71,8 +71,8 @@ class WindowsRecommendations: is_secondary_glazing=is_secondary_glazing ) - is_override = "windows_glazing" in self.property.override - if is_override: + already_installed = "windows_glazing" in self.property.already_installed + if already_installed: cost_result = override_costs(cost_result) description = "The property already has double glazing installed. No further action is required." else: @@ -98,7 +98,7 @@ class WindowsRecommendations: "starting_u_value": None, "new_u_value": None, "sap_points": None, - "is_override": is_override, + "already_installed": already_installed, **cost_result, "is_secondary_glazing": is_secondary_glazing }