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]
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[
(self.project_scores_matrix["Floor Area Segment"] == floor_area_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
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}")
# -----------------------

View file

@ -949,7 +949,7 @@ async def model_engine(body: PlanTriggerRequest):
total_uplift = optimal_solution["total_uplift"]
# This is the funding scheme selected
# 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
partial_project_score = optimal_solution["partial_project_score"]
# This is the uplift score ABS

View file

@ -17,15 +17,28 @@ def app():
:return:
"""
asset_list = pd.read_excel(
"/Users/khalimconn-kowlessar/Downloads/Energy Information MASTER June 2025 - Standardised.xlsx",
sheet_name="Solar Properties",
)
asset_list = asset_list[~asset_list["estimated"]]
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(
columns={"domna_address_1": "address", "domna_postcode": "postcode", "epc_os_uprn": "uprn"}
)
# asset_list = pd.read_excel(
# "/Users/khalimconn-kowlessar/Downloads/Energy Information MASTER June 2025 - Standardised.xlsx",
# sheet_name="Solar Properties",
# )
# asset_list = asset_list[~asset_list["estimated"]]
# 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(
# 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
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
for row in filtered_data:
row["low-energy-lighting"] = float(row["low-energy-lighting"])
@ -88,9 +91,10 @@ class EpcClean:
sums[description] += row["low-energy-lighting"]
counts[description] += 1
# Scale to between 0 and 1
averages = [{
"lighting-description": correct_spelling(description.lower()),
"low-energy-lighting": total / counts[description]
"lighting-description": correct_spelling(description.lower()) / 100,
"low-energy-lighting": total / counts[description] / 100
} for description, total in sums.items()]
return averages

View file

@ -181,6 +181,7 @@ class Costs:
"solid_floor_insulation": 0.26,
"low_energy_lighting": 0.26,
"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

View file

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

View file

@ -264,7 +264,7 @@ class SolarPvRecommendations:
scaffolding_options=self.scaffolding_options,
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:
description += " Property is in a consevation area - please check with local planning authority."