mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
debugging a recommendation for hhrsh where the property currently has underfloor heating
This commit is contained in:
parent
b81e2a4eba
commit
53e0a651c9
8 changed files with 137 additions and 3 deletions
2
.idea/Model.iml
generated
2
.idea/Model.iml
generated
|
|
@ -7,7 +7,7 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/open_uprn" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/recommendations" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="AssetList" jdkType="Python SDK" />
|
||||
<orderEntry type="jdk" jdkName="Fastapi-backend" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -3,7 +3,7 @@
|
|||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.10 (backend)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="AssetList" project-jdk-type="Python SDK" />
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Fastapi-backend" project-jdk-type="Python SDK" />
|
||||
<component name="PyCharmProfessionalAdvertiser">
|
||||
<option name="shown" value="true" />
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -96,3 +96,7 @@ class PlanTriggerRequest(BaseModel):
|
|||
# When performing a remote assessment, if this has been set, it will allow the engine to
|
||||
# pull data from the find my epc website, to utilise as part of a remote assessment
|
||||
event_type: Optional[Literal["remote_assessment"]] = None
|
||||
|
||||
# If true, before optimising the engine will select a slightly larger package, to account for the SAP 10 causing
|
||||
# scores to drop by a few points
|
||||
simulate_sap_10: Optional[bool] = False
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import backend.app.assumptions as assumptions
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ class HeatingRecommender:
|
|||
},
|
||||
# These are the heating types we need to produce a dual heating recommendation
|
||||
"dual": None
|
||||
},
|
||||
'Electric underfloor heating, electric storage heaters': {
|
||||
# For this, we would recommend a heat pump
|
||||
"dual": None
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,6 +113,10 @@ class HeatingRecommender:
|
|||
|
||||
hhr_suitable = no_mains or self.has_electric_heating_description or self.has_room_heaters
|
||||
|
||||
hhr_suitable = hhr_suitable and (
|
||||
"underfloor heating" not in self.property.main_heating["clean_description"]
|
||||
)
|
||||
|
||||
return (
|
||||
hhr_suitable and (not ashp_only_heating_recommendation) and not self.has_ashp and
|
||||
("high_heat_retention_storage_heater" in measures)
|
||||
|
|
|
|||
47
sfr/principal_pitch/0_prepare_sample.py
Normal file
47
sfr/principal_pitch/0_prepare_sample.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
"""
|
||||
This is a script for preparing a sample for testing the end to end process, so that when Spring send us
|
||||
data, we know it will work.
|
||||
"""
|
||||
|
||||
import pandas as pd
|
||||
|
||||
birmingham_epcs = pd.read_csv(
|
||||
"/Users/khalimconn-kowlessar/Documents/hestia/sfr/Spring JV/domestic-E08000025-Birmingham/certificates.csv"
|
||||
)
|
||||
|
||||
# We get the newest EPC, by UPRN and LODGEMENT_DATE
|
||||
birmingham_epcs['LODGEMENT_DATE'] = pd.to_datetime(birmingham_epcs['LODGEMENT_DATE'])
|
||||
|
||||
birmingham_epcs = birmingham_epcs.sort_values(
|
||||
by=['UPRN', 'LODGEMENT_DATE'],
|
||||
ascending=[True, False]
|
||||
).drop_duplicates(subset='UPRN')
|
||||
|
||||
# Take a sample of properties, EPC F or G, EPC lodged in 2025. We focus on houses/bingalows
|
||||
sample = birmingham_epcs[
|
||||
(birmingham_epcs['CURRENT_ENERGY_RATING'].isin(['F', 'G'])) &
|
||||
(birmingham_epcs['LODGEMENT_DATE'] >= '2025-01-01') &
|
||||
(birmingham_epcs['PROPERTY_TYPE'].isin(['House', 'Bungalow']))
|
||||
]
|
||||
|
||||
# Prepare the sample, with just the columns we would expect to receive from Spring
|
||||
# 1) UPRN
|
||||
# 2) Address
|
||||
# 3) Postcode
|
||||
# 4) Property type
|
||||
# 5) Built form
|
||||
# 6) Number of bedrooms (we'll simulate this)
|
||||
# 7) Number of bathrooms (we'll simulate this)
|
||||
# 8) Valuation (We'll simulate this, around 200,000)
|
||||
|
||||
sample = sample[['UPRN', 'ADDRESS', 'POSTCODE', 'PROPERTY_TYPE', 'BUILT_FORM']].copy()
|
||||
sample['BEDROOMS'] = 3 # Simulating number of bedrooms
|
||||
sample['BATHROOMS'] = 1 # Simulating number of bathrooms
|
||||
sample['VALUATION'] = 200000 # Simulating valuation
|
||||
sample.columns = [x.lower() for x in sample.columns]
|
||||
|
||||
# Store this as a excel
|
||||
sample.to_excel(
|
||||
"/Users/khalimconn-kowlessar/Documents/hestia/sfr/Spring JV/birmingham_sample.xlsx",
|
||||
index=False
|
||||
)
|
||||
76
sfr/principal_pitch/1_prepare_data.py
Normal file
76
sfr/principal_pitch/1_prepare_data.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"""
|
||||
This script prepares the data for the principal pitch modelling
|
||||
"""
|
||||
import os
|
||||
import pandas as pd
|
||||
from dotenv import load_dotenv
|
||||
from utils.s3 import save_csv_to_s3
|
||||
from etl.find_my_epc.AssetListEpcData import AssetListEpcData
|
||||
|
||||
load_dotenv(dotenv_path="backend/.env")
|
||||
EPC_AUTH_TOKEN = os.getenv("EPC_AUTH_TOKEN")
|
||||
PORTFOLIO_ID = 206
|
||||
USER_ID = 8
|
||||
EPC_TARGET = "C"
|
||||
|
||||
# Read the input file
|
||||
|
||||
properties = pd.read_excel(
|
||||
"/Users/khalimconn-kowlessar/Documents/hestia/sfr/Spring JV/birmingham_sample.xlsx"
|
||||
)
|
||||
|
||||
# Pull the non-invasive recommendations
|
||||
asset_list_epc_client = AssetListEpcData(
|
||||
asset_list=properties,
|
||||
epc_auth_token=EPC_AUTH_TOKEN
|
||||
)
|
||||
asset_list_epc_client.get_data()
|
||||
asset_list_epc_client.get_non_invasive_recommendations()
|
||||
asset_list_epc_client.get_patch()
|
||||
# TODO; Find some new, on-market opportunities that aren't on the EPC API, so we definitely have a patch
|
||||
|
||||
# Store the asset list in s3
|
||||
filename = f"{USER_ID}/{PORTFOLIO_ID}/asset_list.csv"
|
||||
save_csv_to_s3(
|
||||
dataframe=properties,
|
||||
bucket_name="retrofit-plan-inputs-dev",
|
||||
file_name=filename
|
||||
)
|
||||
|
||||
# Store 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(asset_list_epc_client.non_invasive_recommendations),
|
||||
bucket_name="retrofit-plan-inputs-dev",
|
||||
file_name=non_invasive_recommendations_filename
|
||||
)
|
||||
|
||||
# Store patches in S3
|
||||
patches_filename = ""
|
||||
if asset_list_epc_client.patches:
|
||||
patches_filename = f"{USER_ID}/{PORTFOLIO_ID}/patches.csv"
|
||||
save_csv_to_s3(
|
||||
dataframe=pd.DataFrame(asset_list_epc_client.patches),
|
||||
bucket_name="retrofit-plan-inputs-dev",
|
||||
file_name=patches_filename
|
||||
)
|
||||
|
||||
body = {
|
||||
"portfolio_id": str(PORTFOLIO_ID),
|
||||
"housing_type": "Private",
|
||||
"goal": "Increasing EPC",
|
||||
"goal_value": "C",
|
||||
"trigger_file_path": filename,
|
||||
"already_installed_file_path": "",
|
||||
"patches_file_path": patches_filename,
|
||||
"non_invasive_recommendations_file_path": non_invasive_recommendations_filename,
|
||||
"valuation_file_path": "",
|
||||
"scenario_name": "EPC C",
|
||||
"multi_plan": True,
|
||||
"budget": None,
|
||||
"ashp_cop": 3.5,
|
||||
# This is new - when optimising, we drop scores by a few points to account for SAP 10
|
||||
"simulate_sap_10": True,
|
||||
"exclusions": ["external_wall_insulation"]
|
||||
}
|
||||
print(body)
|
||||
0
sfr/principal_pitch/2_export_data.py
Normal file
0
sfr/principal_pitch/2_export_data.py
Normal file
Loading…
Add table
Reference in a new issue