peabody specific

This commit is contained in:
Khalim Conn-Kowlessar 2026-01-17 13:00:00 +00:00
parent 8ad2c002fd
commit 74ce1627ec
4 changed files with 193 additions and 15 deletions

View file

@ -114,14 +114,16 @@ from backend.app.db.models.recommendations import Recommendation, Plan, PlanReco
from backend.app.db.models.portfolio import PropertyModel, PropertyDetailsEpcModel
from collections import defaultdict
PORTFOLIO_ID = 434 # Peabody
PORTFOLIO_ID = 435 # Peabody
SCENARIOS = [
904,
905
908,
909,
910,
]
scenario_names = {
904: "EPC C - no solid floor, ashp 3.0",
905: "EPC B - no solid floor, ashp 3.0",
908: "EPC C - no solid floor, ashp 3.0",
909: "EPC C - no solid floor, no EWI or IWI, ashp 3.0",
910: "EPC B - no solid floor, no EWI, ashp 3.0"
}
@ -232,9 +234,58 @@ properties_data, plans_data, recommendations_data = get_data(
recommendations_df = pd.DataFrame(recommendations_data)
properties_df = pd.DataFrame(properties_data)
plans_df = pd.DataFrame(plans_data)
solar_pv_recommendations = recommendations_df[recommendations_df["measure_type"] == "solar_pv"]
s_id = 910
ps_w_a_plan = plans_df[plans_df["scenario_id"] == s_id].copy()
# Take the newest by scenario id
ps_w_a_plan = ps_w_a_plan.sort_values("created_at", ascending=False).drop_duplicates(
subset=["property_id"]
)
z = ps_w_a_plan[
ps_w_a_plan["cost_of_works"] > 0
].copy()
z2 = properties_df[properties_df["property_id"].isin(z["property_id"].values)]
# '', 'hot_water_cost_current',
# 'lighting_cost_current', 'appliances_cost_current',
# 'gas_standing_charge', 'electricity_standing_charge'
z2["total_bills"] = z2["heating_cost_current"] + z2["hot_water_cost_current"] + z2["lighting_cost_current"] + z2[
"appliances_cost_current"
] + z2["gas_standing_charge"] + z2["electricity_standing_charge"]
from tqdm import tqdm
# For a property ID, find a property where the no EWI/IWI approach is more expensive than the EWI approach
pids = properties_df["property_id"].unique()
for pid in tqdm(pids):
if pid in [603272, 550550, 574493]:
continue
# get the plans
property_plan = plans_df[plans_df["property_id"] == int(pid)]
# Take the newest plan by scenario id
property_plan = property_plan.sort_values("created_at", ascending=False).drop_duplicates(
subset=["scenario_id"]
)
a = property_plan[property_plan["scenario_id"] == 909].squeeze() # no EWI/IWI
b = property_plan[property_plan["scenario_id"] == 908].squeeze() # EWI
if (a["cost_of_works"] > b["cost_of_works"]) and (
a["post_epc_rating"].value == "C") and (b["cost_of_works"] > 5000):
bah
solar_pv_recommendations = recommendations_df[
recommendations_df["measure_type"] == "solar_pv"
]
solid_wall_recommendation = recommendations_df[
recommendations_df["scenario_id"].isin([908]) &
recommendations_df["measure_type"].isin(["internal_wall_insulation"]) &
recommendations_df["default"]
]
average_savings = solar_pv_recommendations.groupby("scenario_id")["energy_cost_savings"].mean().reset_index()
# Add on scenarion names
average_savings["scenario_name"] = average_savings["scenario_id"].map(scenario_names)
# Check tenures
initial_asset_data = pd.read_excel(

View file

@ -11,7 +11,6 @@ from etl.customers.cambridge.surveys import current_epc
with db_session() as session:
# We need installed measures, where the measure type is ewi or iwi
installed_measures = session.query(InstalledMeasure).filter(
InstalledMeasure.measure_type.in_(["cavity_wall_insulation"])
).all()
# Get the uprns
installed_uprns = [x.uprn for x in installed_measures]
@ -32,7 +31,7 @@ needing_retry = sal[sal["epc_os_uprn"].isin(installed_uprns)]
# Store
needing_retry.to_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final "
"SAL/properties_needing_retry_20260115 - cavity wall insulation.xlsx",
"SAL/properties_needing_retry_20260115 - all already installed.xlsx",
sheet_name="Standardised Asset List",
index=False
)

View file

@ -0,0 +1,41 @@
# get all properties that have an IWI recommendation
import pandas as pd
r1 = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC B - no "
"solid floor, no EWI, ashp 3.0 - 20250113 final.xlsx"
)
r2 = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no "
"solid floor, ashp 3.0 - 20250113 final.xlsx"
)
r3 = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/EPC C - no "
"solid floor, no EWI or IWI, ashp 3.0 - 20250113 final.xlsx"
)
s1 = r1[~pd.isnull(r1["internal_wall_insulation"])]
s2 = r2[~pd.isnull(r2["internal_wall_insulation"])]
# Combined uprns
uprns = s1["uprn"].tolist() + s2["uprn"].tolist()
uprns = list(set(uprns))
# Create SAL of these uprns
sal = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final SAL/20260113 - "
"final asset list.xlsx",
sheet_name="Standardised Asset List"
)
needing_retry = sal[sal["epc_os_uprn"].isin(uprns)]
# Store
needing_retry.to_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final "
"SAL/properties_needing_retry_20260115 - internal wall insulation.xlsx",
sheet_name="Standardised Asset List",
index=False
)

