completed the current energy bill estimate

This commit is contained in:
Khalim Conn-Kowlessar 2024-07-08 14:12:37 +01:00
parent eb65ff538e
commit 30ce7df6c1
2 changed files with 107 additions and 19 deletions

View file

@ -112,6 +112,8 @@ class Property:
self.wall_type = None
self.floor_type = None
self.energy_cost_estimates = {}
self.energy = {
"primary_energy_consumption": epc_record.get("energy_consumption_current"),
"co2_emissions": epc_record.get("co2_emissions_current"),
@ -612,26 +614,63 @@ class Property:
for col in ["heating_kwh", "hot_water_kwh"]:
scoring_df[col] = None
# We should adjust the costs first and then calculate the energy consumption
lighting_cost = float(self.data["lighting-cost-current"])
heating_cost = float(self.data["heating-cost-current"])
hot_water_cost = float(self.data["hot-water-cost-current"])
total_cost = lighting_cost + heating_cost + hot_water_cost
adjusted_heating_cost = AnnualBillSavings.adjust_energy_cost_to_metered(
epc_energy_cost=heating_cost,
current_epc_rating=self.data["current-energy-rating"],
)
adjusted_hot_water_cost = AnnualBillSavings.adjust_energy_cost_to_metered(
epc_energy_cost=hot_water_cost,
current_epc_rating=self.data["current-energy-rating"],
)
adjusted_lighting_cost = AnnualBillSavings.adjust_energy_cost_to_metered(
epc_energy_cost=lighting_cost,
current_epc_rating=self.data["current-energy-rating"],
)
scoring_df["heating-cost-current"] = [adjusted_heating_cost]
scoring_df["hot-water-cost-current"] = [adjusted_hot_water_cost]
scoring_df["lighting-cost-current"] = [adjusted_lighting_cost]
energy_consumption_client.data = None
heating_prediction = energy_consumption_client.score_new_data(
new_data=scoring_df, target="heating_kwh"
)
)[0]
hot_water_prediction = energy_consumption_client.score_new_data(
new_data=scoring_df, target="hot_water_kwh"
)
)[0]
starting_heat_demand = (
float(self.data["energy-consumption-current"]) * self.floor_area
)
# We convert the lighting cost into kwh, just using the price cap
lighting_kwh = float(adjusted_lighting_cost) / AnnualBillSavings.ELECTRICITY_PRICE_CAP
appliances_energy_use = AnnualBillSavings.estimate_appliances_energy_use(total_floor_area=self.floor_area)
appliances_energy_cost = appliances_energy_use * AnnualBillSavings.ELECTRICITY_PRICE_CAP
total_energy_consumption = heating_prediction + hot_water_prediction + lighting_kwh + appliances_energy_use
self.current_adjusted_energy = AnnualBillSavings.adjust_energy_to_metered(
epc_energy_consumption=starting_heat_demand,
epc_energy_consumption=total_energy_consumption,
current_epc_rating=self.data["current-energy-rating"],
total_floor_area=self.floor_area
)
self.current_energy_bill = AnnualBillSavings.calculate_annual_bill(self.current_adjusted_energy)
self.energy_cost_estimates = {
"heating": adjusted_heating_cost,
"hot_water": adjusted_hot_water_cost,
"lighting": adjusted_lighting_cost,
"appliances": appliances_energy_cost
}
self.expected_energy_bill = (
adjusted_heating_cost + adjusted_hot_water_cost + adjusted_lighting_cost + appliances_energy_cost
)
def set_spatial(self, spatial: pd.DataFrame):
"""

View file

@ -25,9 +25,9 @@ class AnnualBillSavings:
AVERAGE_GAS_CONSUMPTION = 11500
# Latest price cap figures from Ofgem are for April 2024
# https://www.ofgem.gov.uk/publications/new-energy-price-cap-level-april-june-2024-starts-today
ELECTRICITY_PRICE_CAP = 0.245
GAS_PRICE_CAP = 0.0604
# https://www.ofgem.gov.uk/energy-price-cap
ELECTRICITY_PRICE_CAP = 0.2236
GAS_PRICE_CAP = 0.0548
# This is the most recent export payment figure, at 12p per kwh
ELECTRICITY_EXPORT_PAYMENT = 0.12
@ -125,7 +125,17 @@ class AnnualBillSavings:
return eam
@classmethod
def adjust_energy_to_metered(cls, epc_energy_consumption, current_epc_rating, total_floor_area):
def estimate_appliances_energy_use(cls, total_floor_area):
# The EPC energy consumption does not factor in cooking and applicance use, so this is estimated using the
# methodology outlined in SAP, and is discussed in the UCL paper in section 3.1.1
estimated_occupants = cls.calculate_occupants(total_floor_area=total_floor_area)
appliances_energy_use = cls.estimate_electrical_appliances(estimated_occupants, total_floor_area)
return appliances_energy_use
@classmethod
def adjust_energy_to_metered(
cls, epc_energy_consumption, current_epc_rating
):
"""
The over-prediction of energy use by EPCs in Great Britain: A comparison
of EPC-modelled and metered primary energy use intensity
@ -136,13 +146,6 @@ class AnnualBillSavings:
:return:
"""
# The EPC energy consumption does not factor in cooking and applicance use, so this is estimated using the
# methodology outlined in SAP, and is discussed in the UCL paper in section 3.1.1
estimated_occupants = cls.calculate_occupants(total_floor_area=total_floor_area)
appliances_energy_use = cls.estimate_electrical_appliances(estimated_occupants, total_floor_area)
epc_energy_consumption += appliances_energy_use
gradients = {
"A": -0.1,
"B": -0.1,
@ -175,6 +178,52 @@ class AnnualBillSavings:
return adjusted_consumption
@classmethod
def adjust_energy_cost_to_metered(cls, epc_energy_cost, current_epc_rating):
"""
The over-prediction of energy use by EPCs in Great Britain: A comparison
of EPC-modelled and metered primary energy use intensity
Which can be found here: https://www.sciencedirect.com/science/article/pii/S0378778823002542
We implement the results on page 10
This is used to just re-map the cost from the EPC to the metered cost
:return:
"""
gradients = {
"A": -0.1,
"B": -0.1,
"C": -0.43,
"D": -0.52,
"E": -0.7,
"F": -0.76,
"G": -0.76
}
intercepts = {
"A": 28,
"B": 28,
"C": 97,
"D": 119,
"E": 160,
"F": 157,
"G": 157
}
gradient = gradients[current_epc_rating]
intercept = intercepts[current_epc_rating]
# This should be negative
consumption_difference = gradient * epc_energy_cost + intercept
consumption_difference = 0 if consumption_difference > 0 else consumption_difference
adjusted_consumption = (epc_energy_cost + consumption_difference)
if adjusted_consumption < 0:
raise ValueError("consumption_difference should be negative")
return adjusted_consumption
@classmethod
def adjust_expected_band(cls, expected_epc_rating, current_epc_rating):
"""