diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index 89a41456..3f32da25 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -95,17 +95,25 @@ class SolarPvRecommendations: else: raise Exception("IMPLEMENT ME") + # We get solar PV options + solar_product = [x for x in self.panels_products if x["id"] == recommendation_config["solar_product_id"]] + if not solar_product: + raise NotImplementedError( + f"Solar product with id {recommendation_config['solar_product_id']} not found in " + "panels_products" + ) + solar_product = solar_product[0] + n_floors = ( self.property.number_of_storeys["number_of_storeys"] if self.property.number_of_storeys["number_of_storeys"] is not None else 3 ) total_cost = self.costs.solar_pv( - array_cost=recommendation_config.get("cost", None), - n_panels=recommendation_config["n_panels"], + solar_product=solar_product, + scaffolding_options=self.scaffolding_options, n_floors=n_floors, - needs_inverter=True, - )["total"] / n_units + )["total"] kw = np.floor(recommendation_config["array_wattage"] / 100) / 10 # Default to a weeks work for a team of 3 people doing 8 hour days @@ -137,10 +145,29 @@ class SolarPvRecommendations: "has_battery": False, "initial_ac_kwh_per_year": initial_ac_kwh_per_year, "description_simulation": {"photo-supply": roof_coverage_percent}, - "rank": rank # Rank is used to get the representative recommendation - rank 0 will be chosen + "rank": rank, # Rank is used to get the representative recommendation - rank 0 will be chosen + "innovation_rate": solar_product["innovation_rate"], } ) + def _get_available_products(self, n_panels): + """ + Utility function to get the available solar PV products based on the number of panels + :param n_panels: + :return: + """ + available_products = [] + for panel_size in self.PANEL_SIZES: + system_size = (n_panels * panel_size) / 1000 + 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) + + return available_products + def recommend(self, phase): """ We check if a property is potentially suitable for solar PV based on the following criteria: @@ -195,15 +222,9 @@ class SolarPvRecommendations: # We combine each of these configurations with estimates with and without a battery for rank, recommendation_config in solar_configurations.iterrows(): - available_products = [] - for panel_size in self.PANEL_SIZES: - system_size = (n_panels * panel_size) / 1000 - 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) + n_panels = recommendation_config["n_panels"] + + available_products = self._get_available_products(n_panels) # Given the available products in the database, we product the possible array of recommendations for solar_pv_product in available_products: @@ -235,10 +256,8 @@ class SolarPvRecommendations: # 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, + solar_product=solar_pv_product, scaffolding_options=self.scaffolding_options, n_floors=self.property.number_of_floors )