debugging etl clean

This commit is contained in:
Khalim Conn-Kowlessar 2025-08-22 01:34:16 +01:00
parent cc187fe8d6
commit a9fd725453
7 changed files with 68 additions and 14 deletions

View file

@ -322,6 +322,10 @@ class Funding:
return data["Cost Savings"].values[0] return data["Cost Savings"].values[0]
def _calculate_full_project_abs(self, floor_area_band: str, starting_sap_band: str, ending_sap_band: str): def _calculate_full_project_abs(self, floor_area_band: str, starting_sap_band: str, ending_sap_band: str):
if starting_sap_band == ending_sap_band:
return 0
data = self.project_scores_matrix[ data = self.project_scores_matrix[
(self.project_scores_matrix["Floor Area Segment"] == floor_area_band) & (self.project_scores_matrix["Floor Area Segment"] == floor_area_band) &
(self.project_scores_matrix["Starting Band"] == starting_sap_band) & (self.project_scores_matrix["Starting Band"] == starting_sap_band) &
@ -638,6 +642,38 @@ class Funding:
# If we don't have a pre heating system, we assume the measure is not applicable # If we don't have a pre heating system, we assume the measure is not applicable
return 0 return 0
if measure_type in ["double_glazing", "secondary_glazing"]:
# pps is under the WG_singletodouble Measure_Type
pps = filtered_pps_matrix[
filtered_pps_matrix["Measure_Type"] == "WG_singletodouble"
]
return pps.squeeze()["Cost Savings"]
if measure_type == "roomstat_programmer_trvs":
# We can get funding for TRVs
pps = filtered_pps_matrix[
filtered_pps_matrix["Measure_Type"] == "TRV"
]
if pre_heating_system in pps["Pre_Main_Heating_Source"].values:
pps = pps[pps["Pre_Main_Heating_Source"] == pre_heating_system]
if pps.shape[0] != 1:
raise ValueError("something went wrong, more than one pps for TRV")
return pps.squeeze()["Cost Savings"]
# If we don't have a pre heating system, we assume the measure is not applicable
return 0
if measure_type == "time_temperature_zone_control":
pps = filtered_pps_matrix[
filtered_pps_matrix["Measure_Type"] == "TTZC"
]
if pre_heating_system in pps["Pre_Main_Heating_Source"].values:
pps = pps[pps["Pre_Main_Heating_Source"] == pre_heating_system]
if pps.shape[0] != 1:
raise ValueError("something went wrong, more than one pps for TTZC")
return pps.squeeze()["Cost Savings"]
# If we don't have a pre heating system, we assume the measure is not applicable
return 0
raise ValueError(f"Invalid measure type for partial project ABS calculation: {measure_type}") raise ValueError(f"Invalid measure type for partial project ABS calculation: {measure_type}")
# ----------------------- # -----------------------

View file

@ -949,7 +949,7 @@ async def model_engine(body: PlanTriggerRequest):
total_uplift = optimal_solution["total_uplift"] total_uplift = optimal_solution["total_uplift"]
# This is the funding scheme selected # This is the funding scheme selected
# This is the full project ABS # This is the full project ABS
full_project_score = optimal_solution["full_project_funding"] full_project_score = optimal_solution["project_score"]
# This is the partial project ABS # This is the partial project ABS
partial_project_score = optimal_solution["partial_project_score"] partial_project_score = optimal_solution["partial_project_score"]
# This is the uplift score ABS # This is the uplift score ABS

View file

@ -17,15 +17,28 @@ def app():
:return: :return:
""" """
asset_list = pd.read_excel( # asset_list = pd.read_excel(
"/Users/khalimconn-kowlessar/Downloads/Energy Information MASTER June 2025 - Standardised.xlsx", # "/Users/khalimconn-kowlessar/Downloads/Energy Information MASTER June 2025 - Standardised.xlsx",
sheet_name="Solar Properties", # sheet_name="Solar Properties",
) # )
asset_list = asset_list[~asset_list["estimated"]] # asset_list = asset_list[~asset_list["estimated"]]
asset_list["domna_address_1"] = asset_list["domna_address_1"].astype(str) # asset_list["domna_address_1"] = asset_list["domna_address_1"].astype(str)
asset_list = asset_list[["domna_address_1", "domna_postcode", "epc_os_uprn"]].rename( # asset_list = asset_list[["domna_address_1", "domna_postcode", "epc_os_uprn"]].rename(
columns={"domna_address_1": "address", "domna_postcode": "postcode", "epc_os_uprn": "uprn"} # columns={"domna_address_1": "address", "domna_postcode": "postcode", "epc_os_uprn": "uprn"}
) # )
asset_list = [
{
"address": "7 Crawley Road",
"postcode": "N22 6AN",
"uprn": 100021169757
},
{
"address": "7 Crawley Road",
"postcode": "N22 6AN",
"uprn": 100021169757
},
]
# Store the asset list in s3 # Store the asset list in s3
filename = f"{USER_ID}/{PORTFOLIO_ID}/asset_list.csv" filename = f"{USER_ID}/{PORTFOLIO_ID}/asset_list.csv"

View file

@ -75,6 +75,9 @@ class EpcClean:
] ]
] ]
# Average
filtered_data.groupby("lighting-description")["low-energy-lighting"].mean().reset_index()
# Convert low-energy-lighting to float # Convert low-energy-lighting to float
for row in filtered_data: for row in filtered_data:
row["low-energy-lighting"] = float(row["low-energy-lighting"]) row["low-energy-lighting"] = float(row["low-energy-lighting"])
@ -88,9 +91,10 @@ class EpcClean:
sums[description] += row["low-energy-lighting"] sums[description] += row["low-energy-lighting"]
counts[description] += 1 counts[description] += 1
# Scale to between 0 and 1
averages = [{ averages = [{
"lighting-description": correct_spelling(description.lower()), "lighting-description": correct_spelling(description.lower()) / 100,
"low-energy-lighting": total / counts[description] "low-energy-lighting": total / counts[description] / 100
} for description, total in sums.items()] } for description, total in sums.items()]
return averages return averages

View file

@ -181,6 +181,7 @@ class Costs:
"solid_floor_insulation": 0.26, "solid_floor_insulation": 0.26,
"low_energy_lighting": 0.26, "low_energy_lighting": 0.26,
"high_heat_retention_storage_heaters": 0.1, "high_heat_retention_storage_heaters": 0.1,
"windows_glazing": 0.15,
} }
# Preliminaries are a percentage of the total cost of the work and covers the cost of site-specific costs # Preliminaries are a percentage of the total cost of the work and covers the cost of site-specific costs

View file

@ -100,7 +100,7 @@ class LightingRecommendations:
:return: :return:
""" """
if self.property.lighting["low_energy_proportion"] == 100: if self.property.lighting["low_energy_proportion"] >= 1:
return return
leds_recommendation_config = next( leds_recommendation_config = next(

View file

@ -264,7 +264,7 @@ class SolarPvRecommendations:
scaffolding_options=self.scaffolding_options, scaffolding_options=self.scaffolding_options,
n_floors=self.property.number_of_floors n_floors=self.property.number_of_floors
) )
description = f"Install a {solar_pv_product['description']}" description = solar_pv_product['description']
if self.property.in_conservation_area: if self.property.in_conservation_area:
description += " Property is in a consevation area - please check with local planning authority." description += " Property is in a consevation area - please check with local planning authority."