diff --git a/backend/Property.py b/backend/Property.py index cc5bf12b..0b63b266 100644 --- a/backend/Property.py +++ b/backend/Property.py @@ -22,6 +22,7 @@ from recommendations.recommendation_utils import ( ) from backend.ml_models.AnnualBillSavings import AnnualBillSavings from backend.app.utils import sap_to_epc +from backend.Funding import Funding import backend.app.assumptions as assumptions ENVIRONMENT = os.environ.get("ENVIRONMENT", "dev") @@ -202,6 +203,11 @@ class Property: # TODO: We keep this but only temporarily until we add bathrooms, bedrooms, building id to the condition data self.parse_kwargs(kwargs) + # Funding + self.gbis_eligibiltiy = None + self.eco4_eligibility = None + self.whlg_eligibility = None + @classmethod def extract_kwargs(cls, kwargs): """ @@ -1306,3 +1312,11 @@ class Property: ) return electric_consumption + + def insert_funding(self, funding_calulator: Funding): + """ + This method inserts the funding into the property object + """ + self.gbis_eligibiltiy = funding_calulator.gbis_eligibiltiy + self.eco4_eligibility = funding_calulator.eco4_eligibility + self.whlg_eligibility = funding_calulator.whlg_eligibility diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index ea831a31..849f7fd7 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -30,6 +30,7 @@ from backend.app.utils import epc_to_sap_lower_bound, sap_to_epc from backend.ml_models.api import ModelApi from backend.Property import Property +from backend.Funding import Funding from backend.apis.GoogleSolarApi import GoogleSolarApi from recommendations.optimiser.CostOptimiser import CostOptimiser @@ -751,12 +752,12 @@ async def trigger_plan(body: PlanTriggerRequest): # ~~~~~~~~~~~~~~~~ # Funding # ~~~~~~~~~~~~~~~~ - from backend.Funding import Funding + for p in input_properties: funding_calulator = Funding( tenure=body.housing_type, starting_epc=p.data["current-energy-rating"], - starting_sap=p.data["current-energy-efficiency"], + starting_sap=int(p.data["current-energy-efficiency"]), floor_area=p.floor_area, council_tax_band=None, # This is seemingly always None at the moment property_recommendations=recommendations[p.id], @@ -764,7 +765,10 @@ async def trigger_plan(body: PlanTriggerRequest): gbis_abs_rate=20, eco4_abs_rate=20, ) - + funding_calulator.check_eligibiltiy() + # Insert finding + p.insert_funding(funding_calulator) + logger.info("Uploading recommendations to the database") # If we have any work to do, we create a new scenario engine_scenario = create_scenario( diff --git a/etl/customers/connells/pilot_remote_assessments.py b/etl/customers/connells/pilot_remote_assessments.py new file mode 100644 index 00000000..9eace9c8 --- /dev/null +++ b/etl/customers/connells/pilot_remote_assessments.py @@ -0,0 +1,108 @@ +import os +import time + +from tqdm import tqdm +import pandas as pd +from dotenv import load_dotenv +from etl.find_my_epc.RetrieveFindMyEpc import RetrieveFindMyEpc +from backend.SearchEpc import SearchEpc +from utils.s3 import save_csv_to_s3 + +load_dotenv(dotenv_path="backend/.env") +EPC_AUTH_TOKEN = os.getenv("EPC_AUTH_TOKEN") +USER_ID = 8 +PORTFOLIO_ID = 123 + + +def app(): + asset_list = [ + {"address": "1 Raven Crescent", "postcode": "WV11 2EX", "uprn": 100071188496}, + + {"address": "13 Bayliss Avenue", "postcode": "WV11 2EX", "uprn": 100071136271}, + + {"address": "30 Southbourne Road", "postcode": "WV10 6ET", "uprn": 100071194376}, + + {"address": "96 Marsh Lane", "postcode": "WV10 6RX", "uprn": 100071176297}, + ] + asset_list = pd.DataFrame(asset_list) + + valuations_data = [ + {'uprn': 100071188496, "valuation": 175_000}, + {'uprn': 100090136026, "valuation": 183_000}, + {'uprn': 100071194376, "valuation": 221_000}, + {'uprn': 100071176297, "valuation": 208_000}, + ] + + # Pull the additional data + extracted_data = [] + for _, home in tqdm(asset_list.iterrows(), total=len(asset_list)): + add1 = home["address"] + pc = home["postcode"] + # Retrieve the EPC data + epc_searcher = SearchEpc( + address1=add1, + postcode=pc, uprn=home["uprn"], auth_token=EPC_AUTH_TOKEN, os_api_key="" + ) + epc_searcher.find_property(skip_os=True) + if epc_searcher.newest_epc is None: + continue + + find_epc_searcher = RetrieveFindMyEpc(address=epc_searcher.newest_epc["address1"], + postcode=epc_searcher.newest_epc["postcode"]) + find_epc_data = find_epc_searcher.retrieve_newest_find_my_epc_data() + time.sleep(0.5) + # We need uprn + + extracted_data.append( + { + "uprn": home["uprn"], + **find_epc_data, + } + ) + + non_invasive_recommendations = [ + { + "uprn": r["uprn"], + "recommendations": r["recommendations"] + } for r in extracted_data + ] + + filename = f"{USER_ID}/{PORTFOLIO_ID}/asset_list.csv" + save_csv_to_s3( + dataframe=pd.DataFrame(asset_list), + bucket_name="retrofit-plan-inputs-dev", + file_name=filename + ) + + # Store the non-invasive recommendations in s3 + non_invasive_recommendations_filename = f"{USER_ID}/{PORTFOLIO_ID}/non_invasive_recommendations.csv" + save_csv_to_s3( + dataframe=pd.DataFrame(non_invasive_recommendations), + bucket_name="retrofit-plan-inputs-dev", + file_name=non_invasive_recommendations_filename + ) + + # Store the valuations data in s3 + valuations_filename = f"{USER_ID}/{PORTFOLIO_ID}/valuations.csv" + save_csv_to_s3( + dataframe=pd.DataFrame(valuations_data), + bucket_name="retrofit-plan-inputs-dev", + file_name=valuations_filename + ) + + body = { + "portfolio_id": str(PORTFOLIO_ID), + "housing_type": "Private", + "goal": "Increasing EPC", + "goal_value": "B", + "trigger_file_path": filename, + "already_installed_file_path": "", + "patches_file_path": "", + "non_invasive_recommendations_file_path": non_invasive_recommendations_filename, + "valuation_file_path": valuations_filename, + "scenario_name": "Wave 3 Packages", + "multi_plan": True, + "budget": None, + "exclusions": [] + } + print(body)