mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
pashub rdsap sitenotes pdf output to dataclasses
This commit is contained in:
parent
6f8a304568
commit
a7d460a2d4
8 changed files with 1221 additions and 3 deletions
|
|
@ -42,8 +42,8 @@ logger = setup_logger()
|
|||
|
||||
def run_job() -> None:
|
||||
|
||||
username: str = "" # TODO: get from github secrets
|
||||
password: str = ""
|
||||
username: str = "joseph.westwood@domna.homes" # TODO: get from github secrets
|
||||
password: str = "DomnaTest123!"
|
||||
|
||||
property_list_file: str = (
|
||||
"hubspot-crm-exports-southern-ra-lite-programme-3103-2026-03-31-2.xlsx"
|
||||
|
|
|
|||
3
datatypes/epc/surveys/__init__.py
Normal file
3
datatypes/epc/surveys/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
from .pashub_rdsap_site_notes import PasHubRdSapSiteNotes
|
||||
|
||||
__all__ = ["PasHubRdSapSiteNotes"]
|
||||
291
datatypes/epc/surveys/pashub_rdsap_site_notes.py
Normal file
291
datatypes/epc/surveys/pashub_rdsap_site_notes.py
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class InspectionMetadata:
|
||||
inspection_surveyor: str
|
||||
email_address: str
|
||||
report_reference: str
|
||||
created_on: str
|
||||
date_of_inspection: str
|
||||
property_address: str
|
||||
property_photo: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class General:
|
||||
epc_checked_before_assessment: bool
|
||||
epc_exists_at_point_of_assessment: bool
|
||||
inspection_date: str
|
||||
transaction_type: str
|
||||
tenure: str
|
||||
property_type: str
|
||||
detachment_type: str
|
||||
number_of_storeys: int
|
||||
terrain_type: str
|
||||
number_of_extensions: int
|
||||
electricity_smart_meter: bool
|
||||
electric_meter_type: str
|
||||
dwelling_export_capable: bool
|
||||
mains_gas_available: bool
|
||||
gas_smart_meter: bool
|
||||
gas_meter_accessible: bool
|
||||
measurements_location: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainBuildingConstruction:
|
||||
age_range: str
|
||||
age_indicators: str
|
||||
walls_construction_type: str
|
||||
cavity_construction_indicators: str
|
||||
walls_insulation_type: str
|
||||
thermal_conductivity_of_wall_insulation: str
|
||||
wall_u_value_known: bool
|
||||
wall_thickness_mm: int
|
||||
party_wall_construction_type: str
|
||||
filled_cavity_indicators: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExtensionConstruction:
|
||||
id: int
|
||||
age_range: str
|
||||
age_indicators: str
|
||||
walls_construction_type: str
|
||||
cavity_construction_indicators: str
|
||||
walls_insulation_type: str
|
||||
thermal_conductivity_of_wall_insulation: str
|
||||
wall_u_value_known: bool
|
||||
wall_thickness_mm: int
|
||||
party_wall_construction_type: str
|
||||
filled_cavity_indicators: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class FloorConstruction:
|
||||
floor_type: str
|
||||
floor_construction: str
|
||||
floor_insulation_type: str
|
||||
floor_u_value_known: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class BuildingConstruction:
|
||||
main_building: MainBuildingConstruction
|
||||
floor: FloorConstruction
|
||||
extensions: Optional[List[ExtensionConstruction]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class FloorMeasurement:
|
||||
name: str
|
||||
area_m2: float
|
||||
height_m: float
|
||||
heat_loss_perimeter_m: float
|
||||
pwl_m: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainBuildingMeasurements:
|
||||
floors: List[FloorMeasurement]
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExtensionMeasurements:
|
||||
id: int
|
||||
floors: List[FloorMeasurement]
|
||||
|
||||
|
||||
@dataclass
|
||||
class BuildingMeasurements:
|
||||
main_building: MainBuildingMeasurements
|
||||
extensions: Optional[List[ExtensionMeasurements]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoofSpaceDetail:
|
||||
construction_type: str
|
||||
insulation_at: str
|
||||
roof_u_value_known: bool
|
||||
cavity_wall_construction_indicators: str
|
||||
rooms_in_roof: bool
|
||||
# Numeric thickness (mm) when known; string (e.g. "As built") when not measured
|
||||
insulation_thickness_mm: Optional[int] = None
|
||||
insulation_thickness: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ExtensionRoofSpace:
|
||||
id: int
|
||||
construction_type: str
|
||||
insulation_at: str
|
||||
roof_u_value_known: bool
|
||||
cavity_wall_construction_indicators: str
|
||||
rooms_in_roof: bool
|
||||
insulation_thickness_mm: Optional[int] = None
|
||||
insulation_thickness: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoofSpace:
|
||||
main_building: RoofSpaceDetail
|
||||
extensions: Optional[List[ExtensionRoofSpace]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Window:
|
||||
id: int
|
||||
location: str
|
||||
wall_type: str
|
||||
glazing_type: str
|
||||
window_type: str
|
||||
frame_type: str
|
||||
glazing_gap: str
|
||||
draught_proofed: bool
|
||||
permanent_shutters: bool
|
||||
height_m: float
|
||||
width_m: float
|
||||
orientation: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeating:
|
||||
selection_method: str
|
||||
system_type: str
|
||||
product_id: int
|
||||
manufacturer: str
|
||||
model: str
|
||||
orig_manufacturer: str
|
||||
fuel: str
|
||||
summer_efficiency: float
|
||||
type: str
|
||||
condensing: bool
|
||||
year: str
|
||||
mount: str
|
||||
open_flue: str
|
||||
fan_assist: bool
|
||||
status: str
|
||||
central_heating_pump_age: str
|
||||
controls: str
|
||||
flue_gas_heat_recovery_system: bool
|
||||
weather_compensator: bool
|
||||
emitter: str
|
||||
emitter_temperature: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SecondaryHeating:
|
||||
secondary_fuel: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class WaterHeating:
|
||||
type: str
|
||||
system: str
|
||||
cylinder_size: str
|
||||
cylinder_measured_heat_loss: Optional[str] = None
|
||||
insulation_type: Optional[str] = None
|
||||
insulation_thickness_mm: Optional[int] = None
|
||||
has_thermostat: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class HeatingAndHotWater:
|
||||
main_heating: MainHeating
|
||||
secondary_heating: SecondaryHeating
|
||||
water_heating: WaterHeating
|
||||
|
||||
|
||||
@dataclass
|
||||
class Ventilation:
|
||||
ventilation_type: str
|
||||
has_fixed_air_conditioning: bool
|
||||
number_of_open_flues: int
|
||||
number_of_closed_flues: int
|
||||
number_of_boiler_flues: int
|
||||
number_of_other_flues: int
|
||||
number_of_extract_fans: int
|
||||
number_of_passive_vents: int
|
||||
number_of_flueless_gas_fires: int
|
||||
pressure_test: str
|
||||
draught_lobby: bool
|
||||
ventilation_in_pcdf_database: Optional[bool] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Conservatories:
|
||||
has_conservatory: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class Renewables:
|
||||
wind_turbines: bool
|
||||
solar_hot_water: bool
|
||||
photovoltaic_array: bool
|
||||
number_of_pv_batteries: int
|
||||
hydro: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class RoomCountElements:
|
||||
number_of_habitable_rooms: int
|
||||
any_unheated_rooms: bool
|
||||
number_of_external_doors: int
|
||||
number_of_insulated_external_doors: int
|
||||
number_of_draughtproofed_external_doors: int
|
||||
number_of_open_chimneys: int
|
||||
number_of_blocked_chimneys: int
|
||||
number_of_fixed_incandescent_bulbs: int
|
||||
exact_led_cfl_count_known: bool
|
||||
number_of_fixed_led_bulbs: int
|
||||
number_of_fixed_cfl_bulbs: int
|
||||
waste_water_heat_recovery: str
|
||||
number_of_heated_rooms: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class Shower:
|
||||
id: int
|
||||
outlet_type: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class WaterUse:
|
||||
number_of_baths: int
|
||||
number_of_special_features: int
|
||||
showers: List[Shower]
|
||||
|
||||
|
||||
@dataclass
|
||||
class CustomerResponse:
|
||||
customer_present: bool
|
||||
willing_to_answer_satisfaction_survey: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class SurveyAddendum:
|
||||
addendum: str
|
||||
related_party_disclosure: str
|
||||
hard_to_treat_cavity_access_issues: bool
|
||||
hard_to_treat_cavity_high_exposure: bool
|
||||
hard_to_treat_cavity_narrow_cavities: bool
|
||||
|
||||
|
||||
@dataclass
|
||||
class PasHubRdSapSiteNotes:
|
||||
inspection_metadata: InspectionMetadata
|
||||
general: General
|
||||
building_construction: BuildingConstruction
|
||||
building_measurements: BuildingMeasurements
|
||||
roof_space: RoofSpace
|
||||
windows: List[Window]
|
||||
heating_and_hot_water: HeatingAndHotWater
|
||||
ventilation: Ventilation
|
||||
conservatories: Conservatories
|
||||
renewables: Renewables
|
||||
room_count_elements: RoomCountElements
|
||||
water_use: WaterUse
|
||||
customer_response: CustomerResponse
|
||||
addendum: SurveyAddendum
|
||||
0
datatypes/epc/surveys/tests/__init__.py
Normal file
0
datatypes/epc/surveys/tests/__init__.py
Normal file
232
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example1.json
vendored
Normal file
232
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example1.json
vendored
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
{
|
||||
"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": "test"
|
||||
},
|
||||
"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": 280,
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"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.33,
|
||||
"width_m": 0.96,
|
||||
"orientation": "South East"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"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.04,
|
||||
"width_m": 0.96,
|
||||
"orientation": "North West"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"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.02,
|
||||
"width_m": 0.97,
|
||||
"orientation": "North West"
|
||||
}
|
||||
],
|
||||
"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": "PV Recommended",
|
||||
"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
|
||||
}
|
||||
}
|
||||
330
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example2.json
vendored
Normal file
330
datatypes/epc/surveys/tests/fixtures/pashub_rdsap_site_notes_example2.json
vendored
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
{
|
||||
"inspection_metadata": {
|
||||
"inspection_surveyor": "test",
|
||||
"email_address": "test@test.com",
|
||||
"report_reference": "6EA2A86D-94CE-4792-8D49-AB495C744EDD",
|
||||
"created_on": "2025-11-10",
|
||||
"date_of_inspection": "2025-09-25",
|
||||
"property_address": "test",
|
||||
"property_photo": true
|
||||
},
|
||||
"general": {
|
||||
"epc_checked_before_assessment": true,
|
||||
"epc_exists_at_point_of_assessment": false,
|
||||
"inspection_date": "2025-09-25",
|
||||
"transaction_type": "Grant-Scheme (ECO, RHI, etc.)",
|
||||
"tenure": "Rented Social",
|
||||
"property_type": "House",
|
||||
"detachment_type": "Mid-terrace",
|
||||
"number_of_storeys": 2,
|
||||
"terrain_type": "Suburban",
|
||||
"number_of_extensions": 1,
|
||||
"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": "1950-1966",
|
||||
"age_indicators": "local knowledge, enquiries of owner",
|
||||
"walls_construction_type": "Cavity",
|
||||
"cavity_construction_indicators": "wall thickness over 270 mm",
|
||||
"walls_insulation_type": "Filled Cavity",
|
||||
"filled_cavity_indicators": "evidence of cavity fill drill holes",
|
||||
"thermal_conductivity_of_wall_insulation": "Unknown",
|
||||
"wall_u_value_known": false,
|
||||
"wall_thickness_mm": 310,
|
||||
"party_wall_construction_type": "Cavity Masonry, Filled"
|
||||
},
|
||||
"extensions": [
|
||||
{
|
||||
"id": 1,
|
||||
"age_range": "2003-2006",
|
||||
"age_indicators": "local knowledge, enquiries of owner",
|
||||
"walls_construction_type": "Cavity",
|
||||
"cavity_construction_indicators": "wall thickness over 270 mm",
|
||||
"walls_insulation_type": "As built",
|
||||
"thermal_conductivity_of_wall_insulation": "Unknown",
|
||||
"wall_u_value_known": false,
|
||||
"wall_thickness_mm": 310,
|
||||
"party_wall_construction_type": "Cavity Masonry, Filled"
|
||||
}
|
||||
],
|
||||
"floor": {
|
||||
"floor_type": "Ground Floor",
|
||||
"floor_construction": "Solid",
|
||||
"floor_insulation_type": "As Built",
|
||||
"floor_u_value_known": false
|
||||
}
|
||||
},
|
||||
"building_measurements": {
|
||||
"main_building": {
|
||||
"floors": [
|
||||
{
|
||||
"name": "Floor 1",
|
||||
"area_m2": 35.68,
|
||||
"height_m": 2.19,
|
||||
"heat_loss_perimeter_m": 13.44,
|
||||
"pwl_m": 10.62
|
||||
},
|
||||
{
|
||||
"name": "Floor 0",
|
||||
"area_m2": 35.68,
|
||||
"height_m": 2.17,
|
||||
"heat_loss_perimeter_m": 11.0,
|
||||
"pwl_m": 10.62
|
||||
}
|
||||
]
|
||||
},
|
||||
"extensions": [
|
||||
{
|
||||
"id": 1,
|
||||
"floors": [
|
||||
{
|
||||
"name": "Floor 0",
|
||||
"area_m2": 3.8,
|
||||
"height_m": 2.0,
|
||||
"heat_loss_perimeter_m": 5.7,
|
||||
"pwl_m": 0.0
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"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": "cavity visible in roof space",
|
||||
"rooms_in_roof": false
|
||||
},
|
||||
"extensions": [
|
||||
{
|
||||
"id": 1,
|
||||
"construction_type": "Pitched roof, Sloping ceiling",
|
||||
"insulation_at": "Sloping ceiling insulation",
|
||||
"roof_u_value_known": false,
|
||||
"insulation_thickness": "As built",
|
||||
"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.2,
|
||||
"width_m": 2.3,
|
||||
"orientation": "North West"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"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.2,
|
||||
"width_m": 1.0,
|
||||
"orientation": "North West"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"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": 0.9,
|
||||
"width_m": 1.0,
|
||||
"orientation": "North East"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"location": "Extension 1",
|
||||
"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": 0.9,
|
||||
"width_m": 1.0,
|
||||
"orientation": "North"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"location": "Extension 1",
|
||||
"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": 0.9,
|
||||
"width_m": 1.7,
|
||||
"orientation": "North East"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"location": "Extension 1",
|
||||
"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": 0.9,
|
||||
"width_m": 2.3,
|
||||
"orientation": "North West"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"location": "Extension 1",
|
||||
"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.0,
|
||||
"width_m": 1.2,
|
||||
"orientation": "North West"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"location": "Extension 1",
|
||||
"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": 0.9,
|
||||
"width_m": 1.0,
|
||||
"orientation": "North East"
|
||||
}
|
||||
],
|
||||
"heating_and_hot_water": {
|
||||
"main_heating": {
|
||||
"selection_method": "PCDF Search",
|
||||
"system_type": "Boiler with radiators or underfloor heating",
|
||||
"product_id": 16839,
|
||||
"manufacturer": "Vaillant",
|
||||
"model": "ecoTEC pro 28",
|
||||
"orig_manufacturer": "Vaillant",
|
||||
"fuel": "Mains gas",
|
||||
"summer_efficiency": 0,
|
||||
"type": "Combi",
|
||||
"condensing": true,
|
||||
"year": "2005 - 2015",
|
||||
"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": "No Cylinder",
|
||||
"cylinder_measured_heat_loss": null,
|
||||
"insulation_type": null,
|
||||
"insulation_thickness_mm": null,
|
||||
"has_thermostat": null
|
||||
}
|
||||
},
|
||||
"ventilation": {
|
||||
"ventilation_type": "Mechanical Extract - Decentralised",
|
||||
"ventilation_in_pcdf_database": false,
|
||||
"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": 0,
|
||||
"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": 3,
|
||||
"any_unheated_rooms": false,
|
||||
"number_of_heated_rooms": null,
|
||||
"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": 4,
|
||||
"exact_led_cfl_count_known": true,
|
||||
"number_of_fixed_led_bulbs": 0,
|
||||
"number_of_fixed_cfl_bulbs": 1,
|
||||
"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
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,362 @@
|
|||
import json
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
|
||||
import pytest
|
||||
|
||||
from datatypes.epc.schema.tests.helpers import from_dict
|
||||
from datatypes.epc.surveys.pashub_rdsap_site_notes import (
|
||||
ExtensionConstruction,
|
||||
ExtensionMeasurements,
|
||||
ExtensionRoofSpace,
|
||||
PasHubRdSapSiteNotes,
|
||||
)
|
||||
|
||||
FIXTURES = os.path.join(os.path.dirname(__file__), "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]
|
||||
|
||||
|
||||
class TestExample1:
|
||||
"""No extensions; regular boiler with hot water cylinder; natural ventilation."""
|
||||
|
||||
@pytest.fixture
|
||||
def survey(self) -> PasHubRdSapSiteNotes:
|
||||
return from_dict(PasHubRdSapSiteNotes, load("example1.json"))
|
||||
|
||||
# --- inspection_metadata ---
|
||||
|
||||
def test_report_reference(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert (
|
||||
survey.inspection_metadata.report_reference
|
||||
== "49D422A9-0779-44DD-9665-464D35DFF1A8"
|
||||
)
|
||||
|
||||
def test_created_on(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.inspection_metadata.created_on == "2026-03-31"
|
||||
|
||||
def test_property_photo_absent(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.inspection_metadata.property_photo is None
|
||||
|
||||
# --- general ---
|
||||
|
||||
def test_transaction_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.general.transaction_type == "None of the Above"
|
||||
|
||||
def test_number_of_extensions(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.general.number_of_extensions == 0
|
||||
|
||||
def test_smart_meters(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.general.electricity_smart_meter is True
|
||||
assert survey.general.gas_smart_meter is True
|
||||
|
||||
# --- building_construction ---
|
||||
|
||||
def test_main_building_wall_thickness(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_construction.main_building.wall_thickness_mm == 280
|
||||
|
||||
def test_main_building_walls_insulation_type(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert (
|
||||
survey.building_construction.main_building.walls_insulation_type
|
||||
== "As built"
|
||||
)
|
||||
|
||||
def test_filled_cavity_indicators_absent(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert (
|
||||
survey.building_construction.main_building.filled_cavity_indicators is None
|
||||
)
|
||||
|
||||
def test_no_extensions_in_construction(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_construction.extensions is None
|
||||
|
||||
def test_floor_construction(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert (
|
||||
survey.building_construction.floor.floor_construction
|
||||
== "Suspended, not timber"
|
||||
)
|
||||
|
||||
# --- building_measurements ---
|
||||
|
||||
def test_main_building_floor_count(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert len(survey.building_measurements.main_building.floors) == 2
|
||||
|
||||
def test_floor_area(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_measurements.main_building.floors[0].area_m2 == 24.78
|
||||
|
||||
def test_no_extension_measurements(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_measurements.extensions is None
|
||||
|
||||
# --- roof_space ---
|
||||
|
||||
def test_roof_insulation_thickness_mm(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.roof_space.main_building.insulation_thickness_mm == 100
|
||||
|
||||
def test_roof_insulation_thickness_string_absent(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.roof_space.main_building.insulation_thickness is None
|
||||
|
||||
def test_no_extension_roof_spaces(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.roof_space.extensions is None
|
||||
|
||||
def test_rooms_in_roof_false(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.roof_space.main_building.rooms_in_roof is False
|
||||
|
||||
# --- windows ---
|
||||
|
||||
def test_window_count(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert len(survey.windows) == 4
|
||||
|
||||
def test_window_dimensions(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
w = survey.windows[0]
|
||||
assert w.height_m == 1.36
|
||||
assert w.width_m == 1.0
|
||||
|
||||
def test_window_orientation(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.windows[0].orientation == "South East"
|
||||
assert survey.windows[2].orientation == "North West"
|
||||
|
||||
def test_window_glazing_gap(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.windows[0].glazing_gap == "16 mm or more"
|
||||
|
||||
# --- heating_and_hot_water ---
|
||||
|
||||
def test_main_heating_manufacturer(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.manufacturer == "Vaillant"
|
||||
|
||||
def test_main_heating_model(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.model == "ecoFIT sustain 415"
|
||||
|
||||
def test_main_heating_product_id(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.product_id == 18400
|
||||
|
||||
def test_main_heating_type_regular(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.type == "Regular"
|
||||
|
||||
def test_water_heating_cylinder_present(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
wh = survey.heating_and_hot_water.water_heating
|
||||
assert wh.cylinder_size == "Normal (90-130 litres)"
|
||||
assert wh.insulation_type == "Factory fitted"
|
||||
assert wh.insulation_thickness_mm == 12
|
||||
assert wh.has_thermostat is True
|
||||
|
||||
def test_secondary_heating_none(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert (
|
||||
survey.heating_and_hot_water.secondary_heating.secondary_fuel
|
||||
== "No Secondary Heating"
|
||||
)
|
||||
|
||||
# --- ventilation ---
|
||||
|
||||
def test_ventilation_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.ventilation.ventilation_type == "Natural"
|
||||
|
||||
def test_ventilation_pcdf_absent(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.ventilation.ventilation_in_pcdf_database is None
|
||||
|
||||
def test_extract_fans(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.ventilation.number_of_extract_fans == 2
|
||||
|
||||
# --- room_count_elements ---
|
||||
|
||||
def test_habitable_rooms(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_habitable_rooms == 2
|
||||
|
||||
def test_heated_rooms_zero(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_heated_rooms == 0
|
||||
|
||||
def test_led_bulbs(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_fixed_led_bulbs == 5
|
||||
|
||||
def test_cfl_bulbs(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_fixed_cfl_bulbs == 4
|
||||
|
||||
# --- water_use ---
|
||||
|
||||
def test_shower_outlet_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert len(survey.water_use.showers) == 1
|
||||
assert survey.water_use.showers[0].outlet_type == "Non-Electric Shower"
|
||||
|
||||
# --- addendum ---
|
||||
|
||||
def test_addendum_value(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.addendum.addendum == "PV Recommended"
|
||||
|
||||
def test_related_party_disclosure(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.addendum.related_party_disclosure == "No related party"
|
||||
|
||||
def test_hard_to_treat_flags_false(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.addendum.hard_to_treat_cavity_access_issues is False
|
||||
assert survey.addendum.hard_to_treat_cavity_high_exposure is False
|
||||
assert survey.addendum.hard_to_treat_cavity_narrow_cavities is False
|
||||
|
||||
|
||||
class TestExample2:
|
||||
"""With extensions; combi boiler (no cylinder); mechanical extract ventilation."""
|
||||
|
||||
@pytest.fixture
|
||||
def survey(self) -> PasHubRdSapSiteNotes:
|
||||
return from_dict(PasHubRdSapSiteNotes, load("example2.json"))
|
||||
|
||||
# --- inspection_metadata ---
|
||||
|
||||
def test_report_reference(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert (
|
||||
survey.inspection_metadata.report_reference
|
||||
== "6EA2A86D-94CE-4792-8D49-AB495C744EDD"
|
||||
)
|
||||
|
||||
def test_property_photo_present(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.inspection_metadata.property_photo is True
|
||||
|
||||
def test_created_on_differs_from_inspection_date(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.inspection_metadata.created_on == "2025-11-10"
|
||||
assert survey.inspection_metadata.date_of_inspection == "2025-09-25"
|
||||
|
||||
# --- general ---
|
||||
|
||||
def test_number_of_extensions(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.general.number_of_extensions == 1
|
||||
|
||||
def test_transaction_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.general.transaction_type == "Grant-Scheme (ECO, RHI, etc.)"
|
||||
|
||||
# --- building_construction ---
|
||||
|
||||
def test_main_building_filled_cavity_indicators(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert (
|
||||
survey.building_construction.main_building.filled_cavity_indicators
|
||||
== "evidence of cavity fill drill holes"
|
||||
)
|
||||
|
||||
def test_extension_construction_present(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_construction.extensions is not None
|
||||
assert len(survey.building_construction.extensions) == 1
|
||||
|
||||
def test_extension_construction_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_construction.extensions is not None
|
||||
ext: ExtensionConstruction = survey.building_construction.extensions[0]
|
||||
assert ext.id == 1
|
||||
assert ext.walls_insulation_type == "As built"
|
||||
assert ext.wall_thickness_mm == 310
|
||||
|
||||
def test_extension_no_filled_cavity_indicators(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.building_construction.extensions is not None
|
||||
assert (
|
||||
survey.building_construction.extensions[0].filled_cavity_indicators is None
|
||||
)
|
||||
|
||||
# --- building_measurements ---
|
||||
|
||||
def test_main_building_floor_count(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert len(survey.building_measurements.main_building.floors) == 2
|
||||
|
||||
def test_extension_measurements_present(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_measurements.extensions is not None
|
||||
assert len(survey.building_measurements.extensions) == 1
|
||||
|
||||
def test_extension_floor_area(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.building_measurements.extensions is not None
|
||||
ext: ExtensionMeasurements = survey.building_measurements.extensions[0]
|
||||
assert ext.id == 1
|
||||
assert len(ext.floors) == 1
|
||||
assert ext.floors[0].area_m2 == 3.8
|
||||
|
||||
# --- roof_space ---
|
||||
|
||||
def test_main_roof_insulation_thickness_mm(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.roof_space.main_building.insulation_thickness_mm == 100
|
||||
|
||||
def test_extension_roof_spaces_present(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.roof_space.extensions is not None
|
||||
assert len(survey.roof_space.extensions) == 1
|
||||
|
||||
def test_extension_roof_uses_string_thickness(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.roof_space.extensions is not None
|
||||
ext: ExtensionRoofSpace = survey.roof_space.extensions[0]
|
||||
assert ext.insulation_thickness == "As built"
|
||||
assert ext.insulation_thickness_mm is None
|
||||
|
||||
def test_extension_roof_construction_type(
|
||||
self, survey: PasHubRdSapSiteNotes
|
||||
) -> None:
|
||||
assert survey.roof_space.extensions is not None
|
||||
assert (
|
||||
survey.roof_space.extensions[0].construction_type
|
||||
== "Pitched roof, Sloping ceiling"
|
||||
)
|
||||
|
||||
# --- windows ---
|
||||
|
||||
def test_window_count(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert len(survey.windows) == 8
|
||||
|
||||
def test_extension_windows(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
extension_windows = [w for w in survey.windows if w.location == "Extension 1"]
|
||||
assert len(extension_windows) == 5
|
||||
|
||||
def test_window_ids_sequential(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
ids = [w.id for w in survey.windows]
|
||||
assert ids == list(range(1, 9))
|
||||
|
||||
# --- heating_and_hot_water ---
|
||||
|
||||
def test_main_heating_type_combi(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.type == "Combi"
|
||||
|
||||
def test_main_heating_model(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.heating_and_hot_water.main_heating.model == "ecoTEC pro 28"
|
||||
|
||||
def test_water_heating_no_cylinder(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
wh = survey.heating_and_hot_water.water_heating
|
||||
assert wh.cylinder_size == "No Cylinder"
|
||||
assert wh.cylinder_measured_heat_loss is None
|
||||
assert wh.insulation_type is None
|
||||
assert wh.insulation_thickness_mm is None
|
||||
assert wh.has_thermostat is None
|
||||
|
||||
# --- ventilation ---
|
||||
|
||||
def test_ventilation_type(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert (
|
||||
survey.ventilation.ventilation_type == "Mechanical Extract - Decentralised"
|
||||
)
|
||||
|
||||
def test_ventilation_in_pcdf_database(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.ventilation.ventilation_in_pcdf_database is False
|
||||
|
||||
def test_no_extract_fans_for_mev(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.ventilation.number_of_extract_fans == 0
|
||||
|
||||
# --- room_count_elements ---
|
||||
|
||||
def test_habitable_rooms(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_habitable_rooms == 3
|
||||
|
||||
def test_heated_rooms_null(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_heated_rooms is None
|
||||
|
||||
def test_incandescent_bulbs(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.room_count_elements.number_of_fixed_incandescent_bulbs == 4
|
||||
|
||||
# --- addendum ---
|
||||
|
||||
def test_addendum_none(self, survey: PasHubRdSapSiteNotes) -> None:
|
||||
assert survey.addendum.addendum == "None"
|
||||
|
|
@ -3,6 +3,6 @@ pythonpath = .
|
|||
log_cli = true
|
||||
log_cli_level = INFO
|
||||
addopts = --cov-report term-missing --cov=etl/epc --cov=recommendations --cov=backend --cov=etl/epc_clean --cov=etl/spatial
|
||||
testpaths = recommendations/tests backend/tests etl/epc/tests etl/epc_clean/tests etl/spatial/tests backend/condition/tests backend/address2UPRN/tests backend/onboarders/tests backend/categorisation/tests backend/export/tests etl/hubspot/tests backend/hubspot_trigger_orchestrator/tests datatypes/epc/schema/tests
|
||||
testpaths = recommendations/tests backend/tests etl/epc/tests etl/epc_clean/tests etl/spatial/tests backend/condition/tests backend/address2UPRN/tests backend/onboarders/tests backend/categorisation/tests backend/export/tests etl/hubspot/tests backend/hubspot_trigger_orchestrator/tests datatypes/epc/schema/tests datatypes/epc/surveys/tests
|
||||
markers =
|
||||
integration: mark a test as an integration test
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue