fixed error in reference to fuel type

This commit is contained in:
Khalim Conn-Kowlessar 2025-08-09 17:35:48 +01:00
parent a9018a541e
commit 62d92f29e6
2 changed files with 56 additions and 25 deletions

View file

@ -1,6 +1,8 @@
from enum import Enum
from typing import List
import pandas as pd
from backend.app.plan.schemas import HousingType, WALL_INSULATION_MEASURES, ROOF_INSULATION_MEASURES, MEASURE_MAP
@ -38,11 +40,6 @@ class Funding:
self.floor_area_band = None
self.project_scores_matrix = project_scores_matrix
self.partial_project_scores_matrix = partial_project_scores_matrix
# Filter on the starting band and floor area so we only do this once
self.partial_project_scores_matrix = self.partial_project_scores_matrix[
(self.partial_project_scores_matrix["Total Floor Area Band"] == self.floor_area_band) &
(self.partial_project_scores_matrix["Starting Band"] == self.starting_sap_band)
]
self.whlg_eligible_postcodes = whlg_eligible_postcodes
@ -408,16 +405,16 @@ class Funding:
]:
return 'Electric Storage Heaters Responsiveness >0.2'
if mainheating["has_room_heaters"] and main_fuel["fuel_tye"] == "lpg":
if mainheating["has_room_heaters"] and main_fuel["fuel_type"] == "lpg":
return 'Bottled LPG Room Heaters'
if mainheating["has_room_heaters"] and main_fuel["fuel_tye"] == "electricity":
if mainheating["has_room_heaters"] and main_fuel["fuel_type"] == "electricity":
return 'Electric Room Heaters'
if mainheating["has_room_heaters"] and main_fuel["fuel_tye"] == "mains gas":
if mainheating["has_room_heaters"] and main_fuel["fuel_type"] == "mains gas":
return 'Gas Room Heaters'
if mainheating["has_room_heaters"] and main_fuel["fuel_tye"] in [
if mainheating["has_room_heaters"] and main_fuel["fuel_type"] in [
"dual fuel appliance mineral and wood", "manufactured smokeless fuel"
]:
return 'Solid Fossil Room Heaters'
@ -430,6 +427,7 @@ class Funding:
mainheating: dict,
main_fuel: dict,
mainheat_energy_eff: str,
filtered_pps_matrix: pd.DataFrame,
current_wall_uvalue: float = None,
is_partial: bool = False,
existing_li_thickness: float = None,
@ -438,7 +436,7 @@ class Funding:
"""
Calculate the partial project ABS score for a single measure.
"""
df = self.partial_project_scores_matrix
# Filter on the starting band and floor area so we only do this once
if measure_type == "internal_wall_insulation":
if current_wall_uvalue is None:
@ -446,7 +444,7 @@ class Funding:
starting_str, ending_str = self.get_starting_ending_uvalues(current_wall_uvalue)
measure_code = f"IWI_solid_{starting_str}_{ending_str}"
pps = df[df["Measure_Type"] == measure_code]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == measure_code]
if pps.shape[0] != 1:
raise ValueError(f"Invalid IWI category: {measure_code}")
@ -458,7 +456,7 @@ class Funding:
starting_str, ending_str = self.get_starting_ending_uvalues(current_wall_uvalue)
measure_code = f"EWI_solid_{starting_str}_{ending_str}"
pps = df[df["Measure_Type"] == measure_code]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == measure_code]
if pps.shape[0] != 1:
raise ValueError(f"Invalid EWI category: {measure_code}")
@ -466,7 +464,7 @@ class Funding:
if measure_type == "cavity_wall_insulation":
measure_code = "CWI_partial_fill" if is_partial else "CWI_0.033"
pps = df[df["Measure_Type"] == measure_code]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == measure_code]
if pps.shape[0] != 1:
raise ValueError(f"Invalid CWI category: {measure_code}")
@ -477,14 +475,14 @@ class Funding:
raise ValueError("existing_li_thickness is required for LI")
measure_code = "LI_lessequal100" if existing_li_thickness <= 100 else "LI_greater100"
pps = df[df["Measure_Type"] == measure_code]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == measure_code]
if pps.shape[0] != 1:
raise ValueError(f"Invalid LI category: {measure_code}")
return pps.squeeze()["Cost Savings"]
if measure_type == "flat_roof_insulation":
pps = df[df["Measure_Type"] == "FRI"]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == "FRI"]
if pps.shape[0] != 1:
raise ValueError("Invalid FRI category")
return pps.squeeze()["Cost Savings"]
@ -493,36 +491,38 @@ class Funding:
# Use the more conservative score (unin is usually lower)
# code = "RIRI_res_unin" if not is_roof_insulated else "RIRI_res_in"
code = "RIRI_res_unin"
pps = df[df["Measure_Type"] == code]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == code]
if pps.shape[0] != 1:
raise ValueError(f"Invalid RIRI category: {code}")
return pps.squeeze()["Cost Savings"]
if measure_type == "suspended_floor_insulation":
pps = df[df["Measure_Type"] == "UFI"]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == "UFI"]
if pps.shape[0] != 1:
raise ValueError("Invalid UFI category")
return pps.squeeze()["Cost Savings"]
if measure_type == "solid_floor_insulation":
pps = df[df["Measure_Type"] == "SFI"]
pps = filtered_pps_matrix[filtered_pps_matrix["Measure_Type"] == "SFI"]
if pps.shape[0] != 1:
raise ValueError("Invalid SFI category")
return pps.squeeze()["Cost Savings"]
if measure_type == "solar_pv":
pre_heating_system = self._map_to_pre_main_heating(mainheating, main_fuel, mainheat_energy_eff)
solar_pps_df = df[
(df["Measure_Type"] == "Solar_PV") & (df["Pre_Main_Heating_Source"] == pre_heating_system)
solar_pps_df = filtered_pps_matrix[
(filtered_pps_matrix["Measure_Type"] == "Solar_PV") &
(filtered_pps_matrix["Pre_Main_Heating_Source"] == pre_heating_system)
]
return solar_pps_df.squeeze()["Cost Savings"]
if measure_type == "air_source_heat_pump":
pre_heating_system = self._map_to_pre_main_heating(mainheating, main_fuel, mainheat_energy_eff)
pps = df[
(df["Pre_Main_Heating_Source"] == pre_heating_system) &
(df["Post_Main_Heating_Source"] == "Air to Water ASHP") &
(df["Measure_Type"] == "B_Upgrade_nopreHCs") # We assume we'll be making a heating system upgrade
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") &
(filtered_pps_matrix["Measure_Type"] == "B_Upgrade_nopreHCs")
# We assume we'll be making a heating system upgrade
]
if pps.shape[0] != 1:
@ -763,6 +763,11 @@ class Funding:
self.ending_sap_band = self.get_sap_band(ending_sap)
self.floor_area_band = self.get_floor_area_band(floor_area)
filtered_pps_matrix = self.partial_project_scores_matrix[
(self.partial_project_scores_matrix["Total Floor Area Band"] == self.floor_area_band) &
(self.partial_project_scores_matrix["Starting Band"] == self.starting_sap_band)
].copy()
if self.tenure == "Private":
# ECO4 PRS
self.eco4_prs_eligibility(starting_sap, ending_sap, measure_types, has_solar, solar_eligible)
@ -774,7 +779,6 @@ class Funding:
self.eco4_funding = self.full_project_abs * (
self.private_cavity_abs_rate if is_cavity else self.private_solid_abs_rate)
elif self.tenure == "Social":
# ECO4 Social
self.eco4_sh_eligibility(
@ -791,6 +795,11 @@ class Funding:
# We calculate uplift innovation, where required
project_uplifts = []
for i, measure in enumerate(measure_types):
if not innovation_flags[i]:
# Capture 0 innovation uplift for debugging
project_uplifts.append(0)
continue
pps = self.calculate_partial_project_abs(
measure_type=measure,
mainheating=mainheating,
@ -799,6 +808,7 @@ class Funding:
current_wall_uvalue=current_wall_uvalue,
is_partial=is_partial,
existing_li_thickness=existing_li_thickness,
filtered_pps_matrix=filtered_pps_matrix,
)
project_uplifts.append(pps * uplifts[i])
total_uplift = sum(project_uplifts)
@ -817,6 +827,7 @@ class Funding:
current_wall_uvalue=current_wall_uvalue,
is_partial=is_partial,
existing_li_thickness=existing_li_thickness,
filtered_pps_matrix=filtered_pps_matrix
)

View file

@ -994,8 +994,11 @@ def test_uplift(
measures = [
{"type": "solar_pv", "is_innovation": True, "uplift": 0.45},
{"type": "internal_wall_insulation", "is_innovation": False, "uplift": 0},
{"type": "cavity_wall_insulation", "is_innovation": False, "uplift": 0},
{"type": "external_wall_insulation", "is_innovation": False, "uplift": 0},
{"type": "loft_insulation", "is_innovation": False, "uplift": 0},
{"type": "air_source_heat_pump", "is_innovation": False, "uplift": 0},
{"type": "double_glazing", "is_innovation": False, "uplift": 0},
{"type": "cavity_wall_insulation", "is_innovation": True, "uplift": 0.25},
{"type": "high_heat_retention_storage_heaters", "is_innovation": False, "uplift": 0},
]
@ -1030,6 +1033,23 @@ for _, x in tqdm(epc_df.iterrows(), total=len(epc_df)):
tenure="Social"
)
self = funding
measures = measures
starting_sap = 33
ending_sap = 69
floor_area = 71
mainheat_description = x["MAINHEAT_DESCRIPTION"]
heating_control_description = x["MAINHEATCONT_DESCRIPTION"]
is_cavity = True
current_wall_uvalue = 2
is_partial = False
existing_li_thickness = 0
has_wall_insulation_recommendation = True
has_roof_insulation_recommendation = True
mainheating = h
main_fuel = f
mainheat_energy_eff = mainheat_energy_eff
funding.check_funding(
measures=measures,
starting_sap=33,