Implementing searching epc methodology

This commit is contained in:
Khalim Conn-Kowlessar 2024-01-02 11:44:18 +00:00
parent bb9b8308be
commit 40b7ec1c18
6 changed files with 80 additions and 1695 deletions

2
.idea/Model.iml generated
View file

@ -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="Python 3.10 (model_data)" jdkType="Python SDK" />
<orderEntry type="jdk" jdkName="Python 3.10 (backend)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyNamespacePackagesService">

2
.idea/misc.xml generated
View file

@ -3,7 +3,7 @@
<component name="Black">
<option name="sdkName" value="Python 3.10 (backend)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (model_data)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (backend)" project-jdk-type="Python SDK" />
<component name="PythonCompatibilityInspectionAdvertiser">
<option name="version" value="3" />
</component>

View file

@ -22,6 +22,10 @@ class OrdnanceSuveyClient:
self.results = None
self.most_relevant_result = None
self.property_type = None
self.built_form = None
@lru_cache(maxsize=128)
def get_places_api(self):
"""
@ -39,9 +43,18 @@ class OrdnanceSuveyClient:
data = response.json()
results = data['results']
self.results = results
# Extract some details about the best match
self.most_relevant_result = self.results[0]["DPA"]
self.property_type, self.built_form = self.parse_classification_code(
self.most_relevant_result["CLASSIFICATION_CODE"]
)
return
else:
logger.info("Could not find any results for the provided address and postcode")
return
return {"status": response.status_code}
@staticmethod
def parse_classification_code(classification_code: str):

View file

@ -18,7 +18,6 @@ from recommendations.recommendation_utils import (
)
ENVIRONMENT = os.environ.get('ENVIRONMENT', 'dev')
EPC_AUTH_TOKEN = os.environ.get('EPC_AUTH_TOKEN')
DATA_BUCKET = os.environ.get('DATA_BUCKET', 'retrofit-data-dev' if ENVIRONMENT == 'dev' else None)
logger = setup_logger()
@ -49,16 +48,16 @@ class Property(Definitions):
spatial = None
def __init__(self, id, postcode, address1, epc_client=None, data=None):
def __init__(self, id, data=None, old_data=None, full_sap_epc=None):
self.id = id
self.postcode = postcode
self.address1 = address1
self.data = data
self.old_data = None
self.old_data = old_data
self.full_sap_epc = full_sap_epc
self.property_dimensions = None
self.uprn = None
self.full_sap_epc = None
self.in_conservation_area, self.is_listed, self.is_heritage = None, None, None
self.restricted_measures = False
self.year_built = None
@ -92,47 +91,6 @@ class Property(Definitions):
self.current_adjusted_energy = None
self.expected_adjusted_energy = None
if epc_client:
self.epc_client = epc_client
else:
self.epc_client = EpcClient(auth_token=EPC_AUTH_TOKEN)
def search_address_epc(self):
"""
This method searches for an address in the EPC database and returns the first result
:return: property data
"""
if self.data:
return
# This will fail if a property does not have an EPC - this has been documented as a case to handle
response = self.epc_client.domestic.search(params={"address": self.address1, "postcode": self.postcode})
# Check if we have a full sap EPC
self.full_sap_epc = [r for r in response["rows"] if r["transaction-type"] == "new dwelling"]
self.full_sap_epc = self.full_sap_epc[0] if self.full_sap_epc else self.full_sap_epc
if len(response["rows"]) > 1:
newest_response = [
r for r in response["rows"] if
r["lodgement-datetime"] == max([x["lodgement-datetime"] for x in response["rows"]])
]
if len(newest_response) > 1:
raise Exception("More than one result found for this address - investigate me")
# We'll keep old EPCs in case it contains information, not present on the newest one
self.old_data = [epc for epc in response["rows"] if epc["lmk-key"] != newest_response[0]["lmk-key"]]
response["rows"] = newest_response
self.data = response["rows"][0]
# For the moment, if we don't have a UPRN, we don't do anything about it, however we'll handle this in
# the future by using the Ordnance Survey places API
if not self.data["uprn"]:
logger.warning("We do not have a UPRN for this property")
else:
self.uprn = int(self.data["uprn"])
def set_energy(self):
"""
Extracts and formats data about the home's energy and co2 consumption

File diff suppressed because it is too large Load diff

View file

@ -75,15 +75,16 @@ async def trigger_plan(body: PlanTriggerRequest):
# We validate each record in the file. If the record is NOT valid, we need to handle this accordingly
# TODO: implment validation. We should also standardise postcode and address in some fashion as
# a postcode of abcdef would be considered different to ABCDEF
# TODO: Search for the property
epc_searcher = SearchEpc(
address1=config['address'],
address1=config["address"],
postcode=config["postcode"],
auth_token=get_settings().EPC_AUTH_TOKEN,
os_api_key=get_settings().ORDNANCE_SURVEY_API_KEY
)
epc_searcher.find_property()
# Create a record in db
# Create a record in db - TODO: Create this using the epc address and postcode and validate with
# uprn
property_id, is_new = create_property(
session, portfolio_id=body.portfolio_id, address=config['address'], postcode=config['postcode']
)
@ -102,10 +103,10 @@ async def trigger_plan(body: PlanTriggerRequest):
input_properties.append(
Property(
postcode=config['postcode'],
address1=config['address'],
epc_client=epc_client,
id=property_id
id=property_id,
data=epc_searcher.newest_epc,
old_data=epc_searcher.older_epcs,
full_sap_epc=epc_searcher.full_sap_epc,
)
)