View file

@ -11,6 +11,7 @@ from backend.app.db.models.recommendations import Recommendation, Plan, PlanReco
from backend.app.db.models.portfolio import PropertyModel, PropertyDetailsEpcModel, PropertyDetailsSpatial
from backend.app.db.functions.materials_functions import get_materials
from collections import defaultdict
from sqlalchemy import func
# PORTFOLIO_ID = 206
# SCENARIOS = [389]
@ -57,9 +58,44 @@ def get_data(portfolio_id, scenario_ids):
# --------------------
# Plans
# --------------------
plans_query = session.query(Plan).filter(
Plan.scenario_id.in_(scenario_ids)
).all()
latest_plans_subq = (
session.query(
Plan.scenario_id,
Plan.property_id,
func.max(Plan.created_at).label("latest_created_at")
)
.filter(Plan.scenario_id.in_(scenario_ids))
.group_by(
Plan.scenario_id,
Plan.property_id
)
.subquery()
)
# plans_query = session.query(Plan).filter(
# Plan.scenario_id.in_(scenario_ids)
# ).all()
plans_query = (
session.query(Plan)
.join(
latest_plans_subq,
(Plan.scenario_id == latest_plans_subq.c.scenario_id) &
(Plan.property_id == latest_plans_subq.c.property_id) &
(Plan.created_at == latest_plans_subq.c.latest_created_at)
)
.all()
)
# plans_query = (
# session.query(Plan)
# .join(
# latest_plans_subq,
# (Plan.scenario_id == latest_plans_subq.c.scenario_id) &
# (Plan.created_at == latest_plans_subq.c.latest_created_at)
# )
# .all()
# )
plans_data = [
{col.name: getattr(plan, col.name) for col in Plan.__table__.columns}
@ -73,7 +109,8 @@ def get_data(portfolio_id, scenario_ids):
# --------------------
recommendations_query = session.query(
Recommendation,
Plan.scenario_id
Plan.scenario_id,
PlanRecommendations.plan_id
).join(
PlanRecommendations,
Recommendation.id == PlanRecommendations.recommendation_id
@ -216,6 +253,7 @@ for scenario_id in SCENARIOS:
[
"landlord_property_id", "property_id", "uprn", "address", "postcode", "property_type", "walls", "roof",
"heating", "windows", "current_epc_rating", "current_sap_points", "total_floor_area", "number_of_rooms",
"id"
]
].merge(
recommendations_measures_pivot, how="left", on="property_id"
@ -223,17 +261,42 @@ for scenario_id in SCENARIOS:
post_install_sap, how="left", on="property_id"
)
df = df.drop(columns=["property_id"])
# df = df.drop(columns=["property_id"])
df["sap_points"] = df["sap_points"].fillna(0)
df["predicted_post_works_sap"] = df["current_sap_points"] + df["sap_points"]
df["predicted_post_works_sap"] = df["predicted_post_works_sap"].round()
df["predicted_post_works_sap"] = df["predicted_post_works_sap"]
df["predicted_post_works_epc"] = df["predicted_post_works_sap"].apply(lambda x: sap_to_epc(x))
df["uprn"] = df["uprn"].astype(str)
relevant_plans = plans_df[plans_df["scenario_id"] == scenario_id]
df2 = df.merge(
relevant_plans[["property_id", "post_sap_points", "post_epc_rating"]], how="left", on="property_id",
suffixes=("", "_plan")
)
print(df2["predicted_post_works_epc"].value_counts())
print(df2["post_epc_rating"].value_counts())
z = df2[
(df2["predicted_post_works_epc"] != "D") &
(df2["post_epc_rating"].astype(str) == "Epc.D")
]
df2["predicted_post_works_epc"].value_counts()
df2["post_epc_rating"].astype(str).value_counts()
df2[df2["total_retrofit_cost"] > 0].shape
getting_works = df[df["total_retrofit_cost"] > 0]
getting_works["predicted_post_works_epc"].value_counts()
32565 / getting_works.shape[0]
df[df["predicted_post_works_sap"] == ""]
# Create excel to store to
filename = ("/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting "
f"Project/Final SAL/{scenario_names[scenario_id]} - 20250113 final.xlsx")
f"Project/Final SAL/scenarios/{scenario_names[scenario_id]} - 20250114 final.xlsx")
with pd.ExcelWriter(filename) as writer:
df.to_excel(writer, sheet_name="properties", index=False)
@ -388,3 +451,27 @@ asset_list.to_excel(
condition_cost_comparison = asset_list[
["condition_score", "decoration_sum_min ", "decoration_sum_max", "domna_condition_cost"]
]
# Testing
plans_df.head()
example = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/Final "
"SAL/scenarios/EPC C - no solid floor, no EWI or IWI, ashp 3.0 - 20250114 final.xlsx"
)
plans_df2 = plans_df.merge(
properties_df[["property_id", "landlord_property_id"]],
left_on="property_id",
right_on="property_id",
how="left"
)
plans_df2 = plans_df2[plans_df2["scenario_id"] == 909]
dupes = plans_df2[plans_df2["property_id"].duplicated()]
# merge on plans
example = example.merge(
plans_df, how="left",
)