mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
delete code related to deprecated Dwelling class
This commit is contained in:
parent
fa3e276dc4
commit
99908537ba
3 changed files with 7 additions and 900 deletions
|
|
@ -1,143 +0,0 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class PropertyDetails:
|
||||
property_type: str # e.g. "House", "Flat"
|
||||
built_form: str # e.g. "Mid-terrace", "Detached"
|
||||
tenure: str # e.g. "Owner-occupied", "Rented Social"
|
||||
number_of_storeys: int
|
||||
construction_age_band: Optional[str] = None # e.g. "1950-1966", "I: 1996 - 2002"
|
||||
transaction_type: Optional[str] = None
|
||||
terrain_type: Optional[str] = None
|
||||
mains_gas_available: Optional[bool] = None
|
||||
electricity_smart_meter: Optional[bool] = None
|
||||
gas_smart_meter: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class FloorDimensions:
|
||||
"""Floor area and geometry for one storey of one building part."""
|
||||
|
||||
total_floor_area_m2: float
|
||||
height_m: float
|
||||
heat_loss_perimeter_m: Optional[float] = None
|
||||
party_wall_length_m: Optional[float] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WallDetails:
|
||||
construction_type: str # e.g. "Cavity", "Solid masonry"
|
||||
insulation_type: str # e.g. "As built", "Filled cavity", "External"
|
||||
thickness_mm: Optional[int] = None
|
||||
party_wall_construction_type: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoofDetails:
|
||||
construction_type: str # e.g. "Pitched, access to loft", "Flat"
|
||||
insulation_at: Optional[str] = None # e.g. "Joists", "Rafters"
|
||||
insulation_thickness_mm: Optional[int] = None
|
||||
has_rooms_in_roof: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class FloorDetails:
|
||||
construction_type: str # e.g. "Solid", "Suspended timber"
|
||||
insulation_type: Optional[str] = None # e.g. "As built", "Insulated"
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowDetails:
|
||||
glazing_type: str # e.g. "Double glazing", "Triple glazing"
|
||||
orientation: Optional[str] = None
|
||||
frame_type: Optional[str] = None
|
||||
glazing_gap: Optional[str] = None
|
||||
draught_proofed: Optional[bool] = None
|
||||
height_m: Optional[float] = None
|
||||
width_m: Optional[float] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingSystem:
|
||||
fuel: str # e.g. "Mains gas", "Oil", "Electricity"
|
||||
system_type: str # e.g. "Boiler with radiators or underfloor heating"
|
||||
boiler_type: Optional[str] = None # e.g. "Regular", "Combi"
|
||||
manufacturer: Optional[str] = None
|
||||
model: Optional[str] = None
|
||||
condensing: Optional[bool] = None
|
||||
controls: Optional[str] = None
|
||||
flue_gas_heat_recovery: bool = False
|
||||
weather_compensator: bool = False
|
||||
emitter: Optional[str] = None # e.g. "Radiators", "Underfloor"
|
||||
|
||||
|
||||
@dataclass
|
||||
class HotWaterSystem:
|
||||
source: str # e.g. "From main heating 1", "Immersion heater"
|
||||
cylinder_size: Optional[str] = None
|
||||
insulation_type: Optional[str] = None
|
||||
insulation_thickness_mm: Optional[int] = None
|
||||
has_thermostat: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SecondaryHeatingSystem:
|
||||
fuel: str # e.g. "Wood logs", "Electricity"
|
||||
|
||||
|
||||
@dataclass
|
||||
class VentilationDetails:
|
||||
ventilation_type: str # e.g. "Natural", "Mechanical Extract - Decentralised"
|
||||
number_of_open_flues: int = 0
|
||||
number_of_closed_flues: int = 0
|
||||
number_of_boiler_flues: int = 0
|
||||
number_of_other_flues: int = 0
|
||||
number_of_extract_fans: int = 0
|
||||
number_of_passive_vents: int = 0
|
||||
number_of_flueless_gas_fires: int = 0
|
||||
has_fixed_air_conditioning: bool = False
|
||||
pressure_test: Optional[str] = None
|
||||
draught_lobby: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewablesDetails:
|
||||
has_photovoltaic: bool = False
|
||||
has_solar_hot_water: bool = False
|
||||
has_wind_turbines: bool = False
|
||||
has_hydro: bool = False
|
||||
number_of_pv_batteries: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class LightingDetails:
|
||||
number_of_led_bulbs: Optional[int] = None
|
||||
number_of_cfl_bulbs: Optional[int] = None
|
||||
number_of_incandescent_bulbs: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Dwelling:
|
||||
property_details: PropertyDetails
|
||||
# One entry per storey per building part (main building + any extensions, flattened)
|
||||
floor_dimensions: List[FloorDimensions]
|
||||
walls: WallDetails
|
||||
roof: RoofDetails
|
||||
floor: FloorDetails
|
||||
windows: List[WindowDetails]
|
||||
main_heating: MainHeatingSystem
|
||||
hot_water: HotWaterSystem
|
||||
ventilation: VentilationDetails
|
||||
renewables: RenewablesDetails
|
||||
lighting: LightingDetails
|
||||
number_of_habitable_rooms: int
|
||||
number_of_external_doors: int
|
||||
number_of_open_chimneys: int
|
||||
has_conservatory: bool = False
|
||||
secondary_heating: Optional[SecondaryHeatingSystem] = None
|
||||
number_of_blocked_chimneys: int = 0
|
||||
number_of_baths: Optional[int] = None
|
||||
number_of_showers: Optional[int] = None
|
||||
waste_water_heat_recovery: Optional[str] = None
|
||||
|
|
@ -1,20 +1,5 @@
|
|||
from typing import List, Optional, Union
|
||||
|
||||
from datatypes.epc.domain.dwelling import (
|
||||
Dwelling,
|
||||
FloorDimensions,
|
||||
FloorDetails,
|
||||
HotWaterSystem,
|
||||
LightingDetails,
|
||||
MainHeatingSystem,
|
||||
PropertyDetails,
|
||||
RenewablesDetails,
|
||||
RoofDetails,
|
||||
SecondaryHeatingSystem,
|
||||
VentilationDetails,
|
||||
WallDetails,
|
||||
WindowDetails,
|
||||
)
|
||||
from typing import Union
|
||||
from datatypes.epc.domain.epc_property_data import EpcPropertyData
|
||||
from datatypes.epc.schema.rdsap_schema_17_0 import RdSapSchema17_0
|
||||
from datatypes.epc.schema.rdsap_schema_17_1 import RdSapSchema17_1
|
||||
from datatypes.epc.schema.rdsap_schema_18_0 import RdSapSchema18_0
|
||||
|
|
@ -22,10 +7,7 @@ from datatypes.epc.schema.rdsap_schema_19_0 import RdSapSchema19_0
|
|||
from datatypes.epc.schema.rdsap_schema_20_0_0 import RdSapSchema20_0_0
|
||||
from datatypes.epc.schema.rdsap_schema_21_0_0 import RdSapSchema21_0_0
|
||||
from datatypes.epc.schema.rdsap_schema_21_0_1 import RdSapSchema21_0_1
|
||||
from datatypes.epc.surveys.pashub_rdsap_site_notes import (
|
||||
PasHubRdSapSiteNotes,
|
||||
Window,
|
||||
)
|
||||
from datatypes.epc.surveys.pashub_rdsap_site_notes import PasHubRdSapSiteNotes
|
||||
|
||||
AnyRdSapSchema = Union[
|
||||
RdSapSchema17_0,
|
||||
|
|
@ -41,183 +23,9 @@ AnyRdSapSchema = Union[
|
|||
class DwellingMapper:
|
||||
|
||||
@staticmethod
|
||||
def from_site_notes(survey: PasHubRdSapSiteNotes) -> Dwelling:
|
||||
return Dwelling(
|
||||
property_details=_sn_property_details(survey),
|
||||
floor_dimensions=_sn_floor_dimensions(survey),
|
||||
walls=_sn_walls(survey),
|
||||
roof=_sn_roof(survey),
|
||||
floor=_sn_floor(survey),
|
||||
windows=[_sn_window(w) for w in survey.windows],
|
||||
main_heating=_sn_main_heating(survey),
|
||||
hot_water=_sn_hot_water(survey),
|
||||
ventilation=_sn_ventilation(survey),
|
||||
renewables=_sn_renewables(survey),
|
||||
lighting=_sn_lighting(survey),
|
||||
secondary_heating=_sn_secondary_heating(survey),
|
||||
number_of_habitable_rooms=survey.room_count_elements.number_of_habitable_rooms,
|
||||
number_of_external_doors=survey.room_count_elements.number_of_external_doors,
|
||||
number_of_open_chimneys=survey.room_count_elements.number_of_open_chimneys,
|
||||
number_of_blocked_chimneys=survey.room_count_elements.number_of_blocked_chimneys,
|
||||
has_conservatory=survey.conservatories.has_conservatory,
|
||||
number_of_baths=survey.water_use.number_of_baths,
|
||||
number_of_showers=len(survey.water_use.showers),
|
||||
waste_water_heat_recovery=survey.room_count_elements.waste_water_heat_recovery,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def from_rdsap_schema(_schema: AnyRdSapSchema) -> Dwelling:
|
||||
def from_site_notes(survey: PasHubRdSapSiteNotes) -> EpcPropertyData:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Site notes helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _sn_property_details(survey: PasHubRdSapSiteNotes) -> PropertyDetails:
|
||||
return PropertyDetails(
|
||||
property_type=survey.general.property_type,
|
||||
built_form=survey.general.detachment_type,
|
||||
tenure=survey.general.tenure,
|
||||
number_of_storeys=survey.general.number_of_storeys,
|
||||
construction_age_band=survey.building_construction.main_building.age_range,
|
||||
transaction_type=survey.general.transaction_type,
|
||||
terrain_type=survey.general.terrain_type,
|
||||
mains_gas_available=survey.general.mains_gas_available,
|
||||
electricity_smart_meter=survey.general.electricity_smart_meter,
|
||||
gas_smart_meter=survey.general.gas_smart_meter,
|
||||
)
|
||||
|
||||
|
||||
def _sn_floor_dimensions(survey: PasHubRdSapSiteNotes) -> List[FloorDimensions]:
|
||||
dims = [
|
||||
FloorDimensions(
|
||||
total_floor_area_m2=f.area_m2,
|
||||
height_m=f.height_m,
|
||||
heat_loss_perimeter_m=f.heat_loss_perimeter_m,
|
||||
party_wall_length_m=f.pwl_m,
|
||||
)
|
||||
for f in survey.building_measurements.main_building.floors
|
||||
]
|
||||
for ext in survey.building_measurements.extensions or []:
|
||||
dims.extend(
|
||||
FloorDimensions(
|
||||
total_floor_area_m2=f.area_m2,
|
||||
height_m=f.height_m,
|
||||
heat_loss_perimeter_m=f.heat_loss_perimeter_m,
|
||||
party_wall_length_m=f.pwl_m,
|
||||
)
|
||||
for f in ext.floors
|
||||
)
|
||||
return dims
|
||||
|
||||
|
||||
def _sn_walls(survey: PasHubRdSapSiteNotes) -> WallDetails:
|
||||
mb = survey.building_construction.main_building
|
||||
return WallDetails(
|
||||
construction_type=mb.walls_construction_type,
|
||||
insulation_type=mb.walls_insulation_type,
|
||||
thickness_mm=mb.wall_thickness_mm,
|
||||
party_wall_construction_type=mb.party_wall_construction_type,
|
||||
)
|
||||
|
||||
|
||||
def _sn_roof(survey: PasHubRdSapSiteNotes) -> RoofDetails:
|
||||
mb = survey.roof_space.main_building
|
||||
return RoofDetails(
|
||||
construction_type=mb.construction_type,
|
||||
insulation_at=mb.insulation_at,
|
||||
insulation_thickness_mm=mb.insulation_thickness_mm,
|
||||
has_rooms_in_roof=mb.rooms_in_roof,
|
||||
)
|
||||
|
||||
|
||||
def _sn_floor(survey: PasHubRdSapSiteNotes) -> FloorDetails:
|
||||
f = survey.building_construction.floor
|
||||
return FloorDetails(
|
||||
construction_type=f.floor_construction,
|
||||
insulation_type=f.floor_insulation_type,
|
||||
)
|
||||
|
||||
|
||||
def _sn_window(w: Window) -> WindowDetails:
|
||||
return WindowDetails(
|
||||
glazing_type=w.glazing_type,
|
||||
orientation=w.orientation,
|
||||
frame_type=w.frame_type,
|
||||
glazing_gap=w.glazing_gap,
|
||||
draught_proofed=w.draught_proofed,
|
||||
height_m=w.height_m,
|
||||
width_m=w.width_m,
|
||||
)
|
||||
|
||||
|
||||
def _sn_main_heating(survey: PasHubRdSapSiteNotes) -> MainHeatingSystem:
|
||||
mh = survey.heating_and_hot_water.main_heating
|
||||
return MainHeatingSystem(
|
||||
fuel=mh.fuel,
|
||||
system_type=mh.system_type,
|
||||
boiler_type=mh.type,
|
||||
manufacturer=mh.manufacturer,
|
||||
model=mh.model,
|
||||
condensing=mh.condensing,
|
||||
controls=mh.controls,
|
||||
flue_gas_heat_recovery=mh.flue_gas_heat_recovery_system,
|
||||
weather_compensator=mh.weather_compensator,
|
||||
emitter=mh.emitter,
|
||||
)
|
||||
|
||||
|
||||
def _sn_hot_water(survey: PasHubRdSapSiteNotes) -> HotWaterSystem:
|
||||
wh = survey.heating_and_hot_water.water_heating
|
||||
return HotWaterSystem(
|
||||
source=wh.system,
|
||||
cylinder_size=wh.cylinder_size,
|
||||
insulation_type=wh.insulation_type,
|
||||
insulation_thickness_mm=wh.insulation_thickness_mm,
|
||||
has_thermostat=wh.has_thermostat,
|
||||
)
|
||||
|
||||
|
||||
def _sn_secondary_heating(survey: PasHubRdSapSiteNotes) -> Optional[SecondaryHeatingSystem]:
|
||||
fuel = survey.heating_and_hot_water.secondary_heating.secondary_fuel
|
||||
if fuel == "No Secondary Heating":
|
||||
return None
|
||||
return SecondaryHeatingSystem(fuel=fuel)
|
||||
|
||||
|
||||
def _sn_ventilation(survey: PasHubRdSapSiteNotes) -> VentilationDetails:
|
||||
v = survey.ventilation
|
||||
return VentilationDetails(
|
||||
ventilation_type=v.ventilation_type,
|
||||
number_of_open_flues=v.number_of_open_flues,
|
||||
number_of_closed_flues=v.number_of_closed_flues,
|
||||
number_of_boiler_flues=v.number_of_boiler_flues,
|
||||
number_of_other_flues=v.number_of_other_flues,
|
||||
number_of_extract_fans=v.number_of_extract_fans,
|
||||
number_of_passive_vents=v.number_of_passive_vents,
|
||||
number_of_flueless_gas_fires=v.number_of_flueless_gas_fires,
|
||||
has_fixed_air_conditioning=v.has_fixed_air_conditioning,
|
||||
pressure_test=v.pressure_test,
|
||||
draught_lobby=v.draught_lobby,
|
||||
)
|
||||
|
||||
|
||||
def _sn_renewables(survey: PasHubRdSapSiteNotes) -> RenewablesDetails:
|
||||
r = survey.renewables
|
||||
return RenewablesDetails(
|
||||
has_photovoltaic=r.photovoltaic_array,
|
||||
has_solar_hot_water=r.solar_hot_water,
|
||||
has_wind_turbines=r.wind_turbines,
|
||||
has_hydro=r.hydro,
|
||||
number_of_pv_batteries=r.number_of_pv_batteries,
|
||||
)
|
||||
|
||||
|
||||
def _sn_lighting(survey: PasHubRdSapSiteNotes) -> LightingDetails:
|
||||
rc = survey.room_count_elements
|
||||
return LightingDetails(
|
||||
number_of_led_bulbs=rc.number_of_fixed_led_bulbs,
|
||||
number_of_cfl_bulbs=rc.number_of_fixed_cfl_bulbs,
|
||||
number_of_incandescent_bulbs=rc.number_of_fixed_incandescent_bulbs,
|
||||
)
|
||||
@staticmethod
|
||||
def from_rdsap_schema(_schema: AnyRdSapSchema) -> EpcPropertyData:
|
||||
raise NotImplementedError
|
||||
|
|
|
|||
|
|
@ -1,558 +0,0 @@
|
|||
import json
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
|
||||
import pytest
|
||||
|
||||
from datatypes.epc.domain import (
|
||||
Dwelling,
|
||||
FloorDimensions,
|
||||
FloorDetails,
|
||||
HotWaterSystem,
|
||||
LightingDetails,
|
||||
MainHeatingSystem,
|
||||
PropertyDetails,
|
||||
RenewablesDetails,
|
||||
RoofDetails,
|
||||
VentilationDetails,
|
||||
WallDetails,
|
||||
WindowDetails,
|
||||
)
|
||||
from datatypes.epc.domain.mapper import DwellingMapper
|
||||
from datatypes.epc.schema.tests.helpers import from_dict
|
||||
from datatypes.epc.surveys.pashub_rdsap_site_notes import PasHubRdSapSiteNotes
|
||||
|
||||
FIXTURES = os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"../../surveys/tests/fixtures",
|
||||
)
|
||||
|
||||
|
||||
def load(filename: str) -> Dict[str, Any]:
|
||||
with open(os.path.join(FIXTURES, filename)) as f:
|
||||
return json.load(f) # type: ignore[no-any-return]
|
||||
|
||||
|
||||
def survey(filename: str) -> PasHubRdSapSiteNotes:
|
||||
return from_dict(PasHubRdSapSiteNotes, load(filename))
|
||||
|
||||
|
||||
class TestFromExample1:
|
||||
"""No extensions; regular boiler with cylinder; natural ventilation."""
|
||||
|
||||
@pytest.fixture
|
||||
def dwelling(self) -> Dwelling:
|
||||
return DwellingMapper.from_site_notes(survey("pashub_rdsap_site_notes_example1.json"))
|
||||
|
||||
# --- property_details ---
|
||||
|
||||
def test_property_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.property_type == "House"
|
||||
|
||||
def test_built_form(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.built_form == "Mid-terrace"
|
||||
|
||||
def test_tenure(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.tenure == "Rented Social"
|
||||
|
||||
def test_number_of_storeys(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.number_of_storeys == 2
|
||||
|
||||
def test_construction_age_band(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.construction_age_band == "I: 1996 - 2002"
|
||||
|
||||
def test_transaction_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.transaction_type == "None of the Above"
|
||||
|
||||
def test_terrain_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.terrain_type == "Suburban"
|
||||
|
||||
def test_mains_gas_available(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.mains_gas_available is True
|
||||
|
||||
def test_electricity_smart_meter(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.electricity_smart_meter is True
|
||||
|
||||
def test_gas_smart_meter(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.property_details.gas_smart_meter is True
|
||||
|
||||
# --- floor_dimensions ---
|
||||
|
||||
def test_floor_count(self, dwelling: Dwelling) -> None:
|
||||
# 2 floors from main building, no extensions
|
||||
assert len(dwelling.floor_dimensions) == 2
|
||||
|
||||
def test_floor_area(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor_dimensions[0].total_floor_area_m2 == 24.78
|
||||
|
||||
def test_floor_height(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor_dimensions[0].height_m == 2.37
|
||||
|
||||
def test_heat_loss_perimeter(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor_dimensions[0].heat_loss_perimeter_m == 14.21
|
||||
|
||||
def test_party_wall_length(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor_dimensions[0].party_wall_length_m == 6.15
|
||||
|
||||
# --- walls ---
|
||||
|
||||
def test_wall_construction_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.construction_type == "Cavity"
|
||||
|
||||
def test_wall_insulation_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.insulation_type == "As built"
|
||||
|
||||
def test_wall_thickness(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.thickness_mm == 280
|
||||
|
||||
def test_party_wall_construction_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.party_wall_construction_type == "Cavity Masonry, Unfilled"
|
||||
|
||||
# --- roof ---
|
||||
|
||||
def test_roof_construction_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.roof.construction_type == "Pitched roof (Slates or tiles), Access to loft"
|
||||
|
||||
def test_roof_insulation_at(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.roof.insulation_at == "Joists"
|
||||
|
||||
def test_roof_insulation_thickness(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.roof.insulation_thickness_mm == 100
|
||||
|
||||
def test_roof_no_rooms_in_roof(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.roof.has_rooms_in_roof is False
|
||||
|
||||
# --- floor ---
|
||||
|
||||
def test_floor_construction_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor.construction_type == "Suspended, not timber"
|
||||
|
||||
def test_floor_insulation_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor.insulation_type == "As Built"
|
||||
|
||||
# --- windows ---
|
||||
|
||||
def test_window_count(self, dwelling: Dwelling) -> None:
|
||||
assert len(dwelling.windows) == 4
|
||||
|
||||
def test_window_glazing_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].glazing_type == "Double glazing, Unknown install date"
|
||||
|
||||
def test_window_orientation(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].orientation == "South East"
|
||||
|
||||
def test_window_frame_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].frame_type == "Wooden or PVC"
|
||||
|
||||
def test_window_glazing_gap(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].glazing_gap == "16 mm or more"
|
||||
|
||||
def test_window_draught_proofed(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].draught_proofed is True
|
||||
|
||||
def test_window_dimensions(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.windows[0].height_m == 1.36
|
||||
assert dwelling.windows[0].width_m == 1.0
|
||||
|
||||
# --- main_heating ---
|
||||
|
||||
def test_main_heating_fuel(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.fuel == "Mains gas"
|
||||
|
||||
def test_main_heating_system_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.system_type == "Boiler with radiators or underfloor heating"
|
||||
|
||||
def test_main_heating_boiler_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.boiler_type == "Regular"
|
||||
|
||||
def test_main_heating_manufacturer(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.manufacturer == "Vaillant"
|
||||
|
||||
def test_main_heating_model(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.model == "ecoFIT sustain 415"
|
||||
|
||||
def test_main_heating_condensing(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.condensing is True
|
||||
|
||||
def test_main_heating_controls(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.controls == "Programmer, room thermostat and TRVs"
|
||||
|
||||
def test_main_heating_fghr(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.flue_gas_heat_recovery is False
|
||||
|
||||
def test_main_heating_weather_compensator(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.weather_compensator is False
|
||||
|
||||
def test_main_heating_emitter(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.emitter == "Radiators"
|
||||
|
||||
# --- hot_water ---
|
||||
|
||||
def test_hot_water_source(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.source == "From main heating 1"
|
||||
|
||||
def test_hot_water_cylinder_size(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.cylinder_size == "Normal (90-130 litres)"
|
||||
|
||||
def test_hot_water_insulation_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.insulation_type == "Factory fitted"
|
||||
|
||||
def test_hot_water_insulation_thickness(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.insulation_thickness_mm == 12
|
||||
|
||||
def test_hot_water_thermostat(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.has_thermostat is True
|
||||
|
||||
# --- secondary_heating ---
|
||||
|
||||
def test_secondary_heating_absent(self, dwelling: Dwelling) -> None:
|
||||
# "No Secondary Heating" maps to None
|
||||
assert dwelling.secondary_heating is None
|
||||
|
||||
# --- ventilation ---
|
||||
|
||||
def test_ventilation_type(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.ventilation_type == "Natural"
|
||||
|
||||
def test_ventilation_extract_fans(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.number_of_extract_fans == 2
|
||||
|
||||
def test_ventilation_no_air_conditioning(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.has_fixed_air_conditioning is False
|
||||
|
||||
def test_ventilation_pressure_test(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.pressure_test == "No test"
|
||||
|
||||
def test_ventilation_draught_lobby(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.draught_lobby is False
|
||||
|
||||
# --- renewables ---
|
||||
|
||||
def test_no_photovoltaic(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.renewables.has_photovoltaic is False
|
||||
|
||||
def test_no_solar_hot_water(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.renewables.has_solar_hot_water is False
|
||||
|
||||
def test_no_wind_turbines(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.renewables.has_wind_turbines is False
|
||||
|
||||
def test_pv_batteries_count(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.renewables.number_of_pv_batteries == 0
|
||||
|
||||
# --- lighting ---
|
||||
|
||||
def test_led_bulbs(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.lighting.number_of_led_bulbs == 5
|
||||
|
||||
def test_cfl_bulbs(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.lighting.number_of_cfl_bulbs == 4
|
||||
|
||||
def test_incandescent_bulbs(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.lighting.number_of_incandescent_bulbs == 0
|
||||
|
||||
# --- dwelling-level counts ---
|
||||
|
||||
def test_habitable_rooms(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_habitable_rooms == 2
|
||||
|
||||
def test_external_doors(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_external_doors == 2
|
||||
|
||||
def test_open_chimneys(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_open_chimneys == 0
|
||||
|
||||
def test_blocked_chimneys(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_blocked_chimneys == 0
|
||||
|
||||
def test_no_conservatory(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.has_conservatory is False
|
||||
|
||||
def test_baths(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_baths == 1
|
||||
|
||||
def test_showers(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_showers == 1
|
||||
|
||||
def test_waste_water_heat_recovery(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.waste_water_heat_recovery == "None"
|
||||
|
||||
def test_full_mapping(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling == Dwelling(
|
||||
property_details=PropertyDetails(
|
||||
property_type="House",
|
||||
built_form="Mid-terrace",
|
||||
tenure="Rented Social",
|
||||
number_of_storeys=2,
|
||||
construction_age_band="I: 1996 - 2002",
|
||||
transaction_type="None of the Above",
|
||||
terrain_type="Suburban",
|
||||
mains_gas_available=True,
|
||||
electricity_smart_meter=True,
|
||||
gas_smart_meter=True,
|
||||
),
|
||||
floor_dimensions=[
|
||||
FloorDimensions(total_floor_area_m2=24.78, height_m=2.37, heat_loss_perimeter_m=14.21, party_wall_length_m=6.15),
|
||||
FloorDimensions(total_floor_area_m2=24.78, height_m=2.35, heat_loss_perimeter_m=14.21, party_wall_length_m=6.15),
|
||||
],
|
||||
walls=WallDetails(
|
||||
construction_type="Cavity",
|
||||
insulation_type="As built",
|
||||
thickness_mm=280,
|
||||
party_wall_construction_type="Cavity Masonry, Unfilled",
|
||||
),
|
||||
roof=RoofDetails(
|
||||
construction_type="Pitched roof (Slates or tiles), Access to loft",
|
||||
insulation_at="Joists",
|
||||
insulation_thickness_mm=100,
|
||||
has_rooms_in_roof=False,
|
||||
),
|
||||
floor=FloorDetails(
|
||||
construction_type="Suspended, not timber",
|
||||
insulation_type="As Built",
|
||||
),
|
||||
windows=[
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="South East", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.36, width_m=1.0),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="South East", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.33, width_m=0.96),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.04, width_m=0.96),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.02, width_m=0.97),
|
||||
],
|
||||
main_heating=MainHeatingSystem(
|
||||
fuel="Mains gas",
|
||||
system_type="Boiler with radiators or underfloor heating",
|
||||
boiler_type="Regular",
|
||||
manufacturer="Vaillant",
|
||||
model="ecoFIT sustain 415",
|
||||
condensing=True,
|
||||
controls="Programmer, room thermostat and TRVs",
|
||||
flue_gas_heat_recovery=False,
|
||||
weather_compensator=False,
|
||||
emitter="Radiators",
|
||||
),
|
||||
hot_water=HotWaterSystem(
|
||||
source="From main heating 1",
|
||||
cylinder_size="Normal (90-130 litres)",
|
||||
insulation_type="Factory fitted",
|
||||
insulation_thickness_mm=12,
|
||||
has_thermostat=True,
|
||||
),
|
||||
secondary_heating=None,
|
||||
ventilation=VentilationDetails(
|
||||
ventilation_type="Natural",
|
||||
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,
|
||||
has_fixed_air_conditioning=False,
|
||||
pressure_test="No test",
|
||||
draught_lobby=False,
|
||||
),
|
||||
renewables=RenewablesDetails(
|
||||
has_photovoltaic=False,
|
||||
has_solar_hot_water=False,
|
||||
has_wind_turbines=False,
|
||||
has_hydro=False,
|
||||
number_of_pv_batteries=0,
|
||||
),
|
||||
lighting=LightingDetails(
|
||||
number_of_led_bulbs=5,
|
||||
number_of_cfl_bulbs=4,
|
||||
number_of_incandescent_bulbs=0,
|
||||
),
|
||||
number_of_habitable_rooms=2,
|
||||
number_of_external_doors=2,
|
||||
number_of_open_chimneys=0,
|
||||
number_of_blocked_chimneys=0,
|
||||
has_conservatory=False,
|
||||
number_of_baths=1,
|
||||
number_of_showers=1,
|
||||
waste_water_heat_recovery="None",
|
||||
)
|
||||
|
||||
|
||||
class TestFromExample2:
|
||||
"""With extensions; combi boiler (no cylinder); mechanical extract ventilation."""
|
||||
|
||||
@pytest.fixture
|
||||
def dwelling(self) -> Dwelling:
|
||||
return DwellingMapper.from_site_notes(survey("pashub_rdsap_site_notes_example2.json"))
|
||||
|
||||
# --- floor_dimensions: main building + extension floors flattened ---
|
||||
|
||||
def test_floor_count_includes_extensions(self, dwelling: Dwelling) -> None:
|
||||
# 2 main building floors + 1 extension floor = 3
|
||||
assert len(dwelling.floor_dimensions) == 3
|
||||
|
||||
def test_extension_floor_area(self, dwelling: Dwelling) -> None:
|
||||
# Extension floor is last; area 3.8 m²
|
||||
assert dwelling.floor_dimensions[2].total_floor_area_m2 == 3.8
|
||||
|
||||
def test_extension_floor_party_wall_length(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.floor_dimensions[2].party_wall_length_m == 0.0
|
||||
|
||||
# --- walls: from main building ---
|
||||
|
||||
def test_wall_insulation_type_filled_cavity(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.insulation_type == "Filled Cavity"
|
||||
|
||||
def test_wall_thickness(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.walls.thickness_mm == 310
|
||||
|
||||
# --- roof: from main building ---
|
||||
|
||||
def test_roof_insulation_thickness(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.roof.insulation_thickness_mm == 100
|
||||
|
||||
# --- windows: all 8, location info discarded ---
|
||||
|
||||
def test_window_count(self, dwelling: Dwelling) -> None:
|
||||
assert len(dwelling.windows) == 8
|
||||
|
||||
# --- main_heating ---
|
||||
|
||||
def test_main_heating_boiler_type_combi(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.boiler_type == "Combi"
|
||||
|
||||
def test_main_heating_model(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.main_heating.model == "ecoTEC pro 28"
|
||||
|
||||
# --- hot_water: combi has no cylinder ---
|
||||
|
||||
def test_hot_water_source(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.source == "From main heating 1"
|
||||
|
||||
def test_hot_water_cylinder_size_no_cylinder(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.cylinder_size == "No Cylinder"
|
||||
|
||||
def test_hot_water_insulation_type_none(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.insulation_type is None
|
||||
|
||||
def test_hot_water_thermostat_none(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.hot_water.has_thermostat is None
|
||||
|
||||
# --- ventilation ---
|
||||
|
||||
def test_ventilation_type_mechanical(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.ventilation_type == "Mechanical Extract - Decentralised"
|
||||
|
||||
def test_ventilation_extract_fans_zero(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.ventilation.number_of_extract_fans == 0
|
||||
|
||||
# --- lighting ---
|
||||
|
||||
def test_incandescent_bulbs(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.lighting.number_of_incandescent_bulbs == 4
|
||||
|
||||
def test_led_bulbs_zero(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.lighting.number_of_led_bulbs == 0
|
||||
|
||||
# --- counts ---
|
||||
|
||||
def test_habitable_rooms(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_habitable_rooms == 3
|
||||
|
||||
def test_showers(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling.number_of_showers == 1
|
||||
|
||||
def test_full_mapping(self, dwelling: Dwelling) -> None:
|
||||
assert dwelling == Dwelling(
|
||||
property_details=PropertyDetails(
|
||||
property_type="House",
|
||||
built_form="Mid-terrace",
|
||||
tenure="Rented Social",
|
||||
number_of_storeys=2,
|
||||
construction_age_band="1950-1966",
|
||||
transaction_type="Grant-Scheme (ECO, RHI, etc.)",
|
||||
terrain_type="Suburban",
|
||||
mains_gas_available=True,
|
||||
electricity_smart_meter=True,
|
||||
gas_smart_meter=True,
|
||||
),
|
||||
floor_dimensions=[
|
||||
FloorDimensions(total_floor_area_m2=35.68, height_m=2.19, heat_loss_perimeter_m=13.44, party_wall_length_m=10.62),
|
||||
FloorDimensions(total_floor_area_m2=35.68, height_m=2.17, heat_loss_perimeter_m=11.0, party_wall_length_m=10.62),
|
||||
FloorDimensions(total_floor_area_m2=3.8, height_m=2.0, heat_loss_perimeter_m=5.7, party_wall_length_m=0.0),
|
||||
],
|
||||
walls=WallDetails(
|
||||
construction_type="Cavity",
|
||||
insulation_type="Filled Cavity",
|
||||
thickness_mm=310,
|
||||
party_wall_construction_type="Cavity Masonry, Filled",
|
||||
),
|
||||
roof=RoofDetails(
|
||||
construction_type="Pitched roof (Slates or tiles), Access to loft",
|
||||
insulation_at="Joists",
|
||||
insulation_thickness_mm=100,
|
||||
has_rooms_in_roof=False,
|
||||
),
|
||||
floor=FloorDetails(
|
||||
construction_type="Solid",
|
||||
insulation_type="As Built",
|
||||
),
|
||||
windows=[
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.2, width_m=2.3),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.2, width_m=1.0),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North East", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=0.9, width_m=1.0),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=0.9, width_m=1.0),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North East", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=0.9, width_m=1.7),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=0.9, width_m=2.3),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North West", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=1.0, width_m=1.2),
|
||||
WindowDetails(glazing_type="Double glazing, Unknown install date", orientation="North East", frame_type="Wooden or PVC", glazing_gap="16 mm or more", draught_proofed=True, height_m=0.9, width_m=1.0),
|
||||
],
|
||||
main_heating=MainHeatingSystem(
|
||||
fuel="Mains gas",
|
||||
system_type="Boiler with radiators or underfloor heating",
|
||||
boiler_type="Combi",
|
||||
manufacturer="Vaillant",
|
||||
model="ecoTEC pro 28",
|
||||
condensing=True,
|
||||
controls="Programmer, room thermostat and TRVs",
|
||||
flue_gas_heat_recovery=False,
|
||||
weather_compensator=False,
|
||||
emitter="Radiators",
|
||||
),
|
||||
hot_water=HotWaterSystem(
|
||||
source="From main heating 1",
|
||||
cylinder_size="No Cylinder",
|
||||
insulation_type=None,
|
||||
insulation_thickness_mm=None,
|
||||
has_thermostat=None,
|
||||
),
|
||||
secondary_heating=None,
|
||||
ventilation=VentilationDetails(
|
||||
ventilation_type="Mechanical Extract - Decentralised",
|
||||
number_of_open_flues=0,
|
||||
number_of_closed_flues=0,
|
||||
number_of_boiler_flues=0,
|
||||
number_of_other_flues=0,
|
||||
number_of_extract_fans=0,
|
||||
number_of_passive_vents=0,
|
||||
number_of_flueless_gas_fires=0,
|
||||
has_fixed_air_conditioning=False,
|
||||
pressure_test="No test",
|
||||
draught_lobby=False,
|
||||
),
|
||||
renewables=RenewablesDetails(
|
||||
has_photovoltaic=False,
|
||||
has_solar_hot_water=False,
|
||||
has_wind_turbines=False,
|
||||
has_hydro=False,
|
||||
number_of_pv_batteries=0,
|
||||
),
|
||||
lighting=LightingDetails(
|
||||
number_of_led_bulbs=0,
|
||||
number_of_cfl_bulbs=1,
|
||||
number_of_incandescent_bulbs=4,
|
||||
),
|
||||
number_of_habitable_rooms=3,
|
||||
number_of_external_doors=2,
|
||||
number_of_open_chimneys=0,
|
||||
number_of_blocked_chimneys=0,
|
||||
has_conservatory=False,
|
||||
number_of_baths=1,
|
||||
number_of_showers=1,
|
||||
waste_water_heat_recovery="None",
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue