From eec453670ceb3105d1d041f737db2125518bd27c Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Mon, 29 Jul 2024 14:56:17 +0100 Subject: [PATCH] tweaked solar ranking algorithm --- backend/apis/GoogleSolarApi.py | 8 +++++++- backend/app/assumptions.py | 3 +++ backend/app/plan/router.py | 7 ++++--- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 backend/app/assumptions.py diff --git a/backend/apis/GoogleSolarApi.py b/backend/apis/GoogleSolarApi.py index 8d08b083..074a9ece 100644 --- a/backend/apis/GoogleSolarApi.py +++ b/backend/apis/GoogleSolarApi.py @@ -311,12 +311,19 @@ class GoogleSolarApi: ) # Now that we know the lifetime cnsumption of ac kwh, we can estimate the roi + # Key things we estimate: + # - generation_value: this is the gbp value of the electricity generated + # - roi: the return on investment, calcualated as generation_value / total_cost + # - surplus: this is the amount of additional energy generated, and therefore how much will be exported + # - surplus_value: the value of the surplus energy - this feeds into generation_value, when relevant + # - expected_payback_years: the number of years it will take to pay back the initial investment lifetime_energy_consumption = energy_consumption * self.installation_life_span roi_results = [] for _, panel_config in panel_performance.iterrows(): lifetime_ac_kwh = panel_config["lifetime_ac_kwh"] surplus = 0 + generation_deficit = 0 if lifetime_ac_kwh < lifetime_energy_consumption: # We estimate the amount of electricity generated, based on the price cap generation_value = lifetime_ac_kwh * AnnualBillSavings.ELECTRICITY_PRICE_CAP @@ -329,7 +336,6 @@ class GoogleSolarApi: surplus_value = surplus * AnnualBillSavings.ELECTRICITY_EXPORT_PAYMENT generation_value = lifetime_energy_consumption * AnnualBillSavings.ELECTRICITY_PRICE_CAP roi = (generation_value + surplus_value) / panel_config["total_cost"] - generation_deficit = surplus_value # Calculate expected payback years if generation_value > 0: diff --git a/backend/app/assumptions.py b/backend/app/assumptions.py new file mode 100644 index 00000000..13bd913f --- /dev/null +++ b/backend/app/assumptions.py @@ -0,0 +1,3 @@ +# Assumes that the average efficiency of an air source heat pump is 300%, taking the median of the 200-400% range, +# which is often quoted as a sensible efficiency range for air source heat pumps. +AVERAGE_ASHP_EFFICIENCY = 300 diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index 68dcb916..c1e0b981 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -10,6 +10,7 @@ from sqlalchemy.exc import IntegrityError, OperationalError from sqlalchemy.orm import sessionmaker from starlette.responses import Response +import backend.app.assumptions as assumptions from backend.app.config import get_settings, get_prediction_buckets from backend.app.db.connection import db_engine from backend.app.db.functions.materials_functions import get_materials @@ -440,7 +441,7 @@ async def trigger_plan(body: PlanTriggerRequest): current_energy_efficiency=p.data["current-energy-efficiency"], target_efficiency="C", current_consumption=p.estimate_electrical_consumption( - assumed_ashp_efficiency=300, exclusions=body.exclusions + assumed_ashp_efficiency=assumptions.AVERAGE_ASHP_EFFICIENCY, exclusions=body.exclusions ) ), "property_id": p.id, @@ -517,7 +518,7 @@ async def trigger_plan(body: PlanTriggerRequest): # BUILDING IDS electric_consumption = p.estimate_electrical_consumption( - assumed_ashp_efficiency=300, exclusions=body.exclusions + assumed_ashp_efficiency=assumptions.AVERAGE_ASHP_EFFICIENCY, exclusions=body.exclusions ) # We now decrease this, based on the expected energy efficiency of the property post retrofit to a C, @@ -529,7 +530,7 @@ async def trigger_plan(body: PlanTriggerRequest): current_consumption=electric_consumption ) - solar_performance = solar_api_client.get( + solar_api_client.get( longitude=p.spatial["longitude"], latitude=p.spatial["latitude"], energy_consumption=electric_consumption,