mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Handle wall thickness "Unmeasurable" 🟩
This commit is contained in:
parent
6c70c5a535
commit
78da2f88b6
6 changed files with 236 additions and 6 deletions
|
|
@ -66,9 +66,11 @@ class PasHubRdSapSiteNotesExtractor:
|
|||
val = self._get_in(list_to_process, key)
|
||||
return val is not None and val.lower() != "not known"
|
||||
|
||||
def _wall_thickness_in(self, list_to_process: List[str]) -> int:
|
||||
def _wall_thickness_in(self, list_to_process: List[str]) -> Optional[int]:
|
||||
val = self._get_in(list_to_process, "Wall thickness:")
|
||||
return int(val.split()[0]) if val else 0
|
||||
if not val or val.split()[0].lower() == "unmeasurable":
|
||||
return None
|
||||
return int(val.split()[0])
|
||||
|
||||
def _section(self, start: str, end: str) -> List[str]:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -802,6 +802,26 @@ class TestExtractNoPropertyPhoto:
|
|||
assert result.general.number_of_extensions == 2
|
||||
|
||||
|
||||
class TestWallThicknessExtraction:
|
||||
def _extractor(self) -> PasHubRdSapSiteNotesExtractor:
|
||||
return PasHubRdSapSiteNotesExtractor([])
|
||||
|
||||
def test_numeric_value_returns_int(self) -> None:
|
||||
assert self._extractor()._wall_thickness_in(["Wall thickness:", "310 mm"]) == 310
|
||||
|
||||
def test_unmeasurable_returns_none(self) -> None:
|
||||
assert self._extractor()._wall_thickness_in(["Wall thickness:", "Unmeasurable"]) is None
|
||||
|
||||
def test_unmeasurable_lowercase_returns_none(self) -> None:
|
||||
assert self._extractor()._wall_thickness_in(["Wall thickness:", "unmeasurable"]) is None
|
||||
|
||||
def test_unmeasurable_uppercase_returns_none(self) -> None:
|
||||
assert self._extractor()._wall_thickness_in(["Wall thickness:", "UNMEASURABLE"]) is None
|
||||
|
||||
def test_missing_field_returns_none(self) -> None:
|
||||
assert self._extractor()._wall_thickness_in([]) is None
|
||||
|
||||
|
||||
class TestSolidMasonryPartyWall:
|
||||
@pytest.fixture
|
||||
def bc(self) -> BuildingConstruction:
|
||||
|
|
|
|||
|
|
@ -1581,7 +1581,7 @@ def _map_main_building_part(
|
|||
construction_age_band=_extract_age_band(main.age_range),
|
||||
wall_construction=main.walls_construction_type,
|
||||
wall_insulation_type=main.walls_insulation_type,
|
||||
wall_thickness_measured=main.wall_thickness_mm > 0,
|
||||
wall_thickness_measured=main.wall_thickness_mm is not None,
|
||||
party_wall_construction=main.party_wall_construction_type,
|
||||
sap_floor_dimensions=_map_floor_dimensions(measurements.main_building.floors),
|
||||
wall_thickness_mm=main.wall_thickness_mm,
|
||||
|
|
@ -1605,7 +1605,7 @@ def _map_extension_building_part(
|
|||
construction_age_band=_extract_age_band(ext_c.age_range),
|
||||
wall_construction=ext_c.walls_construction_type,
|
||||
wall_insulation_type=ext_c.walls_insulation_type,
|
||||
wall_thickness_measured=ext_c.wall_thickness_mm > 0,
|
||||
wall_thickness_measured=ext_c.wall_thickness_mm is not None,
|
||||
party_wall_construction=ext_c.party_wall_construction_type,
|
||||
sap_floor_dimensions=_map_floor_dimensions(ext_m.floors),
|
||||
wall_thickness_mm=ext_c.wall_thickness_mm,
|
||||
|
|
|
|||
|
|
@ -694,3 +694,21 @@ class TestFromSiteNotesMiscTopLevel:
|
|||
def test_photovoltaic_array(self, result: EpcPropertyData) -> None:
|
||||
# renewables.photovoltaic_array: false
|
||||
assert result.photovoltaic_array is False
|
||||
|
||||
|
||||
class TestUnmeasurableWallThickness:
|
||||
"""wall_thickness_mm=None in site notes → wall_thickness_measured=False in domain."""
|
||||
|
||||
@pytest.fixture
|
||||
def result(self) -> EpcPropertyData:
|
||||
survey = from_dict(
|
||||
PasHubRdSapSiteNotes,
|
||||
load("pashub_rdsap_site_notes_example_unmeasurable_wall.json"),
|
||||
)
|
||||
return EpcPropertyDataMapper.from_site_notes(survey)
|
||||
|
||||
def test_wall_thickness_measured_is_false(self, result: EpcPropertyData) -> None:
|
||||
assert result.sap_building_parts[0].wall_thickness_measured is False
|
||||
|
||||
def test_wall_thickness_mm_is_none(self, result: EpcPropertyData) -> None:
|
||||
assert result.sap_building_parts[0].wall_thickness_mm is None
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class MainBuildingConstruction:
|
|||
walls_insulation_type: str
|
||||
thermal_conductivity_of_wall_insulation: str
|
||||
wall_u_value_known: bool
|
||||
wall_thickness_mm: int
|
||||
wall_thickness_mm: Optional[int]
|
||||
party_wall_construction_type: str
|
||||
filled_cavity_indicators: Optional[str] = None
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ class ExtensionConstruction:
|
|||
walls_insulation_type: str
|
||||
thermal_conductivity_of_wall_insulation: str
|
||||
wall_u_value_known: bool
|
||||
wall_thickness_mm: int
|
||||
wall_thickness_mm: Optional[int]
|
||||
party_wall_construction_type: str
|
||||
filled_cavity_indicators: Optional[str] = None
|
||||
|
||||
|
|
|
|||
190
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example_unmeasurable_wall.json
vendored
Normal file
190
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example_unmeasurable_wall.json
vendored
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
{
|
||||
"inspection_metadata": {
|
||||
"inspection_surveyor": "test",
|
||||
"email_address": "test@test.com",
|
||||
"report_reference": "49D422A9-0779-44DD-9665-464D35DFF1A8",
|
||||
"created_on": "2026-03-31",
|
||||
"date_of_inspection": "2026-03-31",
|
||||
"property_address": "1, Test Street, Test Town, Test County, TE1 1ST"
|
||||
},
|
||||
"general": {
|
||||
"epc_checked_before_assessment": true,
|
||||
"epc_exists_at_point_of_assessment": false,
|
||||
"inspection_date": "2026-03-31",
|
||||
"transaction_type": "None of the Above",
|
||||
"tenure": "Rented Social",
|
||||
"property_type": "House",
|
||||
"detachment_type": "Mid-terrace",
|
||||
"number_of_storeys": 2,
|
||||
"terrain_type": "Suburban",
|
||||
"number_of_extensions": 0,
|
||||
"electricity_smart_meter": true,
|
||||
"electric_meter_type": "Single",
|
||||
"dwelling_export_capable": true,
|
||||
"mains_gas_available": true,
|
||||
"gas_smart_meter": true,
|
||||
"gas_meter_accessible": true,
|
||||
"measurements_location": "Internal"
|
||||
},
|
||||
"building_construction": {
|
||||
"main_building": {
|
||||
"age_range": "I: 1996 - 2002",
|
||||
"age_indicators": "local knowledge",
|
||||
"walls_construction_type": "Cavity",
|
||||
"cavity_construction_indicators": "stretcher bond",
|
||||
"walls_insulation_type": "As built",
|
||||
"thermal_conductivity_of_wall_insulation": "Unknown",
|
||||
"wall_u_value_known": false,
|
||||
"wall_thickness_mm": null,
|
||||
"party_wall_construction_type": "Cavity Masonry, Unfilled"
|
||||
},
|
||||
"floor": {
|
||||
"floor_type": "Ground Floor",
|
||||
"floor_construction": "Suspended, not timber",
|
||||
"floor_insulation_type": "As Built",
|
||||
"floor_u_value_known": false
|
||||
}
|
||||
},
|
||||
"building_measurements": {
|
||||
"main_building": {
|
||||
"floors": [
|
||||
{
|
||||
"name": "Floor 1",
|
||||
"area_m2": 24.78,
|
||||
"height_m": 2.37,
|
||||
"heat_loss_perimeter_m": 14.21,
|
||||
"pwl_m": 6.15
|
||||
},
|
||||
{
|
||||
"name": "Floor 0",
|
||||
"area_m2": 24.78,
|
||||
"height_m": 2.35,
|
||||
"heat_loss_perimeter_m": 14.21,
|
||||
"pwl_m": 6.15
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"roof_space": {
|
||||
"main_building": {
|
||||
"construction_type": "Pitched roof (Slates or tiles), Access to loft",
|
||||
"insulation_at": "Joists",
|
||||
"roof_u_value_known": false,
|
||||
"insulation_thickness_mm": 100,
|
||||
"cavity_wall_construction_indicators": "No indicator of construction visible",
|
||||
"rooms_in_roof": false
|
||||
}
|
||||
},
|
||||
"windows": [
|
||||
{
|
||||
"id": 1,
|
||||
"location": "Main Building",
|
||||
"wall_type": "External wall",
|
||||
"glazing_type": "Double glazing, Unknown install date",
|
||||
"window_type": "Window",
|
||||
"frame_type": "Wooden or PVC",
|
||||
"glazing_gap": "16 mm or more",
|
||||
"draught_proofed": true,
|
||||
"permanent_shutters": false,
|
||||
"height_m": 1.36,
|
||||
"width_m": 1.0,
|
||||
"orientation": "South East"
|
||||
}
|
||||
],
|
||||
"heating_and_hot_water": {
|
||||
"main_heating": {
|
||||
"selection_method": "PCDF Search",
|
||||
"system_type": "Boiler with radiators or underfloor heating",
|
||||
"product_id": 18400,
|
||||
"manufacturer": "Vaillant",
|
||||
"model": "ecoFIT sustain 415",
|
||||
"orig_manufacturer": "Vaillant",
|
||||
"fuel": "Mains gas",
|
||||
"summer_efficiency": 0,
|
||||
"type": "Regular",
|
||||
"condensing": true,
|
||||
"year": "2018 - current",
|
||||
"mount": "Wall",
|
||||
"open_flue": "Room-sealed",
|
||||
"fan_assist": true,
|
||||
"status": "Normal status for an actual product",
|
||||
"central_heating_pump_age": "Unknown",
|
||||
"controls": "Programmer, room thermostat and TRVs",
|
||||
"flue_gas_heat_recovery_system": false,
|
||||
"weather_compensator": false,
|
||||
"emitter": "Radiators",
|
||||
"emitter_temperature": "Unknown"
|
||||
},
|
||||
"secondary_heating": {
|
||||
"secondary_fuel": "No Secondary Heating"
|
||||
},
|
||||
"water_heating": {
|
||||
"type": "Regular",
|
||||
"system": "From main heating 1",
|
||||
"cylinder_size": "Normal (90-130 litres)",
|
||||
"cylinder_measured_heat_loss": "Not known",
|
||||
"insulation_type": "Factory fitted",
|
||||
"insulation_thickness_mm": 12,
|
||||
"has_thermostat": true
|
||||
}
|
||||
},
|
||||
"ventilation": {
|
||||
"ventilation_type": "Natural",
|
||||
"has_fixed_air_conditioning": false,
|
||||
"number_of_open_flues": 0,
|
||||
"number_of_closed_flues": 0,
|
||||
"number_of_boiler_flues": 0,
|
||||
"number_of_other_flues": 0,
|
||||
"number_of_extract_fans": 2,
|
||||
"number_of_passive_vents": 0,
|
||||
"number_of_flueless_gas_fires": 0,
|
||||
"pressure_test": "No test",
|
||||
"draught_lobby": false
|
||||
},
|
||||
"conservatories": {
|
||||
"has_conservatory": false
|
||||
},
|
||||
"renewables": {
|
||||
"wind_turbines": false,
|
||||
"solar_hot_water": false,
|
||||
"photovoltaic_array": false,
|
||||
"number_of_pv_batteries": 0,
|
||||
"hydro": false
|
||||
},
|
||||
"room_count_elements": {
|
||||
"number_of_habitable_rooms": 2,
|
||||
"any_unheated_rooms": true,
|
||||
"number_of_heated_rooms": 0,
|
||||
"number_of_external_doors": 2,
|
||||
"number_of_insulated_external_doors": 0,
|
||||
"number_of_draughtproofed_external_doors": 2,
|
||||
"number_of_open_chimneys": 0,
|
||||
"number_of_blocked_chimneys": 0,
|
||||
"number_of_fixed_incandescent_bulbs": 0,
|
||||
"exact_led_cfl_count_known": true,
|
||||
"number_of_fixed_led_bulbs": 5,
|
||||
"number_of_fixed_cfl_bulbs": 4,
|
||||
"waste_water_heat_recovery": "None"
|
||||
},
|
||||
"water_use": {
|
||||
"number_of_baths": 1,
|
||||
"number_of_special_features": 0,
|
||||
"showers": [
|
||||
{
|
||||
"id": 1,
|
||||
"outlet_type": "Non-Electric Shower"
|
||||
}
|
||||
]
|
||||
},
|
||||
"customer_response": {
|
||||
"customer_present": true,
|
||||
"willing_to_answer_satisfaction_survey": false
|
||||
},
|
||||
"addendum": {
|
||||
"addendum": "None",
|
||||
"related_party_disclosure": "No related party",
|
||||
"hard_to_treat_cavity_access_issues": false,
|
||||
"hard_to_treat_cavity_high_exposure": false,
|
||||
"hard_to_treat_cavity_narrow_cavities": false
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue