diff --git a/.idea/Model.iml b/.idea/Model.iml
index c6561970..09f2e496 100644
--- a/.idea/Model.iml
+++ b/.idea/Model.iml
@@ -7,7 +7,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 50cad4ca..fb10c6b0 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,7 +3,7 @@
-
+
diff --git a/asset_list/AssetList.py b/asset_list/AssetList.py
index 3731fc77..eca4ae1f 100644
--- a/asset_list/AssetList.py
+++ b/asset_list/AssetList.py
@@ -860,7 +860,7 @@ class AssetList:
return date_str.year
# Handle numeric year (float or int)
- if isinstance(date_str, (int, float)):
+ if isinstance(date_str, (int, float, np.int_)):
if 1000 <= int(date_str) <= 2100:
return int(date_str)
@@ -887,9 +887,6 @@ class AssetList:
self.landlord_year_built
].apply(extract_year)
- for x in self.standardised_asset_list[self.landlord_year_built].values:
- extract_year(x)
-
# We now create standard lookups
to_remap = {
self.landlord_property_type: {
@@ -1346,7 +1343,9 @@ class AssetList:
if self.new_format_non_insturives_present_v2:
existing_solar_non_intrusives_check = (
- self.standardised_asset_list["non-intrusives: ROOF ORIENTATION"] == "ALREADY HAS SOLAR PV"
+ self.standardised_asset_list["non-intrusives: ROOF ORIENTATION"].str.strip().isin(
+ ["ALREADY HAS SOLAR PV"]
+ )
)
else:
existing_solar_non_intrusives_check = (
diff --git a/asset_list/app.py b/asset_list/app.py
index 8af23f38..763f245f 100644
--- a/asset_list/app.py
+++ b/asset_list/app.py
@@ -58,6 +58,40 @@ def app():
EPC recommendations
Property UPRN
"""
+ # Abri
+ data_folder = "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Abri/Post Inspections"
+ data_filename = "Desktop ABRI data - Standardised After Programmes (2).xlsx"
+ sheet_name = "Reviewed List"
+ postcode_column = 'domna_postcode'
+ address1_column = "domna_address_1"
+ address1_method = None
+ fulladdress_column = "domna_full_address"
+ address_cols_to_concat = []
+ missing_postcodes_method = None
+ landlord_year_built = "landlord_year_built"
+ landlord_os_uprn = None
+ landlord_property_type = "PropertyType_original_from_landlord"
+ landlord_built_form = "BuildForm_original_from_landlord"
+ landlord_wall_construction = "Wall Construction_original_from_landlord"
+ landlord_roof_construction = None
+ landlord_heating_system = "HeatingType_original_from_landlord"
+ landlord_existing_pv = None
+ landlord_property_id = "landlord_property_id"
+ landlord_sap = None
+ outcomes_filename = None
+ outcomes_sheetname = None
+ outcomes_postcode = None
+ outcomes_houseno = None
+ outcomes_id = None
+ outcomes_address = None
+ master_filepaths = []
+ master_id_colnames = []
+ master_to_asset_list_filepath = None
+ phase = False
+ ecosurv_landlords = None
+ asset_list_header = 0
+ landlord_block_reference = None
+
# Freebridge
data_folder = "/Users/khalimconn-kowlessar/Documents/hestia/Customers/Freebridge"
data_filename = "Domna - FCH property data May 25 copy.xlsx"
diff --git a/backend/Funding.py b/backend/Funding.py
index cab11899..18e77713 100644
--- a/backend/Funding.py
+++ b/backend/Funding.py
@@ -38,6 +38,12 @@ 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
self.eco4_eligible = False
@@ -432,10 +438,7 @@ class Funding:
"""
Calculate the partial project ABS score for a single measure.
"""
- df = 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)
- ]
+ df = self.partial_project_scores_matrix
if measure_type == "internal_wall_insulation":
if current_wall_uvalue is None:
@@ -518,8 +521,10 @@ class Funding:
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["Post_Main_Heating_Source"] == "Air to Water ASHP") &
+ (df["Measure_Type"] == "B_Upgrade_nopreHCs") # We assume we'll be making a heating system upgrade
]
+
if pps.shape[0] != 1:
raise ValueError("something went wrong, more than one pps for ashp")
return pps.squeeze()["Cost Savings"]
diff --git a/backend/tests/test_funding.py b/backend/tests/test_funding.py
index 45e26dc8..7758de5f 100644
--- a/backend/tests/test_funding.py
+++ b/backend/tests/test_funding.py
@@ -988,3 +988,62 @@ def test_uplift(
main_fuel=main_fuel,
mainheat_energy_eff=mainheat_energy_eff,
)
+
+
+# Large scale testing for various measures
+measures = [
+ {"type": "solar_pv", "is_innovation": True, "uplift": 0.45},
+ {"type": "internal_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": "cavity_wall_insulation", "is_innovation": True, "uplift": 0.25},
+ {"type": "high_heat_retention_storage_heaters", "is_innovation": False, "uplift": 0},
+]
+epc_df = pd.read_csv(
+ "/Users/khalimconn-kowlessar/Downloads/domestic-E08000025-Birmingham/certificates.csv"
+)
+from tqdm import tqdm
+from etl.epc_clean.epc_attributes.MainheatAttributes import MainHeatAttributes
+from etl.epc_clean.epc_attributes.MainFuelAttributes import MainFuelAttributes
+
+mock_project_scores_matrix = mock_project_scores_matrix()
+mock_whlg_postcodes = mock_whlg_postcodes()
+mock_partial_scores_matrix = mock_partial_scores_matrix()
+
+for _, x in tqdm(epc_df.iterrows(), total=len(epc_df)):
+ # inputs
+ mainheat_energy_eff = x["MAINHEAT_ENERGY_EFF"]
+ heating_cleaner = MainHeatAttributes(description=x["MAINHEAT_DESCRIPTION"])
+ fuel_cleaner = MainFuelAttributes(description=x["MAIN_FUEL"])
+
+ h = heating_cleaner.process()
+ f = fuel_cleaner.process()
+
+ funding = Funding(
+ project_scores_matrix=mock_project_scores_matrix,
+ partial_project_scores_matrix=mock_partial_scores_matrix,
+ whlg_eligible_postcodes=mock_whlg_postcodes,
+ social_cavity_abs_rate=13.5,
+ social_solid_abs_rate=17,
+ private_cavity_abs_rate=13.5,
+ private_solid_abs_rate=17,
+ tenure="Social"
+ )
+
+ funding.check_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,
+ )