diff --git a/etl/customers/gla_croydon_demo/asset_list.py b/etl/customers/gla_croydon_demo/asset_list.py index 52e9422c..777cba83 100644 --- a/etl/customers/gla_croydon_demo/asset_list.py +++ b/etl/customers/gla_croydon_demo/asset_list.py @@ -34,6 +34,10 @@ def app(): low_memory=False ) + z = epc_data.groupby(["MAINHEAT_DESCRIPTION", "MAINHEATCONT_DESCRIPTION", "MAIN_FUEL"]).size().reset_index( + name="count") + z = z[z["MAINHEAT_DESCRIPTION"] == "Boiler and radiators, mains gas"] + # Filter on entries where we have a UPRN epc_data = epc_data[~pd.isnull(epc_data["UPRN"])] diff --git a/recommendations/HeatingRecommender.py b/recommendations/HeatingRecommender.py index 2c075820..f602ecab 100644 --- a/recommendations/HeatingRecommender.py +++ b/recommendations/HeatingRecommender.py @@ -5,6 +5,7 @@ from recommendations.recommendation_utils import check_simulation_difference from backend.Property import Property from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes from etl.epc_clean.epc_attributes.HotWaterAttributes import HotWaterAttributes +from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes from recommendations.HeatingControlRecommender import HeatingControlRecommender @@ -44,7 +45,7 @@ class HeatingRecommender: ] and self.property.data["mains-gas-flag"] if has_boiler or no_heating_has_mains: - self.recommend_boiler_upgrades(phase=phase) + self.recommend_boiler_upgrades(phase=phase, no_heating_has_mains=no_heating_has_mains) return @staticmethod @@ -250,17 +251,20 @@ class HeatingRecommender: return closest_size - def recommend_boiler_upgrades(self, phase): + def recommend_boiler_upgrades(self, phase, no_heating_has_mains): """ This boiler recommendation will only recommend a like-for-like upgrade, since changing the system is generally more expensive :param phase: + :param no_heating_has_mains: indicaes if the property has no heating system, but has access to the mains gas :return: """ recommendation_phase = phase # We now recommend boiler upgrades, if applicable + simulation_config = {} + boiler_costs = {} if self.property.data["mainheat-energy-eff"] in ["Very Poor", "Poor", "Average"]: boiler_size = self.estimate_boiler_size( property_type=self.property.data["property-type"], @@ -272,21 +276,20 @@ class HeatingRecommender: # If heating and hot water come from the mains, we need a combi boiler, otherwise we need a regular boiler hotwater_from_mains = self.property.hotwater["clean_description"] in ["From main system"] - access_to_mains_no_system = self.property.main_heating["clean_description"] in [ - 'No system present, electric heaters assumed' - ] and self.property.data["mains-gas-flag"] - is_combi = hotwater_from_mains or access_to_mains_no_system + + is_combi = hotwater_from_mains or no_heating_has_mains if is_combi: description = "Upgrade to a new combi boiler" else: description = "Upgrade to a new boiler" simulation_config = {"mainheat_energy_eff_ending": "Good"} - if access_to_mains_no_system: + if no_heating_has_mains: # Installation of a boiler improves the hot water system so we need to reflect this in # the outcome of the recommendation heating_ending_config = MainHeatAttributes("Boiler and radiators, mains gas").process() hotwater_ending_config = HotWaterAttributes("From main system").process() + fuel_ending_config = MainFuelAttributes("mains gas (not community)").process() heating_simulation_config = check_simulation_difference( new_config=heating_ending_config, old_config=self.property.main_heating @@ -294,14 +297,20 @@ class HeatingRecommender: hotwater_simulation_config = check_simulation_difference( new_config=hotwater_ending_config, old_config=self.property.hotwater ) + fuel_simulation_config = check_simulation_difference( + new_config=fuel_ending_config, old_config=self.property.main_fuel + ) simulation_config = { **simulation_config, **heating_simulation_config, **hotwater_simulation_config, + **fuel_simulation_config, "hot_water_energy_eff_ending": "Good" } + boiler_costs = self.costs.low_carbon_boiler(is_combi=is_combi, size=f"{boiler_size}kw") + self.recommendations.append( { "phase": recommendation_phase, @@ -314,22 +323,45 @@ class HeatingRecommender: "new_u_value": None, "sap_points": None, "simulation_config": simulation_config, - **self.costs.low_carbon_boiler(is_combi=is_combi, size=f"{boiler_size}kw") + **boiler_costs } ) - # We increment the recommendation phase, in the case of us having heating control recommendations - recommendation_phase += 1 - # We recommend the heating controls + # If the property did not previously have a boiler, we combine controls_recommender = HeatingControlRecommender(self.property) controls_recommender.recommend(heating_description="Boiler and radiators, mains gas") # We may have 2 recommendations from the heating controls - if controls_recommender.recommendation: + if not controls_recommender.recommendation: + return + + if no_heating_has_mains: + # We combine the heating and controls recommendations + boiler_recommendation = self.recommendations[0].copy() + combined_recommendations = [] + for controls_recommendation in controls_recommender.recommendation: + combined_recommendation = self.combine_heating_and_controls( + controls_recommendations=[controls_recommendation], + heating_simulation_config=simulation_config, + costs=boiler_costs, + description=boiler_recommendation["description"], + phase=recommendation_phase, + heating_controls_only=False, + system_change=True + ) + combined_recommendations.extend(combined_recommendation) + + # Overwrite the existing boiler recommendation + self.recommendations = combined_recommendations + else: + # We increment the recommendation phase, since the heating controls are separate from the boiler upgrade + recommendation_phase += 1 # The heating controls recommendation is distrinct from the boiler upgrade recommendation # We insert phase into the recommendations for heating controls for recommendation in controls_recommender.recommendation: recommendation["phase"] = recommendation_phase - self.recommendations.extend(controls_recommender.recommendation) + self.recommendations.extend(controls_recommender.recommendation) + + return