mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
93 lines
3.2 KiB
Python
93 lines
3.2 KiB
Python
class AnnualBillSavings:
|
|
"""
|
|
This is a simple class which will estimate the annual bill savings, based on the kwh savings.
|
|
This class uses data from Ofgem, including their price caps, to provide us with an estimate for
|
|
1KWH of energy.
|
|
"""
|
|
|
|
# These gas an electricity consumption figures are based off of figures presented by Ofgem
|
|
# https://www.ofgem.gov.uk/information-consumers/energy-advice-households/average-gas-and-electricity-use-explained
|
|
AVERAGE_ELECTRICITY_CONSUMPTION = 2700
|
|
AVERAGE_GAS_CONSUMPTION = 11500
|
|
|
|
# Latest price cap figures from Ofgem are for January 2024
|
|
# https://www.ofgem.gov.uk/publications/changes-energy-price-cap-1-january-2024
|
|
ELECTRICITY_PRICE_CAP = 0.29
|
|
GAS_PRICE_CAP = 0.07
|
|
|
|
# This is a weighted mean of the price caps, using the consumption figures above as weights
|
|
PRICE_FACTOR = 0.11183098591549295
|
|
|
|
EPC_BANDS = ["G", "F", "E", "D", "C", "B", "A"]
|
|
|
|
@classmethod
|
|
def estimate(cls, kwh: float):
|
|
"""
|
|
Estimate the annual bill savings based on the kwh savings
|
|
:param kwh: The kwh savings
|
|
:return: An estimate for annual bill savings
|
|
"""
|
|
return cls.PRICE_FACTOR * kwh
|
|
|
|
@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
|
|
|
|
Which can be found here: https://www.sciencedirect.com/science/article/pii/S0378778823002542
|
|
We implement the results on page 10
|
|
|
|
: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_consumption + intercept
|
|
if consumption_difference > 0:
|
|
raise ValueError("consumption_difference should be negative")
|
|
|
|
adjusted_consumption = (epc_energy_consumption + consumption_difference)
|
|
|
|
return adjusted_consumption
|
|
|
|
@classmethod
|
|
def adjust_expected_band(cls, expected_epc_rating, current_epc_rating):
|
|
"""
|
|
Because of the differing intercepts and intercepts when adjusting, it's possible for
|
|
expected_adjusted_energy to be bigger than current_adjusted_energy. In this case, we'll
|
|
adjust, against at most 1 EPC band above the curent. This function performs the EPC adjustment
|
|
:param expected_epc_rating: The expected EPC rating
|
|
:param current_epc_rating: The current EPC rating
|
|
"""
|
|
|
|
# Find index of expected EPC rating
|
|
expected_index = cls.EPC_BANDS.index(expected_epc_rating)
|
|
current_index = cls.EPC_BANDS.index(current_epc_rating)
|
|
|
|
if expected_index - 1 < current_index:
|
|
return current_epc_rating
|
|
|
|
return cls.EPC_BANDS[expected_index - 1]
|