mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
completed the current energy bill estimate
This commit is contained in:
parent
eb65ff538e
commit
30ce7df6c1
2 changed files with 107 additions and 19 deletions
|
|
@ -112,6 +112,8 @@ class Property:
|
||||||
self.wall_type = None
|
self.wall_type = None
|
||||||
self.floor_type = None
|
self.floor_type = None
|
||||||
|
|
||||||
|
self.energy_cost_estimates = {}
|
||||||
|
|
||||||
self.energy = {
|
self.energy = {
|
||||||
"primary_energy_consumption": epc_record.get("energy_consumption_current"),
|
"primary_energy_consumption": epc_record.get("energy_consumption_current"),
|
||||||
"co2_emissions": epc_record.get("co2_emissions_current"),
|
"co2_emissions": epc_record.get("co2_emissions_current"),
|
||||||
|
|
@ -612,26 +614,63 @@ class Property:
|
||||||
for col in ["heating_kwh", "hot_water_kwh"]:
|
for col in ["heating_kwh", "hot_water_kwh"]:
|
||||||
scoring_df[col] = None
|
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
|
energy_consumption_client.data = None
|
||||||
heating_prediction = energy_consumption_client.score_new_data(
|
heating_prediction = energy_consumption_client.score_new_data(
|
||||||
new_data=scoring_df, target="heating_kwh"
|
new_data=scoring_df, target="heating_kwh"
|
||||||
)
|
)[0]
|
||||||
|
|
||||||
hot_water_prediction = energy_consumption_client.score_new_data(
|
hot_water_prediction = energy_consumption_client.score_new_data(
|
||||||
new_data=scoring_df, target="hot_water_kwh"
|
new_data=scoring_df, target="hot_water_kwh"
|
||||||
)
|
)[0]
|
||||||
|
|
||||||
starting_heat_demand = (
|
# We convert the lighting cost into kwh, just using the price cap
|
||||||
float(self.data["energy-consumption-current"]) * self.floor_area
|
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(
|
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"],
|
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):
|
def set_spatial(self, spatial: pd.DataFrame):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,9 @@ class AnnualBillSavings:
|
||||||
AVERAGE_GAS_CONSUMPTION = 11500
|
AVERAGE_GAS_CONSUMPTION = 11500
|
||||||
|
|
||||||
# Latest price cap figures from Ofgem are for April 2024
|
# 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
|
# https://www.ofgem.gov.uk/energy-price-cap
|
||||||
ELECTRICITY_PRICE_CAP = 0.245
|
ELECTRICITY_PRICE_CAP = 0.2236
|
||||||
GAS_PRICE_CAP = 0.0604
|
GAS_PRICE_CAP = 0.0548
|
||||||
# This is the most recent export payment figure, at 12p per kwh
|
# This is the most recent export payment figure, at 12p per kwh
|
||||||
ELECTRICITY_EXPORT_PAYMENT = 0.12
|
ELECTRICITY_EXPORT_PAYMENT = 0.12
|
||||||
|
|
||||||
|
|
@ -125,7 +125,17 @@ class AnnualBillSavings:
|
||||||
return eam
|
return eam
|
||||||
|
|
||||||
@classmethod
|
@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
|
The over-prediction of energy use by EPCs in Great Britain: A comparison
|
||||||
of EPC-modelled and metered primary energy use intensity
|
of EPC-modelled and metered primary energy use intensity
|
||||||
|
|
@ -136,13 +146,6 @@ class AnnualBillSavings:
|
||||||
:return:
|
: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 = {
|
gradients = {
|
||||||
"A": -0.1,
|
"A": -0.1,
|
||||||
"B": -0.1,
|
"B": -0.1,
|
||||||
|
|
@ -175,6 +178,52 @@ class AnnualBillSavings:
|
||||||
|
|
||||||
return adjusted_consumption
|
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
|
@classmethod
|
||||||
def adjust_expected_band(cls, expected_epc_rating, current_epc_rating):
|
def adjust_expected_band(cls, expected_epc_rating, current_epc_rating):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue