from dataclasses import dataclass from datetime import date from typing import List, Optional, Union from domain.epc.epc import Epc @dataclass class EnergyElement: description: str energy_efficiency_rating: int environmental_efficiency_rating: int @dataclass class InstantaneousWwhrs: wwhrs_index_number1: Optional[int] = None wwhrs_index_number2: Optional[int] = None @dataclass class MainHeatingDetail: has_fghrs: bool main_fuel_type: Union[int, str] # int from API, str from site notes heat_emitter_type: Union[int, str] # int from API, str from site notes emitter_temperature: Union[int, str] main_heating_control: Union[int, str] # int from API, str from site notes fan_flue_present: Optional[bool] = None boiler_flue_type: Optional[int] = None # TODO: make enum? boiler_ignition_type: Optional[int] = None # TODO: make enum? central_heating_pump_age: Optional[int] = None central_heating_pump_age_str: Optional[str] = None # str from site notes e.g. "Unknown", "Pre 2013" main_heating_index_number: Optional[int] = None sap_main_heating_code: Optional[int] = None # TODO: make enum? main_heating_number: Optional[int] = None main_heating_category: Optional[int] = None main_heating_fraction: Optional[int] = None main_heating_data_source: Optional[int] = None condensing: Optional[bool] = None weather_compensator: Optional[bool] = None @dataclass class ShowerOutlet: shower_outlet_type: Union[int, str] shower_wwhrs: Optional[int] = None @dataclass class ShowerOutlets: # TODO: consolidate ShowerOutlet and ShowerOutlets shower_outlet: ShowerOutlet @dataclass class SapHeating: instantaneous_wwhrs: InstantaneousWwhrs main_heating_details: List[MainHeatingDetail] has_fixed_air_conditioning: bool cylinder_size: Optional[Union[int, str]] = ( None # int code from API; str (e.g. "Normal (90-130 litres)") from site notes ) water_heating_code: Optional[int] = None # TODO: make enum? water_heating_fuel: Optional[int] = None # TODO: make enum? immersion_heating_type: Optional[Union[int, str]] = None # TODO: make enum? shower_outlets: Optional[ShowerOutlets] = None cylinder_insulation_type: Optional[Union[int, str]] = None cylinder_thermostat: Optional[str] = None secondary_fuel_type: Optional[int] = None secondary_heating_type: Optional[Union[int, str]] = None # int from API; str from site notes cylinder_insulation_thickness_mm: Optional[int] = None @dataclass class SapVentilation: ventilation_type: Optional[str] = None draught_lobby: Optional[bool] = None pressure_test: Optional[str] = None # str from site notes e.g. "No test"; int in API via mechanical_ventilation open_flues_count: Optional[int] = None closed_flues_count: Optional[int] = None boiler_flues_count: Optional[int] = None other_flues_count: Optional[int] = None extract_fans_count: Optional[int] = None passive_vents_count: Optional[int] = None flueless_gas_fires_count: Optional[int] = None ventilation_in_pcdf_database: Optional[bool] = None @dataclass class WindowTransmissionDetails: u_value: float data_source: Union[int, str] solar_transmittance: float @dataclass class SapWindow: frame_material: Optional[str] glazing_gap: Union[int, str] orientation: Union[int, str] window_type: Union[int, str] glazing_type: Union[int, str] window_width: float window_height: float draught_proofed: Union[bool, str] # TODO: make enum/mapping? window_location: Union[int, str] # TODO: make enum/mapping window_wall_type: Union[int, str] # TODO: make enum/mapping permanent_shutters_present: Union[bool, str] # TODO: make enum/mapping frame_factor: Optional[float] = None window_transmission_details: Optional[WindowTransmissionDetails] = None permanent_shutters_insulated: Optional[str] = None @dataclass class PvBattery: battery_capacity: float @dataclass class PvBatteries: pv_battery: PvBattery @dataclass class WindTurbineDetails: hub_height: float rotor_diameter: float @dataclass class PhotovoltaicSupplyNoneOrNoDetails: percent_roof_area: int @dataclass class PhotovoltaicSupply: none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails @dataclass class SapEnergySource: mains_gas: bool meter_type: str # int in API, str (e.g. "Single") in site notes pv_battery_count: int wind_turbines_count: int gas_smart_meter_present: bool is_dwelling_export_capable: bool wind_turbines_terrain_type: str # int in API, str (e.g. "Suburban") in site notes electricity_smart_meter_present: bool pv_connection: Optional[Union[int, str]] = None # int from API; str from site notes photovoltaic_supply: Optional[PhotovoltaicSupply] = None wind_turbine_details: Optional[WindTurbineDetails] = None pv_batteries: Optional[PvBatteries] = None @dataclass class SapFloorDimension: room_height_m: float total_floor_area_m2: float party_wall_length_m: float heat_loss_perimeter_m: float floor: Optional[int] = None floor_insulation: Optional[int] = None floor_construction: Optional[int] = None @dataclass class SapRoomInRoof: floor_area: Union[int, float] construction_age_band: str @dataclass class SapAlternativeWall: wall_area: float wall_dry_lined: str wall_construction: int wall_insulation_type: int wall_thickness_measured: str wall_insulation_thickness: Optional[str] = None @dataclass class SapBuildingPart: # General identifier: str # e.g. "main", "roof" construction_age_band: str # Wall wall_construction: Union[ int, str ] # int from API, str from site notes TODO: make enum/mapping? wall_insulation_type: Union[ int, str ] # int from API, str from site notes TODO: make enum/mapping? wall_thickness_measured: bool party_wall_construction: Union[int, str] # TODO: make enum/mapping? # Floor sap_floor_dimensions: List[ SapFloorDimension ] # Not included in site notes; should this be optional? # Optional building_part_number: Optional[int] = ( None # Not sure how we get this from site notes ) wall_dry_lined: Optional[bool] = None # Don't think we have this in site notes wall_thickness_mm: Optional[int] = None wall_insulation_thickness: Optional[str] = None sap_alternative_wall_1: Optional[SapAlternativeWall] = None sap_alternative_wall_2: Optional[SapAlternativeWall] = None floor_heat_loss: Optional[int] = None floor_insulation_thickness: Optional[str] = None flat_roof_insulation_thickness: Optional[Union[str, int]] = ( None # TODO: make enum/mapping? ) floor_type: Optional[str] = None # str from site notes e.g. "Ground Floor" floor_construction_type: Optional[str] = None # str from site notes; distinct from floor_construction: int in SapFloorDimension floor_insulation_type_str: Optional[str] = None # str from site notes e.g. "As Built" floor_u_value_known: Optional[bool] = None roof_construction: Optional[int] = None roof_insulation_location: Optional[Union[int, str]] = ( None # TODO: make enum/mapping? ) roof_insulation_thickness: Optional[Union[str, int]] = ( None # TODO: make enum/mapping? ) sap_room_in_roof: Optional[SapRoomInRoof] = None @dataclass class WindowsTransmissionDetails: u_value: float data_source: int solar_transmittance: float @dataclass class SapFlatDetails: level: int top_storey: str flat_location: int heat_loss_corridor: int storey_count: Optional[int] = None unheated_corridor_length_m: Optional[int] = None @dataclass class EpcPropertyData: # General dwelling_type: str # TODO: make enum? inspection_date: date tenure: str # str in site notes; stringified int (e.g. "1") from API transaction_type: str # str in site notes; stringified int from API address_line_1: str postcode: str post_town: str # Elements roofs: List[EnergyElement] walls: List[EnergyElement] floors: List[EnergyElement] main_heating: List[EnergyElement] door_count: int sap_heating: SapHeating sap_windows: List[SapWindow] sap_energy_source: SapEnergySource sap_building_parts: List[SapBuildingPart] solar_water_heating: bool has_hot_water_cylinder: bool # must be inferred when mapping from site notes has_fixed_air_conditioning: bool # Counts wet_rooms_count: int # If this isn't provided, should it be 0 or None? extensions_count: int # If this isn't provided, should it be 0 or None? heated_rooms_count: int # If this isn't provided, should it be 0 or None? open_chimneys_count: int habitable_rooms_count: int insulated_door_count: ( int # Called "number_of_insulated_external_doors" in site notes; same thing? ) cfl_fixed_lighting_bulbs_count: int led_fixed_lighting_bulbs_count: int incandescent_fixed_lighting_bulbs_count: int # Measurements total_floor_area_m2: float # Optional fields assessment_type: Optional[str] = None # not available from site notes sap_version: Optional[float] = None # not available from site notes uprn: Optional[int] = None # not available from site notes status: Optional[str] = None # not available from site notes window: Optional[EnergyElement] = None # not available from site notes lighting: Optional[EnergyElement] = None # not available from site notes hot_water: Optional[EnergyElement] = None # not available from site notes schema_type: Optional[str] = None schema_versions_original: Optional[str] = None report_type: Optional[str] = None # TODO: make enum? report_reference: Optional[str] = None uprn_source: Optional[str] = None address_line_2: Optional[str] = None region_code: Optional[str] = None # TODO: make enum? country_code: Optional[str] = None built_form: Optional[str] = None # TODO: make enum? property_type: Optional[str] = None pressure_test: Optional[int] = None language_code: Optional[str] = None completion_date: Optional[date] = None registration_date: Optional[date] = None measurement_type: Optional[int] = None # What is this? conservatory_type: Optional[int] = ( None # What is this? site notes have "has_conservatory" flag ) has_conservatory: Optional[bool] = None # mapped directly from site notes has_heated_separate_conservatory: Optional[bool] = None secondary_heating: Optional[EnergyElement] = ( None # For site notes, secondary_fuel maps to sap_heating.secondary_fuel_type ) blocked_chimneys_count: Optional[int] = None energy_rating_average: Optional[int] = None main_heating_controls: Optional[EnergyElement] = ( None # site notes has heating_and_hot_water.main_heating.controls: str - doesn't map to EnergyElement ) current_energy_efficiency_band: Optional[Epc] = None # not available in site notes? environmental_impact_current: Optional[int] = None heating_cost_current: Optional[float] = None co2_emissions_current: Optional[float] = None energy_consumption_current: Optional[int] = None energy_rating_current: Optional[int] = None lighting_cost_current: Optional[float] = None hot_water_cost_current: Optional[float] = None insulated_door_u_value: Optional[float] = None # Not available in site notes mechanical_ventilation: Optional[int] = ( None # ventilation details present in site notes, but I'm not sure they correspond directly to the integers returned by the API here ) percent_draughtproofed: Optional[int] = ( None # Site notes have draught_proofed: bool field for each window, can we use that to infer percentage? ) heating_cost_potential: Optional[float] = None co2_emissions_potential: Optional[float] = None energy_consumption_potential: Optional[int] = None energy_rating_potential: Optional[float] = None lighting_cost_potential: Optional[float] = None hot_water_cost_potential: Optional[float] = None environmental_impact_potential: Optional[int] = None potential_energy_efficiency_band: Optional[Epc] = ( None # not available in site notes ) # renewable_heat_incentive: Optional[Any] = None # Not sure what this is, skip for now draughtproofed_door_count: Optional[int] = None mechanical_vent_duct_type: Optional[int] = None windows_transmission_details: Optional[WindowsTransmissionDetails] = None multiple_glazed_propertion: Optional[int] = None calculation_software_version: Optional[str] = None # Do we care about this? mechanical_vent_duct_placement: Optional[int] = None mechanical_vent_duct_insulation: Optional[int] = None pressure_test_certificate_number: Optional[int] = None mechanical_ventilation_index_number: Optional[int] = None mechanical_vent_measured_installation: Optional[str] = None co2_emissions_current_per_floor_area: Optional[int] = None low_energy_fixed_lighting_bulbs_count: Optional[int] = None sap_flat_details: Optional[SapFlatDetails] = None # survey_addendum: Optional[Any] = None # not sure how to handle, skip for now fixed_lighting_outlets_count: Optional[int] = None low_energy_fixed_lighting_outlets_count: Optional[int] = None # Site-notes-only fields sap_ventilation: Optional[SapVentilation] = None number_of_storeys: Optional[int] = None any_unheated_rooms: Optional[bool] = None waste_water_heat_recovery: Optional[str] = None hydro: Optional[bool] = None photovoltaic_array: Optional[bool] = None