diff --git a/model_data/epc_attributes/HotWaterAttributes.py b/model_data/epc_attributes/HotWaterAttributes.py index d8669f9d..2a981674 100644 --- a/model_data/epc_attributes/HotWaterAttributes.py +++ b/model_data/epc_attributes/HotWaterAttributes.py @@ -110,7 +110,12 @@ class HotWaterAttributes(Definitions): "nwy wrth fwy nag un pwynt": "gas multipoint", "popty estynedig olew": "oil range cooker", "dim system ar gael rhagdybir bod twymwr tanddwr trydan": "no system present electric immersion assumed", - "o'r brif system, dim thermostat ar y silindr": "from main system, no cylinder thermostat" + "o'r brif system, dim thermostat ar y silindr": "from main system, no cylinder thermostat", + "trydan ar unwaith yn y fan lle maegçön cael ei ddefnyddio, adfer gwres d+¦r gwastraff": "electric " + "instantaneous at " + "point of use, " + "waste water heat " + "recovery" } def __init__(self, description: str): diff --git a/model_data/epc_attributes/MainheatAttributes.py b/model_data/epc_attributes/MainheatAttributes.py index 569935b8..dbed54fb 100644 --- a/model_data/epc_attributes/MainheatAttributes.py +++ b/model_data/epc_attributes/MainheatAttributes.py @@ -44,6 +44,7 @@ class MainHeatAttributes(Definitions): "gwresogyddion ystafell, glo carreg": "room heaters, coal", "pwmp gwres sygçön tarddu yn yr awyr, rheiddiaduron, trydan": "air source heat pump, radiators, electric", "gwresogyddion ystafell, nwy prif gyflenwad": "room heaters, mains gas", + "bwyler a rheiddiaduron, dau danwydd mwynau a choed": "boiler and radiators, dual fuel mineral and wood" } REMAP = { @@ -52,11 +53,14 @@ class MainHeatAttributes(Definitions): "solar-assisted heat pump": "solar assisted heat pump" } + edge_case_result = {} + is_edge_case = False + def __init__(self, description: str): self.description = switch_chars(description.lower()) - self.description: str = clean_description(self.description) + self.description: str = clean_description(self.description).strip() # Remove special characters self.nodata = not description or description in self.DATA_ANOMALY_MATCHES @@ -76,27 +80,38 @@ class MainHeatAttributes(Definitions): self.description = remapped - if not description or not any( + self.process_edge_cases() + + if (not description or not any( rt in self.description for rt in self.HEAT_SYSTEMS + self.FUEL_TYPES + self.DISTRIBUTION_SYSTEMS + self.OTHERS - ): + ) and not self.is_edge_case): raise ValueError('Invalid description') - def process_edge_cases(self, result) -> (dict, bool): + def process_edge_cases(self) -> (dict, bool): """ We handle some edge cases that will cause issues, for example descriptions that are missing a heating system :return: truple containing dictionary result, and boolean is_edge_case """ - edge_cases = [", underfloor, electric"] + self.edge_case_result = {} + self.is_edge_case = False + + edge_cases = [", underfloor, electric", ", underfloor"] if self.description not in edge_cases: - return result, False + return if self.description == ", underfloor, electric": - result["has_electric"] = True - result['has_underfloor_heating'] = True - return result, True + self.edge_case_result["has_electric"] = True + self.edge_case_result['has_underfloor_heating'] = True + self.is_edge_case = True + return + + if self.description == ", underfloor": + self.edge_case_result['has_underfloor_heating'] = True + self.is_edge_case = True + return def process(self) -> Dict[str, Union[str, bool]]: @@ -109,8 +124,8 @@ class MainHeatAttributes(Definitions): if self.nodata: return result - result, is_edge_case = self.process_edge_cases(result) - if is_edge_case: + if self.is_edge_case: + result.update(self.edge_case_result) return result description = self.description.split(',') diff --git a/model_data/epc_attributes/RoofAttributes.py b/model_data/epc_attributes/RoofAttributes.py index faaba32d..1b0d640a 100644 --- a/model_data/epc_attributes/RoofAttributes.py +++ b/model_data/epc_attributes/RoofAttributes.py @@ -28,6 +28,7 @@ class RoofAttributes(Definitions): "ystafell(oedd) to, wedigçöi hinswleiddio (rhagdybiaeth)": "roof room(s), insulated (assumed)", "ystafell(oedd) to, inswleiddio cyfyngedig (rhagdybiaeth)": "roof room(s), limited insulation (assumed)", "ystafell(oedd) to, inswleiddio cyfyngedig": "roof room(s), limited insulation", + "ystafell(oedd) to, nenfwd wedigçöi inswleiddio": "roof room(s), ceiling insulated" } def __init__(self, description: str): @@ -70,7 +71,7 @@ class RoofAttributes(Definitions): insulation_thickness = loft_insulation_thickness_match2.group(1) else: insulation_thickness = loft_insulation_thickness_match3.group(1) - + self.description = f"pitched, {insulation_thickness} loft insulation" elif uvalue_search: uvalue = uvalue_search.group(1) diff --git a/model_data/epc_attributes/WindowAttributes.py b/model_data/epc_attributes/WindowAttributes.py index 9b794491..361df4d9 100644 --- a/model_data/epc_attributes/WindowAttributes.py +++ b/model_data/epc_attributes/WindowAttributes.py @@ -27,6 +27,9 @@ class WindowAttributes(Definitions): "gwydrau triphlyg llawn": "fully triple glazed", "gwydrau triphlyg rhannol": "partial triple glazed", "gwydrau triphlyg mwyaf": "mostly triple glazed", + "gwydrau eilaidd llawn": "full secondary glazing", + "gwydrau eilaidd mwyaf": "mostly secondary glazing", + "gwydrau eilaidd rhannol": "partial secondary glazing", } def __init__(self, description: str): diff --git a/model_data/tests/test_data/test_hot_water_attributes_cases.py b/model_data/tests/test_data/test_hot_water_attributes_cases.py index 5c48f57e..a31998fe 100644 --- a/model_data/tests/test_data/test_hot_water_attributes_cases.py +++ b/model_data/tests/test_data/test_hot_water_attributes_cases.py @@ -215,4 +215,8 @@ hotwater_cases = [ 'system_type': 'from main system', 'thermostat_characteristics': 'no cylinder thermostat', 'heating_scope': None, 'energy_recovery': None, 'tariff_type': None, 'extra_features': None, 'chp_systems': None, 'distribution_system': None, 'no_system_present': None, 'assumed': False, "appliance": None}, + {'original_description': 'Trydan ar unwaith yn y fan lle maeGÇÖn cael ei ddefnyddio, adfer gwres d+¦r gwastraff', + 'heater_type': 'electric instantaneous', 'system_type': None, 'thermostat_characteristics': None, + 'heating_scope': None, 'energy_recovery': 'waste water heat recovery', 'tariff_type': None, 'extra_features': None, + 'chp_systems': None, 'distribution_system': None, 'no_system_present': None, 'assumed': False, "appliance": None}, ] diff --git a/model_data/tests/test_data/test_mainheat_attributes_cases.py b/model_data/tests/test_data/test_mainheat_attributes_cases.py index 2b919baa..6a5116e8 100644 --- a/model_data/tests/test_data/test_mainheat_attributes_cases.py +++ b/model_data/tests/test_data/test_mainheat_attributes_cases.py @@ -1432,4 +1432,42 @@ mainheat_cases = [ 'has_electricaire': False, 'has_assumed_for_most_rooms': False, 'has_underfloor_heating': False, "has_electric_heat_pumps": False, "has_micro-cogeneration": False}, + {'original_description': ', underfloor', 'has_radiators': False, 'has_fan_coil_units': False, + 'has_pipes_in_screed_above_insulation': False, 'has_pipes_in_insulated_timber_floor': False, + 'has_pipes_in_concrete_slab': False, 'has_boiler': False, 'has_air_source_heat_pump': False, + 'has_room_heaters': False, 'has_electric_storage_heaters': False, 'has_warm_air': False, + 'has_electric_underfloor_heating': False, 'has_electric_ceiling_heating': False, 'has_community_scheme': False, + 'has_ground_source_heat_pump': False, 'has_no_system_present': False, 'has_portable_electric_heaters': False, + 'has_water_source_heat_pump': False, 'has_electric': False, 'has_mains_gas': False, 'has_wood_logs': False, + 'has_LPG': False, 'has_coal': False, 'has_oil': False, 'has_wood_pellets': False, 'has_anthracite': False, + 'has_dual_fuel_mineral_and_wood': False, 'has_smokeless_fuel': False, 'has_lpg': False, 'has_assumed': False, + 'has_electricaire': False, 'has_assumed_for_most_rooms': False, 'has_underfloor_heating': True, + "has_electric_heat_pumps": False, + "has_micro-cogeneration": False}, + {'original_description': 'Boiler and radiators, dual fuel (mineral and wood)', 'has_radiators': True, + 'has_fan_coil_units': False, + 'has_pipes_in_screed_above_insulation': False, 'has_pipes_in_insulated_timber_floor': False, + 'has_pipes_in_concrete_slab': False, 'has_boiler': True, 'has_air_source_heat_pump': False, + 'has_room_heaters': False, 'has_electric_storage_heaters': False, 'has_warm_air': False, + 'has_electric_underfloor_heating': False, 'has_electric_ceiling_heating': False, 'has_community_scheme': False, + 'has_ground_source_heat_pump': False, 'has_no_system_present': False, 'has_portable_electric_heaters': False, + 'has_water_source_heat_pump': False, 'has_electric': False, 'has_mains_gas': False, 'has_wood_logs': False, + 'has_LPG': False, 'has_coal': False, 'has_oil': False, 'has_wood_pellets': False, 'has_anthracite': False, + 'has_dual_fuel_mineral_and_wood': True, 'has_smokeless_fuel': False, 'has_lpg': False, 'has_assumed': False, + 'has_electricaire': False, 'has_assumed_for_most_rooms': False, 'has_underfloor_heating': False, + "has_electric_heat_pumps": False, + "has_micro-cogeneration": False}, + {'original_description': 'Bwyler a rheiddiaduron, dau danwydd (mwynau a choed)', 'has_radiators': True, + 'has_fan_coil_units': False, + 'has_pipes_in_screed_above_insulation': False, 'has_pipes_in_insulated_timber_floor': False, + 'has_pipes_in_concrete_slab': False, 'has_boiler': True, 'has_air_source_heat_pump': False, + 'has_room_heaters': False, 'has_electric_storage_heaters': False, 'has_warm_air': False, + 'has_electric_underfloor_heating': False, 'has_electric_ceiling_heating': False, 'has_community_scheme': False, + 'has_ground_source_heat_pump': False, 'has_no_system_present': False, 'has_portable_electric_heaters': False, + 'has_water_source_heat_pump': False, 'has_electric': False, 'has_mains_gas': False, 'has_wood_logs': False, + 'has_LPG': False, 'has_coal': False, 'has_oil': False, 'has_wood_pellets': False, 'has_anthracite': False, + 'has_dual_fuel_mineral_and_wood': True, 'has_smokeless_fuel': False, 'has_lpg': False, 'has_assumed': False, + 'has_electricaire': False, 'has_assumed_for_most_rooms': False, 'has_underfloor_heating': False, + "has_electric_heat_pumps": False, + "has_micro-cogeneration": False}, ] diff --git a/model_data/tests/test_data/test_roof_attributes_cases.py b/model_data/tests/test_data/test_roof_attributes_cases.py index 8b48881f..647d4fe5 100644 --- a/model_data/tests/test_data/test_roof_attributes_cases.py +++ b/model_data/tests/test_data/test_roof_attributes_cases.py @@ -386,4 +386,8 @@ clean_roof_test_cases = [ 'thermal_transmittance_unit': None, 'is_pitched': False, 'is_roof_room': True, 'is_loft': False, 'is_flat': False, 'is_thatched': False, 'is_at_rafters': False, 'is_assumed': True, 'has_dwelling_above': False, 'is_valid': True, 'insulation_thickness': 'below average'}, + {'original_description': 'Ystafell(oedd) to, nenfwd wediGÇÖi inswleiddio', 'thermal_transmittance': None, + 'thermal_transmittance_unit': None, 'is_pitched': False, 'is_roof_room': True, 'is_loft': False, 'is_flat': False, + 'is_thatched': False, 'is_at_rafters': False, 'is_assumed': False, 'has_dwelling_above': False, 'is_valid': True, + 'insulation_thickness': 'average'}, ] diff --git a/model_data/tests/test_data/test_window_attributes_cases.py b/model_data/tests/test_data/test_window_attributes_cases.py index 218019d8..1eeeee21 100644 --- a/model_data/tests/test_data/test_window_attributes_cases.py +++ b/model_data/tests/test_data/test_window_attributes_cases.py @@ -54,4 +54,10 @@ windows_cases = [ 'glazing_type': 'double', 'no_data': False}, {'original_description': 'Gwydrau triphlyg llawn', 'has_glazing': True, 'glazing_coverage': 'full', 'glazing_type': 'triple', 'no_data': False}, + {'original_description': 'Gwydrau eilaidd llawn', 'has_glazing': True, 'glazing_coverage': 'full', + 'glazing_type': 'secondary', 'no_data': False}, + {'original_description': 'Gwydrau eilaidd mwyaf', 'has_glazing': True, 'glazing_coverage': 'most', + 'glazing_type': 'secondary', 'no_data': False}, + {'original_description': 'Gwydrau eilaidd rhannol', 'has_glazing': True, 'glazing_coverage': 'partial', + 'glazing_type': 'secondary', 'no_data': False}, ]