mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
updated price cap figures
This commit is contained in:
parent
80fc7c821e
commit
053218b3fd
4 changed files with 73 additions and 24 deletions
|
|
@ -196,7 +196,6 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
)
|
||||
|
||||
model_api = ModelApi(portfolio_id=body.portfolio_id, timestamp=created_at)
|
||||
# model_api.MODEL_PREFIXES = ['sap_change_predictions', 'carbon_change_predictions']
|
||||
|
||||
all_predictions = {
|
||||
"sap_change_predictions": pd.DataFrame(),
|
||||
|
|
@ -219,9 +218,6 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
for key, scored in predictions_dict.items():
|
||||
all_predictions[key] = pd.concat([all_predictions[key], scored])
|
||||
|
||||
# TODO: TEMP
|
||||
# all_predictions["heat_demand_predictions"] = all_predictions["sap_change_predictions"].copy()
|
||||
|
||||
# Insert the predictions into the recommendations and run the optimiser
|
||||
# TODO: If a recommendation has a negative impact on SAP, we should remove it - this seems to have become a
|
||||
# possibility with heating system
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ class AnnualBillSavings:
|
|||
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
|
||||
# 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
|
||||
|
||||
# This is a weighted mean of the price caps, using the consumption figures above as weights
|
||||
PRICE_FACTOR = 0.11183098591549295
|
||||
PRICE_FACTOR = 0.09549999999999999
|
||||
|
||||
EPC_BANDS = ["G", "F", "E", "D", "C", "B", "A"]
|
||||
|
||||
|
|
|
|||
|
|
@ -35,20 +35,20 @@ def app():
|
|||
# 79% D, 19% E, 1% F, 0.2% G - it probably makes the most sense to focus on E and D properties
|
||||
epc_data["CURRENT_ENERGY_RATING"].value_counts(normalize=True)
|
||||
|
||||
# For the purpose of the sample, take the properties have surveys done in the last 2 years
|
||||
# This gives us 1167 remaining properties
|
||||
two_years_ago = pd.Timestamp.now() - pd.DateOffset(days=int(2.5 * 365))
|
||||
epc_data = epc_data[epc_data["LODGEMENT_DATE"] >= two_years_ago]
|
||||
# For the purpose of the sample, take the properties have surveys done in the last 3 years
|
||||
# This gives us 1351 remaining properties
|
||||
three_years_ago = pd.Timestamp.now() - pd.DateOffset(days=int(3 * 365))
|
||||
epc_data = epc_data[epc_data["LODGEMENT_DATE"] >= three_years_ago]
|
||||
|
||||
# Archetype 1: defined below:
|
||||
# 1) House
|
||||
# 2) Unfilled cavity
|
||||
# 3) A roof that could be insulated (flat or pitched with no more than 50mm insulation)
|
||||
# 4) EPC E
|
||||
# 12 properties
|
||||
# 4) EPC E or D
|
||||
# 24 properties
|
||||
archetype_1_sample = epc_data[
|
||||
epc_data["PROPERTY_TYPE"].isin(["House"]) &
|
||||
(epc_data["CURRENT_ENERGY_RATING"] == "E") &
|
||||
(epc_data["CURRENT_ENERGY_RATING"].isin(["D", "E"])) &
|
||||
epc_data["WALLS_DESCRIPTION"].isin(["Cavity wall, as built, no insulation (assumed)"]) &
|
||||
epc_data["ROOF_DESCRIPTION"].isin(
|
||||
[
|
||||
|
|
@ -69,10 +69,10 @@ def app():
|
|||
# 2) Unfilled cavity
|
||||
# 3) Another property above
|
||||
# 4) EPC E
|
||||
# 14 properties here
|
||||
# 57 properties here
|
||||
archetype_2_sample = epc_data[
|
||||
epc_data["PROPERTY_TYPE"].isin(["Flat"]) &
|
||||
(epc_data["CURRENT_ENERGY_RATING"] == "E") &
|
||||
(epc_data["CURRENT_ENERGY_RATING"].isin(["E", "D"])) &
|
||||
epc_data["WALLS_DESCRIPTION"].isin(["Cavity wall, as built, no insulation (assumed)"]) &
|
||||
epc_data["ROOF_DESCRIPTION"].isin(
|
||||
[
|
||||
|
|
@ -88,11 +88,18 @@ def app():
|
|||
# 2) Solid brick wall
|
||||
# 3) House
|
||||
# 4) Pitched roof with no insulation
|
||||
# Just 1 property (more expensive to retrofit)
|
||||
# Just 7 properties (more expensive to retrofit)
|
||||
archetype_3_sample = epc_data[
|
||||
epc_data["PROPERTY_TYPE"].isin(["House"]) &
|
||||
(epc_data["CURRENT_ENERGY_RATING"] == "F") &
|
||||
epc_data["ROOF_DESCRIPTION"].isin(["Pitched, no insulation"])
|
||||
(epc_data["CURRENT_ENERGY_RATING"].isin(["F", "G"])) &
|
||||
epc_data["ROOF_DESCRIPTION"].isin(
|
||||
[
|
||||
"Pitched, no insulation",
|
||||
"Pitched, limited insulation (assumed)",
|
||||
"Pitched, 100 mm loft insulation",
|
||||
"Pitched, no insulation (assumed)",
|
||||
]
|
||||
)
|
||||
]
|
||||
archetype_3_sample_asset_list = archetype_3_sample[["UPRN", "ADDRESS1", "POSTCODE"]].copy()
|
||||
archetype_3_sample_asset_list["ARCHETYPE"] = "Archetype 3"
|
||||
|
|
@ -101,15 +108,18 @@ def app():
|
|||
# 1) Maisonette
|
||||
# 2) Empty cavity
|
||||
# 3) EPC E
|
||||
# 14 properties here
|
||||
# 16 properties here
|
||||
archetype_4_sample = epc_data[
|
||||
epc_data["PROPERTY_TYPE"].isin(["Maisonette"]) &
|
||||
epc_data["WALLS_DESCRIPTION"].isin(["Cavity wall, as built, no insulation (assumed)"])
|
||||
epc_data["WALLS_DESCRIPTION"].isin(
|
||||
["Cavity wall, as built, no insulation (assumed)"]
|
||||
)
|
||||
]
|
||||
|
||||
archetype_4_sample_asset_list = archetype_4_sample[["UPRN", "ADDRESS1", "POSTCODE"]].copy()
|
||||
archetype_4_sample_asset_list["ARCHETYPE"] = "Archetype 4"
|
||||
|
||||
# 41 total properties
|
||||
# 104 total properties
|
||||
asset_list = pd.concat(
|
||||
[
|
||||
archetype_1_sample_asset_list,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,50 @@ def app():
|
|||
asset_list = read_csv_from_s3(
|
||||
"retrofit-plan-inputs-dev", f"{USER_ID}/{portfolio_id}/inputs.csv"
|
||||
)
|
||||
asset_list = pd.DataFrame(asset_list)
|
||||
|
||||
# Get the properties for the portfolio
|
||||
properties = get_properties_with_default_recommendations(session, portfolio_id)
|
||||
properties_df = pd.DataFrame(properties)
|
||||
|
||||
# We now pull the data for the property details
|
||||
property_details = get_property_details_by_portfolio_id(session, portfolio_id)
|
||||
property_details_df = pd.DataFrame(property_details)
|
||||
# Merge on uprn
|
||||
property_details_df = property_details_df.merge(
|
||||
properties_df[["uprn", "id"]].rename(columns={"id": "property_id"}),
|
||||
on="property_id"
|
||||
)
|
||||
|
||||
plans = get_plan_by_portfolio_id(session, portfolio_id)
|
||||
plans_df = pd.DataFrame(plans)
|
||||
|
||||
# Unnest the recommendations. Each recommendation is a list of dictionaries
|
||||
recommendations_exploded = properties_df["recommendations"].explode().tolist()
|
||||
recommendations_df = pd.DataFrame([r for r in recommendations_exploded if not pd.isnull(r)])
|
||||
# Add uprn on
|
||||
recommendations_df = recommendations_df.merge(
|
||||
properties_df[["uprn", "id"]].rename(columns={"id": "property_id"}),
|
||||
how="left",
|
||||
on="property_id"
|
||||
)
|
||||
|
||||
# Summary information by each archetype
|
||||
archetype_1 = asset_list[asset_list["archetype"] == "Archetype 1"]
|
||||
|
||||
recommendations_arch_1_summary = create_recommendations_summary(
|
||||
recommendations_df[recommendations_df["uprn"].astype(str).isin(archetype_1["uprn"].values)],
|
||||
properties_df[properties_df["uprn"].astype(str).isin(archetype_1["uprn"].values)],
|
||||
SAP_TARGET_1
|
||||
)
|
||||
|
||||
# Take the mean, median and maximum of each value
|
||||
arch_1_recommendation_means = recommendations_arch_1_summary.mean()
|
||||
|
||||
arch_1_property_details = property_details_df[
|
||||
property_details_df["uprn"].astype(str).isin(archetype_1["uprn"].values)
|
||||
]
|
||||
|
||||
arch_1_property_details_means = arch_1_property_details.mean()
|
||||
|
||||
arch_1_recommendation_means["total_bill_savings"] / arch_1_property_details_means["adjusted_energy_consumption"]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue