diff --git a/backend/Property.py b/backend/Property.py index 2098a2a4..f5123b96 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -1334,3 +1334,49 @@ class Property: has_air_source_heat_pump = self.main_heating["has_air_source_heat_pump"] return suitable_property_type and not has_air_source_heat_pump + + def estimate_electrical_consumption(self, assumed_ashp_efficiency, exclusions): + """ + Given a property, this method estimates the electrical consumption of the property, based on the energy + consumption, the assumed efficiency of an ASHP and the exclusions. + + What we're trying to do here is size up the future electricicty demand of the property, assuming that the + home is eligible for an ASHP. If the property is not eligible for an ASHP, we don't need to adjust the + consumption. + + This figure is used to size up solar panels, so they can cover heat generation, even if the property + today doesn't generate its heat from electricity + + :param assumed_ashp_efficiency: + :param exclusions: + :return: + """ + + exclusions = [] if exclusions is None else exclusions + + if (self.main_fuel["fuel_type"] == "electricity") or ( + self.main_fuel["fuel_type"] == "mains gas" and not self.is_ashp_valid(exclusions=exclusions) + ): + # if the primary fuel is already electricity, we don't need to adjust the consumpion + return self.current_adjusted_energy + + if self.main_fuel["fuel_type"] == "mains gas" and self.is_ashp_valid(exclusions=exclusions): + # if the primary fuel is gas, we need to adjust the consumption to reflect the expected + # efficiency of an ASHP. + # We should adjust the energy consumption to reflect the 200-400% efficiency of an ASHP with + # electrified heating, so that the solar panel can cover heating generation. + heating_consumption = self.energy_consumption_estimates["adjusted"]["heating"] + hot_water_consumption = self.energy_consumption_estimates["adjusted"]["hot_water"] + + systems_consumptions = heating_consumption + hot_water_consumption + + adjusted_consumption = systems_consumptions / (assumed_ashp_efficiency / 100) + electric_consumption = ( + adjusted_consumption + + self.energy_consumption_estimates["adjusted"]["lighting"] + + self.energy_consumption_estimates["adjusted"]["appliances"] + ) + + return electric_consumption + + raise NotImplementedError("Have not implemented estimating electrical consumption for this fuel type") diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index e21226fa..68dcb916 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -437,9 +437,11 @@ async def trigger_plan(body: PlanTriggerRequest): # We set the target rating to EPC C, which is the typical EPC rating we would expect the # property to achieve post retrofit of just the fabric "energy_consumption": energy_consumption_client.estimate_new_consumption( - current_rating=p.data["current-energy-rating"], - target_rating="C", - current_consumption=p.current_adjusted_energy + current_energy_efficiency=p.data["current-energy-efficiency"], + target_efficiency="C", + current_consumption=p.estimate_electrical_consumption( + assumed_ashp_efficiency=300, exclusions=body.exclusions + ) ), "property_id": p.id, "uprn": p.uprn @@ -514,56 +516,23 @@ async def trigger_plan(body: PlanTriggerRequest): # TODO: Complete me! - we probably won't do this for individual flats - IGNORE FLATS FROM THIS WITHOUT # BUILDING IDS - # if the property is already very close to an EPC C, we don't adjust the energy consumption based on - # expected movement to EPC C. - # To extend this, what we could do is adjust the based on the expected movement from the current SAP - # rating to the target SAP rating (ie 69C) - # TODO: Update this! - energy_consumption = energy_consumption_client.estimate_new_consumption( - current_energy_efficiency=p.data["current-energy-efficiency"], - target_efficiency="69", - current_consumption=p.current_adjusted_energy + electric_consumption = p.estimate_electrical_consumption( + assumed_ashp_efficiency=300, exclusions=body.exclusions ) - def convert_to_electric_consumption(self, p, energy_consumption, assumed_ashp_efficiency, exclusions): - if (p.main_fuel["fuel_type"] == "electricity") or ( - p.main_fuel["fuel_type"] == "mains gas" and not p.is_ashp_valid(exclusions=exclusions) - ): - # if the primary fuel is already electricity, we don't need to adjust the consumpion - return energy_consumption - - if p.main_fuel["fuel_type"] == "mains gas" and p.is_ashp_valid(exclusions=exclusions): - # if the primary fuel is gas, we need to adjust the consumption to reflect the expected - # efficiency of an ASHP. - # We should adjust the energy consumption to reflect the 200-400% efficiency of an ASHP with - # electrified heating, so that the solar panel can cover heating generation. - heating_consumption = p.energy_consumption_estimates["adjusted"]["heating"] - hot_water_consumption = p.energy_consumption_estimates["adjusted"]["hot_water"] - - systems_consumptions = heating_consumption + hot_water_consumption - - adjusted_consumption = systems_consumptions / (assumed_ashp_efficiency / 100) - electric_consumption = ( - adjusted_consumption + - p.energy_consumption_estimates["adjusted"]["lighting"] + - p.energy_consumption_estimates["adjusted"]["appliances"] - ) - - return electric_consumption - - # TODO: Should energy_consumption to adjusted to just electricity requirement? - # We should align our calculation of required energy consumption with expectations around decarbonising - # heating and hot water, so worse case we should take just the electrical consumption of the property - # if the property is current using gas for heating and hot water, then we should adjust the kwh demand - # to reflect the 200-400% efficiency of an ASHP with electrified heating, so that the solar panel can - # cover heating generation. While - # If the main fuel is electricity (not community) then we don't need to change the kwh demand, if it's - # gas we should adjust on the suitability of an ashp! + # We now decrease this, based on the expected energy efficiency of the property post retrofit to a C, + # which is the common level we would expect the property to reach when treating the fabric of the + # home + electric_consumption = energy_consumption_client.estimate_new_consumption( + current_energy_efficiency=p.data["current-energy-efficiency"], + target_efficiency="69", + current_consumption=electric_consumption + ) solar_performance = solar_api_client.get( longitude=p.spatial["longitude"], latitude=p.spatial["latitude"], - energy_consumption=energy_consumption, + energy_consumption=electric_consumption, is_building=False, session=session, uprn=p.uprn