mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
paused for the moment
This commit is contained in:
parent
3ccc5eae89
commit
fe193305e6
3 changed files with 120 additions and 29 deletions
|
|
@ -12,6 +12,8 @@ class Funding:
|
|||
and flag any tenant specific requirements that need to be considered to the funding to be attained
|
||||
"""
|
||||
|
||||
SCHEMES = ["eco4", "gbis", "whlg"]
|
||||
|
||||
ECO_SAP_SCORE_THREHOLDS = [
|
||||
{'Band': 'High_A', 'From': 96.0, 'Up to': 100.0, 'Mid-point': 98.0},
|
||||
{'Band': 'Low_A', 'From': 92.0, 'Up to': 96.0, 'Mid-point': 94.0},
|
||||
|
|
@ -34,10 +36,12 @@ class Funding:
|
|||
tenure: HousingType,
|
||||
starting_epc,
|
||||
starting_sap,
|
||||
postcode,
|
||||
floor_area,
|
||||
council_tax_band,
|
||||
property_recommendations,
|
||||
project_scores_matrix,
|
||||
whlg_eligible_postcodes,
|
||||
gbis_abs_rate: int,
|
||||
eco4_abs_rate: int,
|
||||
):
|
||||
|
|
@ -47,6 +51,10 @@ class Funding:
|
|||
:param starting_epc: The current EPC rating of the property
|
||||
:param starting_sap: The current SAP score for the property
|
||||
:param floor_area: The total floor area of the property
|
||||
:param council_tax_band: The council tax band of the property
|
||||
:param property_recommendations: The recommendations for the property
|
||||
:param project_scores_matrix: The matrix of project scores for ECO4
|
||||
:param whlg_eligible_postcodes: The postcodes eligible for WHLG
|
||||
:param gbis_abs_rate: The assumed £/abs achieved by the installer for GBIS
|
||||
:param eco4_abs_rate: The assumed £/abs achieved by the installer for ECO4
|
||||
"""
|
||||
|
|
@ -58,6 +66,7 @@ class Funding:
|
|||
self.tenure = tenure
|
||||
self.starting_epc = starting_epc
|
||||
self.starting_sap = starting_sap
|
||||
self.postcode = postcode
|
||||
self.starting_eco_band = self.sap_to_eco_band(self.starting_sap)
|
||||
self.floor_area_segment = self.classify_floor_area(floor_area)
|
||||
self.gbis_abs_rate = gbis_abs_rate
|
||||
|
|
@ -75,6 +84,11 @@ class Funding:
|
|||
(project_scores_matrix["Starting Band"] == self.starting_eco_band)
|
||||
]
|
||||
|
||||
# The postcode column is already lower case
|
||||
self.whlg_eligible_postcodes = whlg_eligible_postcodes[
|
||||
whlg_eligible_postcodes["Postcode"] == self.postcode.lower()
|
||||
]
|
||||
|
||||
# Store the final outputs
|
||||
self.gbis_eligibiltiy = {}
|
||||
self.eco4_eligibility = {}
|
||||
|
|
@ -82,6 +96,8 @@ class Funding:
|
|||
|
||||
def output(
|
||||
self,
|
||||
scheme: str,
|
||||
eligible: bool,
|
||||
measure_types: List[str],
|
||||
estimated_funding: float,
|
||||
notify_tenant_benefits_requirements: bool,
|
||||
|
|
@ -90,12 +106,18 @@ class Funding:
|
|||
):
|
||||
""""
|
||||
"""
|
||||
|
||||
if scheme not in self.SCHEMES:
|
||||
raise ValueError("Scheme not recognised")
|
||||
|
||||
return {
|
||||
"scheme": scheme,
|
||||
"eligible": eligible,
|
||||
"measure_types": measure_types,
|
||||
"estimated_funding": estimated_funding,
|
||||
"notify_tenant_benefits_requirements": notify_tenant_benefits_requirements,
|
||||
"notify_council_tax_band_requirements": notify_council_tax_band_requirements,
|
||||
"notify_tenant_low_income_requirements": notify_tenant_low_income_requirements
|
||||
"requires_benefits": notify_tenant_benefits_requirements,
|
||||
"requires_council_tax_band": notify_council_tax_band_requirements,
|
||||
"requires_low_income": notify_tenant_low_income_requirements
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -234,6 +256,8 @@ class Funding:
|
|||
# If the council tax band is missing, we nofify the customer that this is a requirement that
|
||||
# should be checked
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
measure_types=[recommended_measure["measure_type"]],
|
||||
estimated_funding=recommended_measure["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=False,
|
||||
|
|
@ -251,6 +275,8 @@ class Funding:
|
|||
# We find the best measure for GBIS
|
||||
recommended_measure = self.find_best_gbis_measure(measures=valid_measures)
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=True,
|
||||
measure_types=[recommended_measure["measure_type"]],
|
||||
estimated_funding=recommended_measure["estimated_funding"],
|
||||
notify_tenant_benefits_requirements=True,
|
||||
|
|
@ -260,6 +286,8 @@ class Funding:
|
|||
|
||||
# Otherwise, no funding availability
|
||||
return self.output(
|
||||
scheme="gbis",
|
||||
eligible=False,
|
||||
measure_types=[],
|
||||
estimated_funding=0,
|
||||
notify_tenant_benefits_requirements=False,
|
||||
|
|
@ -279,6 +307,23 @@ class Funding:
|
|||
|
||||
raise NotImplementedError("Implement social/oo")
|
||||
|
||||
def whlg(self):
|
||||
if self.tenure == "Social":
|
||||
# We can't do anything for social housing
|
||||
self.whlg_eligibility = self.output(
|
||||
scheme="whlg",
|
||||
eligible=False,
|
||||
measure_types=[],
|
||||
estimated_funding=0,
|
||||
notify_tenant_benefits_requirements=False,
|
||||
notify_council_tax_band_requirements=False,
|
||||
notify_tenant_low_income_requirements=False
|
||||
)
|
||||
return
|
||||
|
||||
if not self.whlg_eligible_postcodes.empty:
|
||||
print("Eligible implement me!")
|
||||
|
||||
def eco4(self):
|
||||
if self.tenure == "Private":
|
||||
self.eco4_eligibiltiy = self.eco4_prs()
|
||||
|
|
@ -292,4 +337,4 @@ class Funding:
|
|||
|
||||
self.gbis()
|
||||
# self.eco4()
|
||||
# self.whlg()
|
||||
self.whlg()
|
||||
|
|
|
|||
|
|
@ -388,15 +388,26 @@ def extract_property_request_data(
|
|||
return patch, property_already_installed, property_non_invasive_recommendations, property_valution
|
||||
|
||||
|
||||
def get_eco_project_scores_matrix():
|
||||
data = read_csv_from_s3(
|
||||
def get_funding_data():
|
||||
"""
|
||||
This function retrieves the eco project scores matrix and the warm homes local grant funding data
|
||||
:return:
|
||||
"""
|
||||
project_scores_matrix = read_csv_from_s3(
|
||||
bucket_name=get_settings().DATA_BUCKET,
|
||||
filepath="funding/ECO4 Full Project Scores Matrix.csv",
|
||||
)
|
||||
df = pd.DataFrame(data)
|
||||
df.columns = ['Floor Area Segment', 'Starting Band', 'Finishing Band', 'Cost Savings']
|
||||
df["Cost Savings"] = df["Cost Savings"].astype(float)
|
||||
return df
|
||||
project_scores_matrix = pd.DataFrame(project_scores_matrix)
|
||||
project_scores_matrix.columns = ['Floor Area Segment', 'Starting Band', 'Finishing Band', 'Cost Savings']
|
||||
project_scores_matrix["Cost Savings"] = project_scores_matrix["Cost Savings"].astype(float)
|
||||
|
||||
whlg_eligible_postcodes = read_csv_from_s3(
|
||||
bucket_name=get_settings().DATA_BUCKET,
|
||||
filepath="funding/whlg eligible postcodes.csv",
|
||||
)
|
||||
whlg_eligible_postcodes = pd.DataFrame(whlg_eligible_postcodes)
|
||||
|
||||
return project_scores_matrix, whlg_eligible_postcodes
|
||||
|
||||
|
||||
router = APIRouter(
|
||||
|
|
@ -544,7 +555,7 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
logger.info("Reading in materials and cleaned datasets")
|
||||
materials = get_materials(session)
|
||||
cleaned = get_cleaned()
|
||||
eco_project_scores_matrix = get_eco_project_scores_matrix()
|
||||
eco_project_scores_matrix, whlg_eligible_postcodes = get_funding_data()
|
||||
|
||||
kwh_client = KwhData(bucket=get_settings().DATA_BUCKET, read_consumption_data=True)
|
||||
|
||||
|
|
@ -688,9 +699,7 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
|
||||
# Insert the predictions into the recommendations and run the optimiser
|
||||
# TODO: If a recommendation has a negative impact on SAP, we should remove it - this seems to have become a
|
||||
# possibility with heating system
|
||||
# TODO: After optimising, if there are any cheap, quick win measures (e.g. insulate water tank with hot water
|
||||
# cylinder jacket), we should add these to the recommendations as default
|
||||
# possibility with heating system?
|
||||
|
||||
for p in input_properties:
|
||||
if not recommendations.get(p.id):
|
||||
|
|
@ -802,21 +811,23 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
# Funding
|
||||
# ~~~~~~~~~~~~~~~~
|
||||
|
||||
# for p in input_properties:
|
||||
# funding_calulator = Funding(
|
||||
# tenure=body.housing_type,
|
||||
# starting_epc=p.data["current-energy-rating"],
|
||||
# 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],
|
||||
# project_scores_matrix=eco_project_scores_matrix,
|
||||
# gbis_abs_rate=20,
|
||||
# eco4_abs_rate=20,
|
||||
# )
|
||||
# funding_calulator.check_eligibiltiy()
|
||||
# # Insert finding
|
||||
# p.insert_funding(funding_calulator)
|
||||
for p in input_properties:
|
||||
funding_calulator = Funding(
|
||||
tenure=body.housing_type,
|
||||
starting_epc=p.data["current-energy-rating"],
|
||||
starting_sap=int(p.data["current-energy-efficiency"]),
|
||||
postcode=p.postcode,
|
||||
floor_area=p.floor_area,
|
||||
council_tax_band=None, # This is seemingly always None at the moment
|
||||
property_recommendations=recommendations[p.id],
|
||||
project_scores_matrix=eco_project_scores_matrix,
|
||||
whlg_eligible_postcodes=whlg_eligible_postcodes,
|
||||
gbis_abs_rate=20,
|
||||
eco4_abs_rate=15,
|
||||
)
|
||||
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
|
||||
|
|
|
|||
35
etl/funding/app.py
Normal file
35
etl/funding/app.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
"""
|
||||
This scipt prepares the data, required for us to perform funding calculations. The starting data should be stored
|
||||
on the machine this is being run on, and this will prepare the information and upload if
|
||||
"""
|
||||
import pandas as pd
|
||||
from utils.s3 import save_csv_to_s3
|
||||
|
||||
STAGE = "dev"
|
||||
DATA_BUCKET = "retrofit-data-{stage}"
|
||||
PROJECTS_SCORES_MATRIX_LOCATION = "/Users/khalimconn-kowlessar/Downloads/ECO4 Full Project Scores Matrix.csv"
|
||||
WHLG_ELIGIBLE_POSTCODES = "/Users/khalimconn-kowlessar/Downloads/WHLG-eligible-postcodes.xlsx"
|
||||
|
||||
|
||||
def app():
|
||||
# Read in the project scores matrix
|
||||
project_scores_matrix = pd.read_csv(PROJECTS_SCORES_MATRIX_LOCATION)
|
||||
|
||||
# Store in AWS S3
|
||||
save_csv_to_s3(
|
||||
dataframe=project_scores_matrix,
|
||||
bucket_name=DATA_BUCKET.format(stage=STAGE),
|
||||
file_name="funding/ECO4 Full Project Scores Matrix.csv"
|
||||
)
|
||||
|
||||
# Read in the Warm Homes Local Grant eligible postcodes data
|
||||
whlg_eligible_postcodes = pd.read_excel(WHLG_ELIGIBLE_POSTCODES, sheet_name="Eligible postcodes", header=1)
|
||||
# We tidy up the data before we store
|
||||
whlg_eligible_postcodes = whlg_eligible_postcodes[["Postcode"]]
|
||||
whlg_eligible_postcodes["Postcode"] = whlg_eligible_postcodes["Postcode"].str.lower()
|
||||
|
||||
save_csv_to_s3(
|
||||
dataframe=whlg_eligible_postcodes,
|
||||
bucket_name=DATA_BUCKET.format(stage=STAGE),
|
||||
file_name="funding/whlg eligible postcodes.csv"
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue