diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index 3387fc7a..2de8f873 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -95,6 +95,50 @@ class SolarPvRecommendations: return is_valid_property_type and is_valid_roof_type and has_no_existing_solar_pv + def recommend_building_analysis(self, phase): + """ + This recommendation approach handles the case of producing solar PV recommendations at the building level, + across multiple flats. For these recommendations, we don't include the battery option since it's impractical + from a space perspective. + :return: + """ + + panel_performance = self.property.solar_panel_configuration["panel_performance"] + total_roof_area = ( + self.property.solar_panel_configuration["insights_data"]["solarPotential"]["wholeRoofStats"]["areaMeters2"] + ) + n_units = self.property.solar_panel_configuration["n_units"] + + best_configurations = panel_performance.head(3) + + for _, recommendation_config in best_configurations.iterrows(): + roof_coverage_percent = round(recommendation_config["panneled_roof_area"] / total_roof_area * 100) + # Spread the cost to the individual units + total_cost = recommendation_config["total_cost"] / n_units + kw = np.floor(recommendation_config["array_warrage"] / 100) / 10 + + description = (f"Install a {kw} kilowatt-peak (kWp) solar photovoltaic (PV) panel system on the roof " + "of the building") + + self.recommendation.append( + { + "phase": phase, + "parts": [], + "type": "solar_pv", + "description": description, + "starting_u_value": None, + "new_u_value": None, + "sap_points": None, + "already_installed": False, + "total_cost": total_cost, + # This is required for simulating the SAP impact. solar_pv_percentage is between 0 & 1 so we scale + # back up here + "photo_supply": roof_coverage_percent, + "has_battery": False, + "description_simulation": {"photo-supply": roof_coverage_percent} + } + ) + def recommend(self, phase): """ We check if a property is potentially suitable for solar PV based on the following criteria: @@ -107,6 +151,11 @@ class SolarPvRecommendations: if not self.is_solar_pv_valid(): return + # If we have a buiilding level analysis, we implement separate logic + if self.property.building_id is not None: + self.recommend_building_analysis(phase) + return + solar_pv_percentage = self.property.solar_pv_percentage # We round up to the neaest 10% solar_pv_percentage = np.ceil(solar_pv_percentage * 10) / 10