From 03854595cd4f2b34ef03643463bed2e6b7ea95f6 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 18 Aug 2025 16:49:50 +0100 Subject: [PATCH] updating solar pv recommendations --- recommendations/SolarPvRecommendations.py | 63 +++++++++++++---------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index c5a1d7d0..89a41456 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -34,7 +34,7 @@ class SolarPvRecommendations: ] ) - PANEL_SIZES = [400, 435, 440] + PANEL_SIZES = [400, 435, 440, 445] def __init__(self, property_instance, materials: list): """ @@ -153,8 +153,6 @@ class SolarPvRecommendations: if not self.property.is_solar_pv_valid(): return - raise ValueError("DOO BUILDING") - # If we have a buiilding level analysis, we implement separate logic if self.property.building_id is not None: self.recommend_building_analysis(phase) @@ -196,36 +194,49 @@ class SolarPvRecommendations: # We combine each of these configurations with estimates with and without a battery for rank, recommendation_config in solar_configurations.iterrows(): - roof_coverage_percent = round(recommendation_config["panneled_roof_area"] / roof_area * 100) - # We round up to the nearest 5 - roof_coverage_percent = np.ceil(roof_coverage_percent / 5) * 5 - # Typically, we've observed that every 5% of additional roof coverage will result in at least - # an additional 1 SAP points (though often 2 points) Given this, we can add a reasonable minimum - # for the number of SAP points we might expect. We've observed that for some cases where properties - # are hitting the higher SAP scores (e.g. EPC A and above), the model can sometimes under-predict - # the number of SAP points. This appears to be due to a relatively small number of properties - # actually achieving the upper echelons of EPC rating. This can be the case if we're simulating a - # whole house retrofit where the home is getting complete insulation, a heat pump and solar panels. - # Because panels are the final recommendation, they are often the measure that takes the home - # into the medium to high EPC A ranges and so because of a lack of training data, this means that - # we might sometime under-predict. This minimum is intended to try and reduce the negative impact - # of this. This minimum is used in Recommendations.calculate_recommendation_impact - minimum_sap_points = (roof_coverage_percent / 5) * self.SAP_POINTS_PER_5_PERCENT_ROOF_COVERAGE - - n_panels = recommendation_config["n_panels"] - - # Different panel sizes: 400, 435, 440 available_products = [] for panel_size in self.PANEL_SIZES: system_size = (n_panels * panel_size) / 1000 - available_products.extend([ + prods = [ x for x in self.panels_products if abs(x["size"] - system_size) < 0.01 - ]) + ] + for x in prods: + x["panel_size"] = panel_size + available_products.extend(prods) # Given the available products in the database, we product the possible array of recommendations for solar_pv_product in available_products: + # we take the paneled roof area and this tells us the roof coverage, based on 400W panels + # We then look at the equivalent for larger panels, which will produce more energy in the same area + + paneled_roof_area = recommendation_config["panneled_roof_area"] + + roof_coverage_percent = round( + ((paneled_roof_area / 400) * solar_pv_product["panel_size"]) / roof_area * 100 + ) + # We round up to the nearest 5 + roof_coverage_percent = np.ceil(roof_coverage_percent / 5) * 5 + + # Note roof_coverage_percent is based on 400 watt panels, so we need to scale it up based on + # largest panels that will produce more energy in the same area + + # Typically, we've observed that every 5% of additional roof coverage will result in at least + # an additional 1 SAP points (though often 2 points) Given this, we can add a reasonable minimum + # for the number of SAP points we might expect. We've observed that for some cases where properties + # are hitting the higher SAP scores (e.g. EPC A and above), the model can sometimes under-predict + # the number of SAP points. This appears to be due to a relatively small number of properties + # actually achieving the upper echelons of EPC rating. This can be the case if we're simulating a + # whole house retrofit where the home is getting complete insulation, a heat pump and solar panels. + # Because panels are the final recommendation, they are often the measure that takes the home + # into the medium to high EPC A ranges and so because of a lack of training data, this means that + # we might sometime under-predict. This minimum is intended to try and reduce the negative impact + # of this. This minimum is used in Recommendations.calculate_recommendation_impact + minimum_sap_points = (roof_coverage_percent / 5) * self.SAP_POINTS_PER_5_PERCENT_ROOF_COVERAGE + + n_panels = recommendation_config["n_panels"] + cost_result = self.costs.solar_pv( product=solar_pv_product, scaffolding_options=self.scaffolding_options, @@ -252,10 +263,6 @@ class SolarPvRecommendations: "sap_points": minimum_sap_points, "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 - "photo_supply": roof_coverage_percent, "has_battery": has_battery, "initial_ac_kwh_per_year": recommendation_config["initial_ac_kwh_per_year"], "description_simulation": {"photo-supply": roof_coverage_percent},