diff --git a/backend/Property.py b/backend/Property.py index 72d1d169..752a0868 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -62,6 +62,9 @@ class Property: n_bedrooms = None building_id = None # Used to group properties together into a single building + # Contains the solar panel optimisation results from the Google Solar API + solar_panel_configuration = None + def __init__( self, id, @@ -604,6 +607,12 @@ class Property: self.find_energy_sources() self.set_current_energy_bill(energy_consumption_client) + def set_solar_panel_configuration(self, solar_panel_configuration): + """ + This funtion inserts the solar panel configuration into the property object + """ + self.solar_panel_configuration = solar_panel_configuration + def set_current_energy_bill(self, energy_consumption_client): """ Given what we know about the property now, estimates the current energy consumption using the UCL paper diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index c3823180..e2adbed1 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -368,12 +368,12 @@ async def trigger_plan(body: PlanTriggerRequest): p.get_spatial_data(uprn_filenames) # TODO: Handle the case of modelling some units as buildings and some as properties individually - # TODO: We should adjust the energy consumtpion to account for post-retrofit energy consumption building_ids = [ { "building_id": p.building_id, "longitude": p.spatial["longitude"], "latitude": p.spatial["latitude"], + # Energy consumption is adjusted for the property's expected post retrofit state "energy_consumption": energy_consumption_client.estimate_new_consumption( current_rating=p.data["current-energy-rating"], target_rating=body.goal_value, @@ -394,6 +394,7 @@ async def trigger_plan(body: PlanTriggerRequest): if coordinate_pair not in unique_coordinates[building_id]: unique_coordinates[building_id].append(coordinate_pair) + solar_panel_configuration = {} for building_id, coordinates in unique_coordinates.items(): if len(coordinates) > 1: raise NotImplementedError("more than one coordinate for a building - handle me") @@ -402,17 +403,27 @@ async def trigger_plan(body: PlanTriggerRequest): energy_consumption = sum( [entry['energy_consumption'] for entry in building_ids if entry['building_id'] == building_id] ) - solar_performance = solar_api_client.get( + solar_api_client.get( longitude=coordinates["longitude"], latitude=coordinates["latitude"], energy_consumption=energy_consumption, is_building=True, ) + solar_panel_configuration[building_id] = { + "insights_data": solar_api_client.insights_data, + "panel_performance": solar_api_client.panel_performance, + "n_units": len([entry for entry in building_ids if entry['building_id'] == building_id]) + } + + # Insert this into the properties that have this building id + for p in input_properties: + if p.building_id == building_id: + p.set_solar_panel_configuration(solar_panel_configuration[building_id]) else: # Model the solar potential at the property level for p in input_properties: - # TODO: Complete me! + # TODO: Complete me! - we probably won't do this for individual flats solar_performance = solar_api_client.get( longitude=p.spatial["longitude"], latitude=p.spatial["latitude"] ) diff --git a/recommendations/SolarPvRecommendations.py b/recommendations/SolarPvRecommendations.py index 458eae12..3387fc7a 100644 --- a/recommendations/SolarPvRecommendations.py +++ b/recommendations/SolarPvRecommendations.py @@ -79,6 +79,11 @@ class SolarPvRecommendations: ] def is_solar_pv_valid(self): + + # If the property is a flat but we are looking at building solar potential, we can include this + if (self.property.building_id is not None) and (self.property.solar_panel_configuration is not None): + return True + is_valid_property_type = self.property.data["property-type"] in ["House", "Bungalow", "Maisonette"] is_valid_roof_type = ( self.property.roof["is_flat"] or self.property.roof["is_pitched"] or self.property.roof["is_roof_room"]