additional fixes for EPC C properties

This commit is contained in:
Khalim Conn-Kowlessar 2025-08-26 15:39:34 +01:00
parent f47580bb3a
commit be6188ad23
3 changed files with 47 additions and 4 deletions

View file

@ -566,6 +566,10 @@ class Funding:
measure_code = "LI_lessequal100" if existing_li_thickness <= 100 else "LI_greater100"
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == measure_code]
# There's no funding for EPC C or above
if self.starting_sap_band in ["Low_C", "High_C", "Low_B", "High_B", "Low_A", "High_A"]:
return 0
if pps.shape[0] != 1:
raise ValueError(f"Invalid LI category: {measure_code}")
return pps.squeeze()["Cost Savings"]
@ -597,6 +601,10 @@ class Funding:
return pps.squeeze()["Cost Savings"]
if measure_type == "solid_floor_insulation":
if self.starting_sap_band in ["Low_C", "High_C", "Low_B", "High_B", "Low_A", "High_A"]:
# We don't fund SFI for properties starting at C or above
return 0
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == "SFI"]
if pps.shape[0] != 1:
raise ValueError("Invalid SFI category")
@ -607,9 +615,20 @@ class Funding:
(filtered_pps_matrix["Measure_Type"] == "Solar_PV") &
(filtered_pps_matrix["Pre_Main_Heating_Source"] == pre_heating_system)
]
if solar_pps_df.empty and self.starting_sap_band in [
"Low_C", "High_C", "Low_B", "High_B", "Low_B", "High_A"
]:
# No funding for EPC C or above
return 0
return solar_pps_df.squeeze()["Cost Savings"]
if measure_type == "air_source_heat_pump":
# No funding for EPC C or above
if self.starting_sap_band in ["Low_C", "High_C", "Low_B", "High_B", "Low_A", "High_A"]:
return 0
pps = filtered_pps_matrix[
(filtered_pps_matrix["Pre_Main_Heating_Source"] == pre_heating_system) &
(filtered_pps_matrix["Post_Main_Heating_Source"] == "Air to Water ASHP") &

View file

@ -900,8 +900,7 @@ class GoogleSolarApi:
return input_properties
@classmethod
def default_panel_performance(cls, property_instance):
def default_panel_performance(self, property_instance):
"""
In a small number of cases, where properties have simulated uprns, we do not have a longitude and latitude
value and therefore we just return a default panel performance
@ -911,6 +910,20 @@ class GoogleSolarApi:
cost_instance = Costs(property_instance=property_instance)
material_1_6 = next(
(m for m in self.solar_materials if m["type"] == "solar_pv" and
abs(m["size"] - 1.6) < 0.1 and not m["includes_battery"]),
None
)
material_3_2 = next(
(m for m in self.solar_materials if m["type"] == "solar_pv" and
abs(m["size"] - 3.2) < 0.1 and not m["includes_battery"]),
None
)
if material_1_6 is None or material_3_2 is None:
raise ValueError("No suitable solar product found for the default configuration.")
# We return a 1.6 and 3.2 kwp system
panel_performance = pd.DataFrame(
[
@ -918,7 +931,12 @@ class GoogleSolarApi:
'n_panels': 8,
'yearly_dc_energy': 3200 * assumptions.MEDIAN_WATTAGE_TO_DC,
'total_cost': cost_instance.solar_pv(
n_panels=8, has_battery=False, n_floors=property_instance.number_of_floors
solar_product=material_1_6,
scaffolding_options=[
{"total_cost": 1000, "size": property_instance.number_of_floors},
{"total_cost": 1000, "size": 3}
],
n_floors=property_instance.number_of_floors
)["total"],
'weighted_ratio': None,
'panneled_roof_area': 8 * assumptions.RDSAP_AREA_PER_PANEL,
@ -938,7 +956,12 @@ class GoogleSolarApi:
'n_panels': 4,
'yearly_dc_energy': 1600 * assumptions.MEDIAN_WATTAGE_TO_DC,
'total_cost': cost_instance.solar_pv(
n_panels=6, has_battery=False, n_floors=property_instance.number_of_floors
solar_product=material_3_2,
scaffolding_options=[
{"total_cost": 1000, "size": property_instance.number_of_floors},
{"total_cost": 1000, "size": 3}
],
n_floors=property_instance.number_of_floors
)["total"],
'weighted_ratio': None,
'panneled_roof_area': 4 * assumptions.RDSAP_AREA_PER_PANEL,

View file

@ -894,6 +894,7 @@ async def model_engine(body: PlanTriggerRequest):
0, 0, 0, 0
)
continue
(
r["partial_project_score"], r["partial_project_funding"], r["innovation_uplift"],
r["uplift_project_score"]