mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
adding retrieve find my epc to engine
This commit is contained in:
parent
2d69c671d3
commit
9e2914156f
9 changed files with 112 additions and 9 deletions
|
|
@ -1351,7 +1351,8 @@ class AssetList:
|
|||
# Check 1: Does the property have a valid heating system?
|
||||
self.standardised_asset_list["solar_landlord_data_indicates_correct_heating_system"] = (
|
||||
self.standardised_asset_list[self.STANDARD_HEATING_SYSTEM].isin(
|
||||
["air source heat pump", "ground source heat pump", "high heat retention storage heaters"]
|
||||
["air source heat pump", "ground source heat pump", "high heat retention storage heaters",
|
||||
"electric boiler"]
|
||||
)
|
||||
)
|
||||
self.standardised_asset_list["solar_landlord_data_indicates_needs_heating_upgrade"] = (
|
||||
|
|
@ -1363,7 +1364,7 @@ class AssetList:
|
|||
self.standardised_asset_list["solar_epc_data_indicates_correct_heating_system"] = (
|
||||
(
|
||||
self.standardised_asset_list[self.EPC_API_DATA_NAMES["mainheat-description"]]
|
||||
.str.lower().str.contains("air source heat pump|ground source heat pump")
|
||||
.str.lower().str.contains("air source heat pump|ground source heat pump|boiler and radiators, electric")
|
||||
) | (
|
||||
self.standardised_asset_list[
|
||||
self.EPC_API_DATA_NAMES["mainheat-description"]].str.lower().str.contains(
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ def app():
|
|||
outcomes_postcode = None
|
||||
outcomes_houseno = None
|
||||
outcomes_id = None
|
||||
outcomes_address = None
|
||||
master_filepaths = []
|
||||
master_to_asset_list_filepath = None
|
||||
|
||||
|
|
|
|||
|
|
@ -63,6 +63,22 @@ BUILT_FORM_MAPPINGS = {
|
|||
np.nan: 'unknown',
|
||||
'Third Floor Flat': 'mid-floor',
|
||||
'2 Ext. Wall Flat': 'mid-terrace',
|
||||
'Hostel': 'unknown'
|
||||
|
||||
'Hostel': 'unknown',
|
||||
'Flat: Mid Terrace: Mid Floor': 'mid-terrace',
|
||||
'Bungalow: SemiDetached': 'semi-detached',
|
||||
'Flat: End Terrace: Top Floor': 'end-terrace',
|
||||
'Flat: Enclosed End Terrace: Top Floor': 'end-terrace',
|
||||
'Maisonette: End Terrace: Ground Floor': 'end-terrace',
|
||||
'Flat: End Terrace: Ground Floor': 'end-terrace',
|
||||
'Flat: Mid Terrace: Top Floor': 'mid-terrace',
|
||||
'House: Detached': 'detached',
|
||||
'Flat: End Terrace: Mid Floor': 'end-terrace',
|
||||
'House: SemiDetached': 'semi-detached',
|
||||
'Flat: Semi Detached: Ground Floor': 'semi-detached',
|
||||
'Flat: Semi Detached: Top Floor': 'semi-detached',
|
||||
'Flat: Mid Terrace: Ground Floor': 'mid-terrace',
|
||||
'House: MidTerrace': 'mid-terrace',
|
||||
'House: EndTerrace': 'end-terrace',
|
||||
'Bungalow: EndTerrace': 'end-terrace',
|
||||
'Bungalow: MidTerrace': 'mid-terrace'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,12 +122,26 @@ HEATING_MAPPINGS = {
|
|||
'SOLID FUEL': 'solid fuel',
|
||||
'GAS': 'gas combi boiler',
|
||||
'DO NOT SURVEY': 'unknown',
|
||||
|
||||
'Gas Boiler': 'gas combi boiler',
|
||||
'Communal Gas ': 'communal gas boiler',
|
||||
'Communal': 'communal gas boiler',
|
||||
'Communal Gas': 'communal gas boiler',
|
||||
'Wood Burning Boiler': "boiler - other fuel",
|
||||
'Oil Fired Boiler': 'oil boiler'
|
||||
|
||||
'Oil Fired Boiler': 'oil boiler',
|
||||
'Electric (direct acting) room heaters: Panel, convector or radiant heaters Electricity: Electricity': 'room '
|
||||
'heaters',
|
||||
'Electric Storage Systems: Integrated storage+direct-acting heater Electricity: Electricity': 'electric storage '
|
||||
'heaters',
|
||||
'Community Heating Systems: Community CHP and boilers (RdSAP) Gas: Mains Gas (Community)': 'communal gas boiler',
|
||||
'Boiler: D rated Regular Boiler Gas: Mains Gas': 'gas boiler',
|
||||
'Boiler: C rated Combi Gas: Mains Gas': 'gas combi boiler',
|
||||
'Electric Storage Systems: Fan storage heaters Electricity: Electricity': 'electric storage heaters',
|
||||
' ': 'unknown',
|
||||
'Boiler: G rated Regular Boiler Gas: Mains Gas': 'gas boiler',
|
||||
'Electric Storage Systems: Modern (slimline) storage heaters Electricity: Electricity': 'electric storage heaters',
|
||||
'Boiler: E rated Regular Boiler Gas: Mains Gas': 'gas boiler',
|
||||
'Boiler: A rated Regular Boiler Electricity: Electricity': 'electric boiler',
|
||||
'Community Heating Systems: Community boilers only (RdSAP) Gas: Mains Gas (Community)': 'communal gas boiler',
|
||||
'Boiler: A rated Combi Gas: Mains Gas': 'gas condensing combi',
|
||||
'Boiler: A rated CPSU Electricity: Electricity': 'electric boiler'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,22 @@ PROPERTY_MAPPING = {
|
|||
'Studio (2nd floor)': 'flat',
|
||||
'Third Floor Flat': 'flat',
|
||||
'2 Ext. Wall Flat': 'flat',
|
||||
'Hostel': 'other'
|
||||
|
||||
'Hostel': 'other',
|
||||
'House: MidTerrace': 'house',
|
||||
'House: EndTerrace': 'house',
|
||||
'Flat: Mid Terrace: Mid Floor': 'flat',
|
||||
'Bungalow: SemiDetached': 'bungalow',
|
||||
'Bungalow: EndTerrace': 'bungalow',
|
||||
'Flat: End Terrace: Top Floor': 'flat',
|
||||
'Maisonette: End Terrace: Ground Floor': 'maisonette',
|
||||
'Flat: End Terrace: Ground Floor': 'flat',
|
||||
'Flat: Mid Terrace: Top Floor': 'flat',
|
||||
'House: Detached': 'house',
|
||||
'Flat: End Terrace: Mid Floor': 'flat',
|
||||
'House: SemiDetached': 'house',
|
||||
'Flat: Semi Detached: Ground Floor': 'flat',
|
||||
'Flat: Semi Detached: Top Floor': 'flat',
|
||||
'Flat: Mid Terrace: Ground Floor': 'flat',
|
||||
'Bungalow: MidTerrace': 'bungalow',
|
||||
'Flat: Enclosed End Terrace: Top Floor': 'flat'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,4 +137,15 @@ WALL_CONSTRUCTION_MAPPINGS = {
|
|||
'Cavity CWI Completed by Dyson': 'filled cavity',
|
||||
None: "unknown",
|
||||
"Cavity": "cavity unknown insulation",
|
||||
'SolidBrick: Unknown': 'solid brick unknown insulation',
|
||||
'Cavity: Unknown': 'cavity unknown insulation',
|
||||
'Cavity: AsBuilt (Post 1995)': 'filled cavity',
|
||||
'Cavity: AsBuilt (1976-1982)': 'cavity unknown insulation',
|
||||
'SystemBuilt: AsBuilt': 'system built',
|
||||
'TimberFrame: AsBuilt': "timber frame unknown insulation",
|
||||
'Cavity: AsBuilt (1983-1995)': 'cavity unknown insulation',
|
||||
'Cavity: AsBuilt (1983-1995), Cavity: FilledCavity': 'filled cavity',
|
||||
'SolidBrick: AsBuilt': 'solid brick unknown insulation',
|
||||
'Cavity: FilledCavity': 'filled cavity',
|
||||
'SolidBrick: Internal': 'insulated solid brick'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ from backend.ml_models.Valuation import PropertyValuation
|
|||
|
||||
from etl.bill_savings.KwhData import KwhData
|
||||
from etl.spatial.OpenUprnClient import OpenUprnClient
|
||||
from etl.find_my_epc.RetrieveFindMyEpc import RetrieveFindMyEpc
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
|
|
@ -514,6 +515,13 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
)
|
||||
)
|
||||
|
||||
# if we have a remote assment data type, we pull the additional data and include it
|
||||
if body.event_type == "remote_assessment":
|
||||
logger.info("Retrieving find my epc data")
|
||||
property_non_invasive_recommendations = RetrieveFindMyEpc.get_from_epc(
|
||||
epc_searcher.newest_epc
|
||||
)
|
||||
|
||||
epc_records = patch_epc(patch, epc_records)
|
||||
|
||||
prepared_epc = EPCRecord(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ MEASURE_MAP = {
|
|||
|
||||
VALID_GOALS = ["Increasing EPC"]
|
||||
VALID_HOUSING_TYPES = ["Social", "Private"]
|
||||
VALID_EVENT_TYPES = ["remote_assessment"]
|
||||
|
||||
|
||||
# Define the validation function for inclusions/exclusions
|
||||
|
|
@ -56,10 +57,16 @@ def check_housing_type(value: str) -> str:
|
|||
return value
|
||||
|
||||
|
||||
def check_event_type(value: str) -> str:
|
||||
assert value in VALID_EVENT_TYPES, f"{value} is not a valid event type"
|
||||
return value
|
||||
|
||||
|
||||
# Use Annotated with BeforeValidator for each list item validation
|
||||
InclusionOrExclusionItem = Annotated[str, BeforeValidator(check_inclusion_or_exclusion)]
|
||||
Goal = Annotated[str, BeforeValidator(check_goals)]
|
||||
HousingType = Annotated[str, BeforeValidator(check_housing_type)]
|
||||
EventType = Annotated[str, BeforeValidator(check_event_type)]
|
||||
|
||||
|
||||
class PlanTriggerRequest(BaseModel):
|
||||
|
|
@ -84,3 +91,7 @@ class PlanTriggerRequest(BaseModel):
|
|||
default_u_values: Optional[bool] = True
|
||||
|
||||
ashp_cop: Optional[float] = 2.8
|
||||
|
||||
# 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[float] = "remote_assessment",
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ import requests
|
|||
from bs4 import BeautifulSoup
|
||||
from datetime import datetime
|
||||
|
||||
from utils.logger import setup_logger
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
|
||||
class RetrieveFindMyEpc:
|
||||
SEARCH_POSTCODE_URL = (
|
||||
|
|
@ -366,3 +370,24 @@ class RetrieveFindMyEpc:
|
|||
formatted_recommendations.append(to_append)
|
||||
|
||||
return formatted_recommendations
|
||||
|
||||
@classmethod
|
||||
def get_from_epc(cls, epc):
|
||||
# Attempt both methods:
|
||||
try:
|
||||
searcher = cls(address=epc["address"], postcode=epc["postcode"])
|
||||
find_epc_data = searcher.retrieve_newest_find_my_epc_data()
|
||||
except Exception as e:
|
||||
logger.error(f"Error retrieving find my epc data: {e}")
|
||||
# We attempt with the backup add
|
||||
searcher = cls(address=epc["address1"], postcode=epc["postcode"])
|
||||
find_epc_data = searcher.retrieve_newest_find_my_epc_data()
|
||||
|
||||
non_invasive_recommendations = {
|
||||
"uprn": epc["uprn"],
|
||||
"address": epc["address"],
|
||||
"postcode": epc["postcode"],
|
||||
"recommendations": find_epc_data["recommendations"],
|
||||
}
|
||||
|
||||
return non_invasive_recommendations
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue