working on cleaning epc data for old records

This commit is contained in:
Khalim Conn-Kowlessar 2025-12-05 09:40:24 +00:00
parent 0876e948c9
commit bdc4c213ad
4 changed files with 62 additions and 8 deletions

View file

@ -727,11 +727,12 @@ class Property:
self.energy_cost_estimates = { self.energy_cost_estimates = {
"unadjusted": unadjusted_heating_costs, "unadjusted": unadjusted_heating_costs,
"epc": { # Don't think we need the EPC
"heating": float(self.data["heating-cost-current"]), # "epc": {
"hot_water": float(self.data["hot-water-cost-current"]), # "heating": float(self.data["heating-cost-current"]),
"lighting": float(self.data["lighting-cost-current"]), # "hot_water": float(self.data["hot-water-cost-current"]),
} # "lighting": float(self.data["lighting-cost-current"]),
# }
} }
self.energy_consumption_estimates = { self.energy_consumption_estimates = {

View file

@ -101,3 +101,12 @@ measures_needing_ventilation = [
# If we have a property beyond this size, we assume it's likely large enough to have an ASHP # If we have a property beyond this size, we assume it's likely large enough to have an ASHP
ASHP_FLOOR_AREA_THRESHOLD = 120 # m2 ASHP_FLOOR_AREA_THRESHOLD = 120 # m2
# Is a placeholder, used for cleaning data. Is a flat average based on the estimated
AVERAGE_LIGHTING_COST = 100
# Average bill, based on british gas is #1,838.71. Subtract 100 for lighting, 228 for hot water. This will include
# appliances so appliances should be removed when this is used
AVERAGE_HEATING_AND_APPLIANCE_COST = 1510.71
# Based on https://energysavingtrust.org.uk/sites/default/files/reports/AtHomewithWater%287%29.pdf
AVERAGE_HOT_WATER_COST = 228

View file

@ -3,6 +3,7 @@ from sqlalchemy.orm import declarative_base
from sqlalchemy.sql import func from sqlalchemy.sql import func
from backend.app.db.models.portfolio import Portfolio, PropertyModel from backend.app.db.models.portfolio import Portfolio, PropertyModel
from backend.app.db.models.materials import Material from backend.app.db.models.materials import Material
from backend.app.db.models.portfolio import Epc
from datatypes.enums import QuantityUnits from datatypes.enums import QuantityUnits
import enum import enum
@ -78,6 +79,16 @@ class Plan(Base):
), ),
nullable=True, nullable=True,
) )
post_sap_points = Column(Float)
post_epc_rating = Column(Enum(Epc))
post_co2_emissions = Column(Float)
co2_savings = Column(Float)
post_energy_bill = Column(Float)
energy_bill_savings = Column(Float)
post_energy_consumption = Column(Float) # energy demand in kWh/year
energy_consumption_savings = Column(Float)
valuation_post_retrofit = Column(Float)
valuation_increase = Column(Float)
class PlanRecommendations(Base): class PlanRecommendations(Base):

View file

@ -1,4 +1,3 @@
import os
import time import time
import json import json
from copy import deepcopy from copy import deepcopy
@ -16,6 +15,7 @@ from etl.epc.Record import EPCRecord
from sqlalchemy.exc import IntegrityError, OperationalError from sqlalchemy.exc import IntegrityError, OperationalError
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from starlette.responses import Response from starlette.responses import Response
from backend.ml_models.AnnualBillSavings import AnnualBillSavings
from backend.app.config import get_settings, get_prediction_buckets from backend.app.config import get_settings, get_prediction_buckets
from backend.app.db.connection import db_engine from backend.app.db.connection import db_engine
@ -415,8 +415,17 @@ def averages_cleaning(prepared_epc: EPCRecord, cleaning_data: pd.DataFrame):
:return: :return:
""" """
if not pd.isnull(prepared_epc.prepared_epc["number_habitable_rooms"]) and not pd.isnull( variables_to_clean = [
prepared_epc.prepared_epc["number_heated_rooms"]) and not pd.isnull(prepared_epc.prepared_epc["floor_height"]): "number_habitable_rooms",
"number_heated_rooms",
"floor_height",
"lighting_cost_current",
"heating_cost_current",
"hot_water_cost_current",
"energy_consumption_potential",
]
if not any([pd.isnull(prepared_epc.prepared_epc[k]) for k in variables_to_clean]):
# Nothing to do # Nothing to do
return prepared_epc return prepared_epc
@ -461,6 +470,30 @@ def averages_cleaning(prepared_epc: EPCRecord, cleaning_data: pd.DataFrame):
prepared_epc.prepared_epc["floor_height"] = clean_floor_height prepared_epc.prepared_epc["floor_height"] = clean_floor_height
prepared_epc.floor_height = clean_floor_height prepared_epc.floor_height = clean_floor_height
if pd.isnull(prepared_epc.lighting_cost_current):
# This is a basic assumption as an average
prepared_epc.prepared_epc["lighting_cost_current"] = assumptions.AVERAGE_LIGHTING_COST
prepared_epc.lighting_cost_current = assumptions.AVERAGE_LIGHTING_COST
if pd.isnull(prepared_epc.heating_cost_current):
# This is a basic assumption as an average
appliance_cost = AnnualBillSavings.estimate_appliances_energy_use(
total_floor_area=prepared_epc.total_floor_area
) * AnnualBillSavings.ELECTRICITY_PRICE_CAP
heating_cleaned_value = assumptions.AVERAGE_HEATING_AND_APPLIANCE_COST - appliance_cost
prepared_epc.prepared_epc["heating_cost_current"] = heating_cleaned_value
prepared_epc.heating_cost_current = heating_cleaned_value
if pd.isnull(prepared_epc.hot_water_cost_current):
# This is a basic assumption as an average
prepared_epc.prepared_epc["hot_water_cost_current"] = assumptions.AVERAGE_HOT_WATER_COST
prepared_epc.hot_water_cost_current = assumptions.AVERAGE_HOT_WATER_COST
if pd.isnull(prepared_epc.energy_consumption_potential):
# Set to current
prepared_epc.prepared_epc["energy_consumption_potential"] = prepared_epc.energy_consumption_current
prepared_epc.energy_consumption_potential = prepared_epc.energy_consumption_current
return prepared_epc return prepared_epc