minor tweaks and bug fixes for properties that failed diagnostic tests

This commit is contained in:
Khalim Conn-Kowlessar 2026-01-06 20:58:13 +00:00
parent 45170d4724
commit 608ff71d35
3 changed files with 102 additions and 17 deletions

View file

@ -23,9 +23,10 @@ scenario_sap_targets = {
859: 69,
}
problems = []
for scenario_id, scenario_name in scenario_names.items():
# Read in the recommended measures
print("Reading")
df = pd.read_excel(
f"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/"
f"{scenario_name}.xlsx"
@ -34,30 +35,98 @@ for scenario_id, scenario_name in scenario_names.items():
# find properties that are below the scenario sap target, but have no recommended measures
df["below_scenario_target"] = df["current_sap_points"] < scenario_sap_targets[scenario_id]
df["no_recommended_measures"] = df["sap_points"] == 0
df["zero_cost"] = df["total_retrofit_cost"] == 0
df["sap_points_above_zero"] = df["sap_points"] > 0
# Also look for zero cost and SAP points > 0
problematic_properties = df[
df["below_scenario_target"] & df["no_recommended_measures"]
]
(df["below_scenario_target"] & df["no_recommended_measures"])
].copy()
if scenario_sap_targets[scenario_id] == 81:
problematic_properties = problematic_properties[problematic_properties["property_type"] != "Flat"]
zero_cost_above_zero_sap = df[
(df["sap_points_above_zero"] & df["zero_cost"])
].copy()
# show all columns
# Source - https://stackoverflow.com/a
# Posted by YOLO, modified by community. See post 'Timeline' for change history
# Retrieved 2026-01-06, License - CC BY-SA 4.0
pd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 1000)
problematic_properties.head(len(problematic_properties))
# pd.set_option('display.max_rows', 500)
# pd.set_option('display.max_columns', 500)
# pd.set_option('display.width', 1000)
# problematic_properties.head(len(problematic_properties))
#
print(f"We have {len(problematic_properties)} problematic properties for scenario {scenario_name} ({scenario_id})")
print(f"We have {len(zero_cost_above_zero_sap)} zero cost properties for scenario {scenario_name} ({scenario_id})")
problems.append(problematic_properties)
problems.append(zero_cost_above_zero_sap)
# plan_input = [
# {
# "uprn": 100022725126,
# "address": "FLAT 5 Daveys Court",
# "postcode": "WC2N 4BW"
# }
# ]
# plan_input = [
# {
# "uprn": 100120966352,
# "address": "FLAT 11 Kingsgate",
# "postcode": "OX18 2BP"
# }
# ]
plan_input = [
{
"uprn": 100022725126,
"address": "FLAT 5 Daveys Court",
"postcode": "WC2N 4BW"
"uprn": 200003371857,
"postcode": "SE1 5SJ",
"address": "39 BUTTERMERE CLOSE",
}
]
all_problems = pd.concat(problems)
all_problems = all_problems.drop_duplicates(subset=["uprn"])
sal = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/20251213 Model "
"data.xlsx",
sheet_name="Standardised Asset List"
)
sal2 = pd.read_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/20260105 - additional "
"UPRNS.xlsx",
sheet_name="Standardised Asset List"
)
sal = pd.concat([sal, sal2])
retry = sal[sal["epc_os_uprn"].isin(all_problems["uprn"])]
# Store
retry.to_excel(
"/Users/khalimconn-kowlessar/Documents/hestia/Customers/Peabody/Nov 2025 Consulting Project/"
"d_problematic_properties_to_review_20260106.xlsx",
sheet_name="Standardised Asset List",
index=False
)
# Delete associated plans
# 1) Get the property IDs for these UPRNS, for this portfolio
portfolio_id = 419
uprns = retry
# TODO: Delete all plans for these properties and re-build
# Plan notes:
# UPRN: 5870109770, property ID: 281244 - need to delete and re-build all scenarios
# UPRN: 100022725126, property ID: 283781 - need to delete and re-build all scenarios
# Bugs:
12156800

View file

@ -170,9 +170,14 @@ class HeatingRecommender:
# If the property has community heating heaters in place, we don't recommend HHRSH
has_community_heating = self.property.main_fuel["is_community"]
hhr_suitable = hhr_suitable and (
"underfloor heating" not in self.property.main_heating["clean_description"]
) and not has_community_heating
# If the property currently has electric underfloor heating, we allow this if there is elecric immersion
# hot water heating
underfloor_not_an_issue = True
if self.property.main_heating["has_electric_underfloor_heating"]:
if self.property.hotwater["heater_type"] != "electric immersion":
underfloor_not_an_issue = False
hhr_suitable = hhr_suitable and not has_community_heating and underfloor_not_an_issue
# If the property has a ground source heat pump, or air source heat pump, we don't recommend HHRSH

View file

@ -86,9 +86,17 @@ class WindowsRecommendations:
# We scale the number of windows based on the proportion of existing glazing
if self.property.data["multi-glaze-proportion"] != "":
n_windows_scalar = 1 - (
int(self.property.data["multi-glaze-proportion"]) / 100
)
if (self.property.windows["clean_description"] == "Some double glazing") and (
self.property.data["windows-energy-eff"] == "Very Poor") and (
self.property.data["multi-glaze-proportion"] == 100
):
# In this case, we assume all of the dinwos need replacing
n_windows_scalar = 1
else:
n_windows_scalar = 1 - (
int(self.property.data["multi-glaze-proportion"]) / 100
)
else:
n_windows_scalar = self.COVERAGE_MAP.get(
self.property.windows["glazing_coverage"], 1
@ -97,6 +105,9 @@ class WindowsRecommendations:
number_of_windows *= n_windows_scalar
number_of_windows = np.ceil(number_of_windows)
# Handle edge case - prevent number of windows 0
number_of_windows = max(1, number_of_windows)
# We then price the job based on the number of windows that there are
cost_result = self.costs.window_glazing(
number_of_windows=number_of_windows,