mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Merge branch 'main' of github.com:Hestia-Homes/Model
This commit is contained in:
commit
680edb5c38
21 changed files with 4073 additions and 34 deletions
|
|
@ -113,12 +113,17 @@ def task_handler():
|
|||
|
||||
@wraps(func)
|
||||
def wrapper(event: dict[str, Any], context: Any, *args, **kwargs):
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
# Parse body: Records-style SQS or plain dict event
|
||||
if "Records" in event:
|
||||
raw_body = event["Records"][0].get("body", {})
|
||||
records = event.get("Records", [event]) # fallback for non-SQS
|
||||
|
||||
results = []
|
||||
failures = []
|
||||
|
||||
for record in records:
|
||||
# Parse body
|
||||
raw_body = record.get("body", record)
|
||||
|
||||
if isinstance(raw_body, str):
|
||||
try:
|
||||
body = json.loads(raw_body)
|
||||
|
|
@ -126,43 +131,55 @@ def task_handler():
|
|||
body = {}
|
||||
else:
|
||||
body = raw_body or {}
|
||||
else:
|
||||
body = event
|
||||
|
||||
# Create fresh task + subtask
|
||||
logger.info("Creating task for source: %s", task_source)
|
||||
task_id, subtask_id = TasksInterface.create_task(
|
||||
task_source=task_source,
|
||||
inputs=body,
|
||||
)
|
||||
logger.info("Created task_id=%s subtask_id=%s", task_id, subtask_id)
|
||||
# Create task per message
|
||||
logger.info("Creating task for source: %s", task_source)
|
||||
task_id, subtask_id = TasksInterface.create_task(
|
||||
task_source=task_source,
|
||||
inputs=body,
|
||||
)
|
||||
|
||||
interface = SubTaskInterface()
|
||||
logger.info("Created task_id=%s subtask_id=%s", task_id, subtask_id)
|
||||
|
||||
interface.update_subtask_status(
|
||||
subtask_id=subtask_id,
|
||||
status="in progress",
|
||||
)
|
||||
|
||||
try:
|
||||
result = func(body, context, *args, **kwargs)
|
||||
interface = SubTaskInterface()
|
||||
|
||||
interface.update_subtask_status(
|
||||
subtask_id=subtask_id,
|
||||
status="complete",
|
||||
outputs={"result": result} if result else None,
|
||||
status="in progress",
|
||||
)
|
||||
logger.info("Task %s completed successfully", task_id)
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Task %s failed: %s", task_id, e)
|
||||
interface.update_subtask_status(
|
||||
subtask_id=subtask_id,
|
||||
status="failed",
|
||||
outputs={"error": str(e)},
|
||||
)
|
||||
raise
|
||||
try:
|
||||
result = func(body, context, *args, **kwargs)
|
||||
|
||||
interface.update_subtask_status(
|
||||
subtask_id=subtask_id,
|
||||
status="complete",
|
||||
outputs={"result": result} if result else None,
|
||||
)
|
||||
|
||||
logger.info("Task %s completed successfully", task_id)
|
||||
results.append(result)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("Task %s failed: %s", task_id, e)
|
||||
|
||||
interface.update_subtask_status(
|
||||
subtask_id=subtask_id,
|
||||
status="failed",
|
||||
outputs={"error": str(e)},
|
||||
)
|
||||
|
||||
if "Records" in event:
|
||||
failures.append({"itemIdentifier": record["messageId"]})
|
||||
else:
|
||||
# Handle non-SQS events
|
||||
raise
|
||||
|
||||
if "Records" in event:
|
||||
return {"batchItemFailures": failures}
|
||||
|
||||
# Handle non-SQS events
|
||||
return results
|
||||
|
||||
return wrapper
|
||||
|
||||
|
|
|
|||
17
datatypes/epc/schema/__init__.py
Normal file
17
datatypes/epc/schema/__init__.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from .rdsap_schema_17_0 import RdSapSchema17_0
|
||||
from .rdsap_schema_17_1 import RdSapSchema17_1
|
||||
from .rdsap_schema_18_0 import RdSapSchema18_0
|
||||
from .rdsap_schema_19_0 import RdSapSchema19_0
|
||||
from .rdsap_schema_20_0_0 import RdSapSchema20_0_0
|
||||
from .rdsap_schema_21_0_0 import RdSapSchema21_0_0
|
||||
from .rdsap_schema_21_0_1 import RdSapSchema21_0_1
|
||||
|
||||
__all__ = [
|
||||
"RdSapSchema17_0",
|
||||
"RdSapSchema17_1",
|
||||
"RdSapSchema18_0",
|
||||
"RdSapSchema19_0",
|
||||
"RdSapSchema20_0_0",
|
||||
"RdSapSchema21_0_0",
|
||||
"RdSapSchema21_0_1",
|
||||
]
|
||||
22
datatypes/epc/schema/common.py
Normal file
22
datatypes/epc/schema/common.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class Measurement:
|
||||
"""A numeric value with a physical unit, e.g. {"value": 2.4, "quantity": "metres"}."""
|
||||
value: float
|
||||
quantity: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DescriptionV1:
|
||||
"""Localised description object used in schemas 17.x, 18.x, 19.x, and 21.0.1."""
|
||||
value: str
|
||||
language: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class CostAmount:
|
||||
"""Monetary amount used in schemas 17.x, 18.x, and 19.x."""
|
||||
value: int
|
||||
currency: str
|
||||
222
datatypes/epc/schema/rdsap_schema_17_0.py
Normal file
222
datatypes/epc/schema/rdsap_schema_17_0.py
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import CostAmount, DescriptionV1, Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
description: DescriptionV1
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
rooms_with_bath_and_or_shower: int
|
||||
rooms_with_mixer_shower_no_bath: int
|
||||
rooms_with_bath_and_mixer_shower: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
cylinder_insulation_type: int
|
||||
has_fixed_air_conditioning: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupplyNoneOrNoDetails:
|
||||
pv_connection: int
|
||||
percent_roof_area: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapEnergySource:
|
||||
mains_gas: str
|
||||
meter_type: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbines_terrain_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Measurement
|
||||
heat_loss_perimeter: Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapBuildingPart:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
wall_thickness: int
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: str
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
indicative_cost: str
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlternativeImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema17_0:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
glazed_area: int
|
||||
glazing_gap: str
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: DescriptionV1
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
pvc_window_frames: str
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
lzc_energy_sources: List[int]
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
low_energy_lighting: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: CostAmount
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: CostAmount
|
||||
main_heating_controls: List[EnergyElement]
|
||||
multiple_glazing_type: int
|
||||
open_fireplaces_count: int
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: CostAmount
|
||||
hot_water_cost_current: CostAmount
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: CostAmount
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: CostAmount
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
fixed_lighting_outlets_count: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
has_heated_separate_conservatory: str
|
||||
potential_energy_efficiency_band: str
|
||||
co2_emissions_current_per_floor_area: int
|
||||
low_energy_fixed_lighting_outlets_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
address_line_2: Optional[str] = None
|
||||
alternative_improvements: Optional[List[AlternativeImprovement]] = None
|
||||
234
datatypes/epc/schema/rdsap_schema_17_1.py
Normal file
234
datatypes/epc/schema/rdsap_schema_17_1.py
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import CostAmount, DescriptionV1, Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
description: DescriptionV1
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
rooms_with_bath_and_or_shower: int
|
||||
rooms_with_mixer_shower_no_bath: int
|
||||
rooms_with_bath_and_mixer_shower: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
mcs_installed_heat_pump: Optional[str] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
cylinder_insulation_type: int
|
||||
has_fixed_air_conditioning: str
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupplyNoneOrNoDetails:
|
||||
pv_connection: int
|
||||
percent_roof_area: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapEnergySource:
|
||||
mains_gas: str
|
||||
meter_type: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbines_terrain_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
# Can be a Measurement object or 0 (int) for party walls of zero length
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
floor_insulation: Optional[int] = None
|
||||
floor_construction: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapBuildingPart:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
wall_thickness: int
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
# Can be a thickness string (e.g. "100mm") or 0 for uninsulated flat roofs
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
indicative_cost: str
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlternativeImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema17_1:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
glazed_area: int
|
||||
glazing_gap: str
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: DescriptionV1
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
pvc_window_frames: str
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
lzc_energy_sources: List[int]
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
low_energy_lighting: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: CostAmount
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: CostAmount
|
||||
main_heating_controls: List[EnergyElement]
|
||||
multiple_glazing_type: int
|
||||
open_fireplaces_count: int
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: CostAmount
|
||||
hot_water_cost_current: CostAmount
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: CostAmount
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: CostAmount
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
fixed_lighting_outlets_count: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
has_heated_separate_conservatory: str
|
||||
potential_energy_efficiency_band: str
|
||||
co2_emissions_current_per_floor_area: int
|
||||
low_energy_fixed_lighting_outlets_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
address_line_2: Optional[str] = None
|
||||
alternative_improvements: Optional[List[AlternativeImprovement]] = None
|
||||
245
datatypes/epc/schema/rdsap_schema_18_0.py
Normal file
245
datatypes/epc/schema/rdsap_schema_18_0.py
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import CostAmount, DescriptionV1, Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
description: DescriptionV1
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
rooms_with_bath_and_or_shower: int
|
||||
rooms_with_mixer_shower_no_bath: int
|
||||
rooms_with_bath_and_mixer_shower: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
central_heating_pump_age: Optional[int] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
has_fixed_air_conditioning: str
|
||||
cylinder_insulation_type: Optional[int] = None
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupplyNoneOrNoDetails:
|
||||
pv_connection: int
|
||||
percent_roof_area: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapEnergySource:
|
||||
mains_gas: str
|
||||
meter_type: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbines_terrain_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
floor_insulation: Optional[int] = None
|
||||
floor_construction: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapRoomInRoof:
|
||||
"""Room-in-roof details. floor_area is a Measurement object in schema 18.0."""
|
||||
floor_area: Measurement
|
||||
insulation: str
|
||||
roof_room_connected: str
|
||||
construction_age_band: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapBuildingPart:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
wall_thickness: int
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
flat_roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
indicative_cost: str
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlternativeImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema18_0:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
glazed_area: int
|
||||
# glazing_gap is an integer in 18.0 (e.g. 12 mm), unlike 17.x where it was a string
|
||||
glazing_gap: int
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: DescriptionV1
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
pvc_window_frames: str
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
lzc_energy_sources: List[int]
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
low_energy_lighting: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: CostAmount
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: CostAmount
|
||||
main_heating_controls: List[EnergyElement]
|
||||
multiple_glazing_type: int
|
||||
open_fireplaces_count: int
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: CostAmount
|
||||
hot_water_cost_current: CostAmount
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: CostAmount
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: CostAmount
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
fixed_lighting_outlets_count: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
has_heated_separate_conservatory: str
|
||||
potential_energy_efficiency_band: str
|
||||
co2_emissions_current_per_floor_area: int
|
||||
low_energy_fixed_lighting_outlets_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
address_line_2: Optional[str] = None
|
||||
alternative_improvements: Optional[List[AlternativeImprovement]] = None
|
||||
251
datatypes/epc/schema/rdsap_schema_19_0.py
Normal file
251
datatypes/epc/schema/rdsap_schema_19_0.py
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import CostAmount, DescriptionV1, Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
description: DescriptionV1
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
rooms_with_bath_and_or_shower: int
|
||||
rooms_with_mixer_shower_no_bath: int
|
||||
rooms_with_bath_and_mixer_shower: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
central_heating_pump_age: Optional[int] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
has_fixed_air_conditioning: str
|
||||
cylinder_insulation_type: Optional[int] = None
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupplyNoneOrNoDetails:
|
||||
pv_connection: int
|
||||
percent_roof_area: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapEnergySource:
|
||||
mains_gas: str
|
||||
meter_type: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbines_terrain_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
floor_insulation: Optional[int] = None
|
||||
floor_construction: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapRoomInRoof:
|
||||
floor_area: Measurement
|
||||
insulation: str
|
||||
roof_room_connected: str
|
||||
construction_age_band: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapBuildingPart:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
wall_thickness: int
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
flat_roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
indicative_cost: str
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class AlternativeImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema19_0:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
glazed_area: int
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: DescriptionV1
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
pvc_window_frames: str
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
lzc_energy_sources: List[int]
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
low_energy_lighting: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: CostAmount
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: CostAmount
|
||||
main_heating_controls: List[EnergyElement]
|
||||
multiple_glazing_type: int
|
||||
open_fireplaces_count: int
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: CostAmount
|
||||
hot_water_cost_current: CostAmount
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: CostAmount
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: CostAmount
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
windows_transmission_details: WindowsTransmissionDetails
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
fixed_lighting_outlets_count: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
has_heated_separate_conservatory: str
|
||||
potential_energy_efficiency_band: str
|
||||
co2_emissions_current_per_floor_area: int
|
||||
low_energy_fixed_lighting_outlets_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
address_line_2: Optional[str] = None
|
||||
glazing_gap: Optional[Union[str, int]] = None
|
||||
alternative_improvements: Optional[List[AlternativeImprovement]] = None
|
||||
282
datatypes/epc/schema/rdsap_schema_20_0_0.py
Normal file
282
datatypes/epc/schema/rdsap_schema_20_0_0.py
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
# description is a plain string in schema 20.0.0 onwards (no longer a localised object)
|
||||
description: str
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Addendum:
|
||||
addendum_numbers: List[int]
|
||||
stone_walls: Optional[str] = None
|
||||
system_build: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
rooms_with_bath_and_or_shower: int
|
||||
rooms_with_mixer_shower_no_bath: int
|
||||
rooms_with_bath_and_mixer_shower: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
central_heating_pump_age: Optional[int] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
has_fixed_air_conditioning: str
|
||||
cylinder_insulation_type: Optional[int] = None
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupplyNoneOrNoDetails:
|
||||
pv_connection: int
|
||||
percent_roof_area: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapEnergySource:
|
||||
mains_gas: str
|
||||
meter_type: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbines_terrain_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapWindow:
|
||||
orientation: int
|
||||
window_area: float
|
||||
window_type: int
|
||||
glazing_type: int
|
||||
window_location: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
floor_insulation: Optional[int] = None
|
||||
floor_construction: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapRoomInRoof:
|
||||
"""Room-in-roof details. floor_area is a plain number in schema 20.0.0 (not a Measurement object)."""
|
||||
floor_area: Union[int, float]
|
||||
insulation: str
|
||||
roof_room_connected: str
|
||||
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:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
wall_thickness: Optional[int] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
flat_roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
storey_count: Optional[int] = None
|
||||
unheated_corridor_length: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementTexts:
|
||||
improvement_description: str
|
||||
improvement_summary: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: Optional[int] = None
|
||||
improvement_texts: Optional[ImprovementTexts] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
# typical_saving is a plain number in schema 20.0.0 (not a CostAmount object)
|
||||
typical_saving: float
|
||||
# indicative_cost can be a formatted string (e.g. "£100 - £350") or a plain integer
|
||||
indicative_cost: Union[str, int]
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_cavity_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema20_0_0:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
glazed_area: int
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
sap_windows: List[SapWindow]
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
# dwelling_type is a plain string in schema 20.0.0 onwards
|
||||
dwelling_type: str
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
lzc_energy_sources: List[int]
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
low_energy_lighting: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: float
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: float
|
||||
main_heating_controls: List[EnergyElement]
|
||||
multiple_glazing_type: int
|
||||
open_fireplaces_count: int
|
||||
heating_cost_potential: float
|
||||
hot_water_cost_current: float
|
||||
insulated_door_u_value: float
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: float
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: float
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
windows_transmission_details: WindowsTransmissionDetails
|
||||
energy_consumption_current: int
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
fixed_lighting_outlets_count: int
|
||||
multiple_glazed_proportion_nr: Optional[str]
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
potential_energy_efficiency_band: str
|
||||
co2_emissions_current_per_floor_area: int
|
||||
low_energy_fixed_lighting_outlets_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
addendum: Optional[Addendum] = None
|
||||
address_line_2: Optional[str] = None
|
||||
has_hot_water_cylinder: Optional[str] = None
|
||||
has_fixed_air_conditioning: Optional[str] = None
|
||||
has_heated_separate_conservatory: Optional[str] = None
|
||||
339
datatypes/epc/schema/rdsap_schema_21_0_0.py
Normal file
339
datatypes/epc/schema/rdsap_schema_21_0_0.py
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
# description is a plain string in schema 21.0.0 (no longer a localised object)
|
||||
description: str
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Addendum:
|
||||
addendum_numbers: List[int]
|
||||
stone_walls: Optional[str] = None
|
||||
system_build: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ShowerOutlet:
|
||||
shower_wwhrs: int
|
||||
shower_outlet_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ShowerOutlets:
|
||||
shower_outlet: ShowerOutlet
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
"""Changed in 21.0.0: references WWHRS product index numbers instead of room counts."""
|
||||
wwhrs_index_number1: Optional[int] = None
|
||||
wwhrs_index_number2: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
boiler_ignition_type: Optional[int] = None
|
||||
central_heating_pump_age: Optional[int] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
has_fixed_air_conditioning: str
|
||||
shower_outlets: Optional[ShowerOutlets] = None
|
||||
cylinder_insulation_type: Optional[int] = None
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = 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: str
|
||||
meter_type: int
|
||||
pv_connection: int
|
||||
pv_battery_count: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbine_details: WindTurbineDetails
|
||||
gas_smart_meter_present: str
|
||||
is_dwelling_export_capable: str
|
||||
wind_turbines_terrain_type: int
|
||||
electricity_smart_meter_present: str
|
||||
pv_batteries: Optional[PvBatteries] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapWindow:
|
||||
pvc_frame: str
|
||||
glazing_gap: int
|
||||
orientation: int
|
||||
window_type: int
|
||||
frame_factor: float
|
||||
glazing_type: int
|
||||
window_width: float
|
||||
window_height: float
|
||||
draught_proofed: str
|
||||
window_location: int
|
||||
window_wall_type: int
|
||||
permanent_shutters_present: str
|
||||
window_transmission_details: WindowTransmissionDetails
|
||||
permanent_shutters_insulated: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
floor_insulation: Optional[int] = None
|
||||
floor_construction: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapRoomInRoof:
|
||||
"""Room-in-roof details. insulation and roof_room_connected removed in schema 21.0.0."""
|
||||
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:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
sap_alternative_wall_1: Optional[SapAlternativeWall] = None
|
||||
sap_alternative_wall_2: Optional[SapAlternativeWall] = None
|
||||
wall_thickness: Optional[int] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
flat_roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
storey_count: Optional[int] = None
|
||||
unheated_corridor_length: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementTexts:
|
||||
improvement_description: str
|
||||
improvement_summary: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: Optional[int] = None
|
||||
improvement_texts: Optional[ImprovementTexts] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: float
|
||||
indicative_cost: Union[str, int]
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_cavity_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema21_0_0:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
sap_windows: List[SapWindow]
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: str
|
||||
language_code: int
|
||||
pressure_test: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
wet_rooms_count: int
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
open_chimneys_count: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: float
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: float
|
||||
main_heating_controls: List[EnergyElement]
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: float
|
||||
hot_water_cost_current: float
|
||||
insulated_door_u_value: float
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: float
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: float
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
draughtproofed_door_count: int
|
||||
mechanical_vent_duct_type: int
|
||||
windows_transmission_details: WindowsTransmissionDetails
|
||||
cfl_fixed_lighting_bulbs_count: int
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
led_fixed_lighting_bulbs_count: int
|
||||
mechanical_vent_duct_placement: int
|
||||
mechanical_vent_duct_insulation: int
|
||||
potential_energy_efficiency_band: str
|
||||
pressure_test_certificate_number: int
|
||||
mechanical_ventilation_index_number: int
|
||||
co2_emissions_current_per_floor_area: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
low_energy_fixed_lighting_bulbs_count: int
|
||||
mechanical_vent_duct_insulation_level: int
|
||||
mechanical_vent_measured_installation: str
|
||||
incandescent_fixed_lighting_bulbs_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
addendum: Optional[Addendum] = None
|
||||
address_line_2: Optional[str] = None
|
||||
has_heated_separate_conservatory: Optional[str] = None
|
||||
fixed_lighting_outlets_count: Optional[int] = None
|
||||
low_energy_fixed_lighting_outlets_count: Optional[int] = None
|
||||
340
datatypes/epc/schema/rdsap_schema_21_0_1.py
Normal file
340
datatypes/epc/schema/rdsap_schema_21_0_1.py
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from .common import DescriptionV1, Measurement
|
||||
|
||||
|
||||
@dataclass
|
||||
class EnergyElement:
|
||||
# Descriptions revert to localised objects in schema 21.0.1 (were plain strings in 21.0.0)
|
||||
description: DescriptionV1
|
||||
energy_efficiency_rating: int
|
||||
environmental_efficiency_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class Addendum:
|
||||
addendum_numbers: List[int]
|
||||
stone_walls: Optional[str] = None
|
||||
system_build: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ShowerOutlet:
|
||||
shower_wwhrs: int
|
||||
shower_outlet_type: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class ShowerOutlets:
|
||||
shower_outlet: ShowerOutlet
|
||||
|
||||
|
||||
@dataclass
|
||||
class InstantaneousWwhrs:
|
||||
"""References WWHRS product index numbers (introduced in 21.0.0)."""
|
||||
wwhrs_index_number1: Optional[int] = None
|
||||
wwhrs_index_number2: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class MainHeatingDetail:
|
||||
has_fghrs: str
|
||||
main_fuel_type: int
|
||||
heat_emitter_type: int
|
||||
emitter_temperature: Union[int, str]
|
||||
main_heating_number: int
|
||||
main_heating_control: int
|
||||
main_heating_category: int
|
||||
main_heating_fraction: int
|
||||
main_heating_data_source: int
|
||||
boiler_flue_type: Optional[int] = None
|
||||
fan_flue_present: Optional[str] = None
|
||||
boiler_ignition_type: Optional[int] = None
|
||||
central_heating_pump_age: Optional[int] = None
|
||||
main_heating_index_number: Optional[int] = None
|
||||
sap_main_heating_code: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapHeating:
|
||||
cylinder_size: int
|
||||
water_heating_code: int
|
||||
water_heating_fuel: int
|
||||
instantaneous_wwhrs: InstantaneousWwhrs
|
||||
main_heating_details: List[MainHeatingDetail]
|
||||
immersion_heating_type: Union[int, str]
|
||||
has_fixed_air_conditioning: str
|
||||
shower_outlets: Optional[ShowerOutlets] = None
|
||||
cylinder_insulation_type: Optional[int] = None
|
||||
cylinder_thermostat: Optional[str] = None
|
||||
secondary_fuel_type: Optional[int] = None
|
||||
secondary_heating_type: Optional[int] = None
|
||||
cylinder_insulation_thickness: Optional[int] = 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: str
|
||||
meter_type: int
|
||||
pv_connection: int
|
||||
pv_battery_count: int
|
||||
photovoltaic_supply: PhotovoltaicSupply
|
||||
wind_turbines_count: int
|
||||
wind_turbine_details: WindTurbineDetails
|
||||
gas_smart_meter_present: str
|
||||
is_dwelling_export_capable: str
|
||||
wind_turbines_terrain_type: int
|
||||
electricity_smart_meter_present: str
|
||||
pv_batteries: Optional[PvBatteries] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapWindow:
|
||||
pvc_frame: str
|
||||
glazing_gap: int
|
||||
orientation: int
|
||||
window_type: int
|
||||
frame_factor: float
|
||||
glazing_type: int
|
||||
window_width: float
|
||||
window_height: float
|
||||
draught_proofed: str
|
||||
window_location: int
|
||||
window_wall_type: int
|
||||
permanent_shutters_present: str
|
||||
window_transmission_details: WindowTransmissionDetails
|
||||
permanent_shutters_insulated: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFloorDimension:
|
||||
floor: int
|
||||
room_height: Measurement
|
||||
total_floor_area: Measurement
|
||||
party_wall_length: Union[Measurement, int]
|
||||
heat_loss_perimeter: Measurement
|
||||
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:
|
||||
identifier: str
|
||||
wall_dry_lined: str
|
||||
floor_heat_loss: int
|
||||
roof_construction: int
|
||||
wall_construction: int
|
||||
building_part_number: int
|
||||
sap_floor_dimensions: List[SapFloorDimension]
|
||||
wall_insulation_type: int
|
||||
construction_age_band: str
|
||||
party_wall_construction: Union[int, str]
|
||||
wall_thickness_measured: str
|
||||
roof_insulation_location: Union[int, str]
|
||||
roof_insulation_thickness: Union[str, int]
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
sap_alternative_wall_1: Optional[SapAlternativeWall] = None
|
||||
sap_alternative_wall_2: Optional[SapAlternativeWall] = None
|
||||
wall_thickness: Optional[int] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
flat_roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SapFlatDetails:
|
||||
level: int
|
||||
top_storey: str
|
||||
flat_location: int
|
||||
heat_loss_corridor: int
|
||||
storey_count: Optional[int] = None
|
||||
# Changed from plain int in 21.0.0 to a Measurement object in 21.0.1
|
||||
unheated_corridor_length: Optional[Union[Measurement, int]] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class WindowsTransmissionDetails:
|
||||
u_value: float
|
||||
data_source: int
|
||||
solar_transmittance: float
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementTexts:
|
||||
improvement_description: str
|
||||
improvement_summary: Optional[str] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class ImprovementDetails:
|
||||
improvement_number: Optional[int] = None
|
||||
improvement_texts: Optional[ImprovementTexts] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class SuggestedImprovement:
|
||||
sequence: int
|
||||
typical_saving: float
|
||||
indicative_cost: Union[str, int]
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
class RenewableHeatIncentive:
|
||||
water_heating: int
|
||||
space_heating_existing_dwelling: int
|
||||
impact_of_loft_insulation: Optional[int] = None
|
||||
impact_of_cavity_insulation: Optional[int] = None
|
||||
impact_of_solid_wall_insulation: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
class RdSapSchema21_0_1:
|
||||
uprn: int
|
||||
roofs: List[EnergyElement]
|
||||
walls: List[EnergyElement]
|
||||
floors: List[EnergyElement]
|
||||
status: str
|
||||
tenure: int
|
||||
window: EnergyElement
|
||||
lighting: EnergyElement
|
||||
postcode: str
|
||||
hot_water: EnergyElement
|
||||
post_town: str
|
||||
built_form: int
|
||||
door_count: int
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
sap_version: float
|
||||
sap_windows: List[SapWindow]
|
||||
schema_type: str
|
||||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
# dwelling_type remains a plain string (not reverted to DescriptionV1) in 21.0.1
|
||||
dwelling_type: str
|
||||
language_code: int
|
||||
pressure_test: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
assessment_type: str
|
||||
completion_date: str
|
||||
inspection_date: str
|
||||
wet_rooms_count: int
|
||||
extensions_count: int
|
||||
measurement_type: int
|
||||
total_floor_area: int
|
||||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
sap_building_parts: List[SapBuildingPart]
|
||||
open_chimneys_count: int
|
||||
solar_water_heating: str
|
||||
habitable_room_count: int
|
||||
heating_cost_current: float
|
||||
insulated_door_count: int
|
||||
co2_emissions_current: float
|
||||
energy_rating_average: int
|
||||
energy_rating_current: int
|
||||
lighting_cost_current: float
|
||||
main_heating_controls: List[EnergyElement]
|
||||
has_hot_water_cylinder: str
|
||||
heating_cost_potential: float
|
||||
hot_water_cost_current: float
|
||||
insulated_door_u_value: float
|
||||
mechanical_ventilation: int
|
||||
percent_draughtproofed: int
|
||||
suggested_improvements: List[SuggestedImprovement]
|
||||
co2_emissions_potential: float
|
||||
energy_rating_potential: int
|
||||
lighting_cost_potential: float
|
||||
schema_version_original: str
|
||||
hot_water_cost_potential: float
|
||||
renewable_heat_incentive: RenewableHeatIncentive
|
||||
draughtproofed_door_count: int
|
||||
mechanical_vent_duct_type: int
|
||||
windows_transmission_details: WindowsTransmissionDetails
|
||||
cfl_fixed_lighting_bulbs_count: int
|
||||
energy_consumption_current: int
|
||||
has_fixed_air_conditioning: str
|
||||
multiple_glazed_proportion: int
|
||||
calculation_software_version: str
|
||||
energy_consumption_potential: int
|
||||
environmental_impact_current: int
|
||||
led_fixed_lighting_bulbs_count: int
|
||||
mechanical_vent_duct_placement: int
|
||||
mechanical_vent_duct_insulation: int
|
||||
potential_energy_efficiency_band: str
|
||||
pressure_test_certificate_number: int
|
||||
mechanical_ventilation_index_number: int
|
||||
co2_emissions_current_per_floor_area: int
|
||||
current_energy_efficiency_band: str
|
||||
environmental_impact_potential: int
|
||||
low_energy_fixed_lighting_bulbs_count: int
|
||||
mechanical_vent_duct_insulation_level: int
|
||||
mechanical_vent_measured_installation: str
|
||||
incandescent_fixed_lighting_bulbs_count: int
|
||||
sap_flat_details: Optional[SapFlatDetails] = None
|
||||
addendum: Optional[Addendum] = None
|
||||
address_line_2: Optional[str] = None
|
||||
has_heated_separate_conservatory: Optional[str] = None
|
||||
fixed_lighting_outlets_count: Optional[int] = None
|
||||
low_energy_fixed_lighting_outlets_count: Optional[int] = None
|
||||
0
datatypes/epc/schema/tests/__init__.py
Normal file
0
datatypes/epc/schema/tests/__init__.py
Normal file
218
datatypes/epc/schema/tests/fixtures/17_0.json
vendored
Normal file
218
datatypes/epc/schema/tests/fixtures/17_0.json
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{
|
||||
"description": {"value": "(another dwelling above)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
{
|
||||
"description": {"value": "System built, with internal insulation", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"floors": [
|
||||
{
|
||||
"description": {"value": "(another dwelling below)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 2,
|
||||
"window": {
|
||||
"description": {"value": "Fully double glazed", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
"lighting": {
|
||||
"description": {"value": "Low energy lighting in 57% of fixed outlets", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
},
|
||||
"postcode": "PT5 4RZ",
|
||||
"hot_water": {
|
||||
"description": {"value": "Electric immersion, off-peak", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 2
|
||||
},
|
||||
"post_town": "POSTTOWN",
|
||||
"built_form": 2,
|
||||
"door_count": 2,
|
||||
"glazed_area": 1,
|
||||
"glazing_gap": "16+",
|
||||
"region_code": 3,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 2,
|
||||
"water_heating_code": 903,
|
||||
"water_heating_fuel": 29,
|
||||
"instantaneous_wwhrs": {
|
||||
"rooms_with_bath_and_or_shower": 1,
|
||||
"rooms_with_mixer_shower_no_bath": 0,
|
||||
"rooms_with_bath_and_mixer_shower": 0
|
||||
},
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 29,
|
||||
"heat_emitter_type": 0,
|
||||
"emitter_temperature": "NA",
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2401,
|
||||
"main_heating_category": 7,
|
||||
"main_heating_fraction": 1,
|
||||
"sap_main_heating_code": 402,
|
||||
"main_heating_data_source": 2
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": 1,
|
||||
"cylinder_insulation_type": 0,
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 9.92,
|
||||
"schema_type": "RdSAP-Schema-17.0",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "EAW",
|
||||
"main_heating": [
|
||||
{
|
||||
"description": {"value": "Electric storage heaters", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 1
|
||||
}
|
||||
],
|
||||
"dwelling_type": {"value": "Mid-floor flat", "language": "1"},
|
||||
"language_code": 1,
|
||||
"property_type": 2,
|
||||
"address_line_1": "42, Moria Mines Lane",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2016-01-12",
|
||||
"inspection_date": "2016-01-12",
|
||||
"extensions_count": 0,
|
||||
"measurement_type": 1,
|
||||
"sap_flat_details": {
|
||||
"level": 2,
|
||||
"top_storey": "N",
|
||||
"flat_location": 1,
|
||||
"heat_loss_corridor": 0
|
||||
},
|
||||
"total_floor_area": 55,
|
||||
"transaction_type": 8,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 1,
|
||||
"pvc_window_frames": "true",
|
||||
"registration_date": "2016-01-12",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "N",
|
||||
"meter_type": 1,
|
||||
"photovoltaic_supply": {
|
||||
"none_or_no_details": {"pv_connection": 0, "percent_roof_area": 0}
|
||||
},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbines_terrain_type": 2
|
||||
},
|
||||
"secondary_heating": {
|
||||
"description": {"value": "Portable electric heaters (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"lzc_energy_sources": [11],
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 240,
|
||||
"floor_heat_loss": 6,
|
||||
"roof_construction": 3,
|
||||
"wall_construction": 8,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.4, "quantity": "metres"},
|
||||
"total_floor_area": {"value": 54.6, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 7.3, "quantity": "metres"},
|
||||
"heat_loss_perimeter": {"value": 23.3, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 3,
|
||||
"construction_age_band": "D",
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": "ND",
|
||||
"roof_insulation_thickness": "ND",
|
||||
"wall_insulation_thickness": "50mm"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 57,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 3,
|
||||
"heating_cost_current": {"value": 214, "currency": "GBP"},
|
||||
"insulated_door_count": 0,
|
||||
"co2_emissions_current": 3.9,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 66,
|
||||
"lighting_cost_current": {"value": 61, "currency": "GBP"},
|
||||
"main_heating_controls": [
|
||||
{
|
||||
"description": {"value": "Manual charge control", "language": "1"},
|
||||
"energy_efficiency_rating": 2,
|
||||
"environmental_efficiency_rating": 2
|
||||
}
|
||||
],
|
||||
"multiple_glazing_type": 3,
|
||||
"open_fireplaces_count": 0,
|
||||
"has_hot_water_cylinder": "true",
|
||||
"heating_cost_potential": {"value": 216, "currency": "GBP"},
|
||||
"hot_water_cost_current": {"value": 396, "currency": "GBP"},
|
||||
"mechanical_ventilation": 0,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": {"value": 158, "currency": "GBP"},
|
||||
"indicative_cost": "£15 - £30",
|
||||
"improvement_type": "C",
|
||||
"improvement_details": {"improvement_number": 1},
|
||||
"improvement_category": 5,
|
||||
"energy_performance_rating": 74,
|
||||
"environmental_impact_rating": 60
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 2.5,
|
||||
"energy_rating_potential": 79,
|
||||
"lighting_cost_potential": {"value": 42, "currency": "GBP"},
|
||||
"schema_version_original": "LIG-17.0",
|
||||
"alternative_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": {"value": 141, "currency": "GBP"},
|
||||
"improvement_type": "J2",
|
||||
"improvement_details": {"improvement_number": 54},
|
||||
"improvement_category": 6,
|
||||
"energy_performance_rating": 81,
|
||||
"environmental_impact_rating": 96
|
||||
}
|
||||
],
|
||||
"hot_water_cost_potential": {"value": 154, "currency": "GBP"},
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 4818,
|
||||
"space_heating_existing_dwelling": 2415
|
||||
},
|
||||
"energy_consumption_current": 427,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "9.0.0",
|
||||
"energy_consumption_potential": 267,
|
||||
"environmental_impact_current": 48,
|
||||
"fixed_lighting_outlets_count": 7,
|
||||
"current_energy_efficiency_band": "D",
|
||||
"environmental_impact_potential": 66,
|
||||
"has_heated_separate_conservatory": "false",
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"co2_emissions_current_per_floor_area": 72,
|
||||
"low_energy_fixed_lighting_outlets_count": 4
|
||||
}
|
||||
243
datatypes/epc/schema/tests/fixtures/17_1.json
vendored
Normal file
243
datatypes/epc/schema/tests/fixtures/17_1.json
vendored
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{
|
||||
"description": {"value": "Pitched, 100 mm loft insulation", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
{
|
||||
"description": {"value": "Pitched, insulated (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
{
|
||||
"description": {"value": "Cavity wall, filled cavity", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"floors": [
|
||||
{
|
||||
"description": {"value": "Solid, no insulation (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 1,
|
||||
"window": {
|
||||
"description": {"value": "Fully double glazed", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
"lighting": {
|
||||
"description": {"value": "Low energy lighting in 23% of fixed outlets", "language": "1"},
|
||||
"energy_efficiency_rating": 2,
|
||||
"environmental_efficiency_rating": 2
|
||||
},
|
||||
"postcode": "PT42 5HL",
|
||||
"hot_water": {
|
||||
"description": {"value": "From main system", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
"post_town": "POSTTOWN",
|
||||
"built_form": 1,
|
||||
"door_count": 4,
|
||||
"glazed_area": 1,
|
||||
"glazing_gap": "16+",
|
||||
"region_code": 17,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 2,
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 28,
|
||||
"cylinder_thermostat": "Y",
|
||||
"instantaneous_wwhrs": {
|
||||
"rooms_with_bath_and_or_shower": 1,
|
||||
"rooms_with_mixer_shower_no_bath": 0,
|
||||
"rooms_with_bath_and_mixer_shower": 1
|
||||
},
|
||||
"secondary_fuel_type": 29,
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 28,
|
||||
"boiler_flue_type": 1,
|
||||
"fan_flue_present": "N",
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": "NA",
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2104,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"mcs_installed_heat_pump": "false",
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 9049
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"secondary_heating_type": 691,
|
||||
"cylinder_insulation_type": 1,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"cylinder_insulation_thickness": 12
|
||||
},
|
||||
"sap_version": 9.92,
|
||||
"schema_type": "RdSAP-Schema-17.1",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "EAW",
|
||||
"main_heating": [
|
||||
{
|
||||
"description": {"value": "Boiler and radiators, oil", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
}
|
||||
],
|
||||
"dwelling_type": {"value": "Detached house", "language": "1"},
|
||||
"language_code": 1,
|
||||
"property_type": 0,
|
||||
"address_line_1": "15, Hedge Lane",
|
||||
"address_line_2": "Lower Moria",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2018-05-29",
|
||||
"inspection_date": "2018-05-29",
|
||||
"extensions_count": 1,
|
||||
"measurement_type": 2,
|
||||
"total_floor_area": 101,
|
||||
"transaction_type": 1,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 7,
|
||||
"pvc_window_frames": "true",
|
||||
"registration_date": "2018-05-27",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "N",
|
||||
"meter_type": 2,
|
||||
"photovoltaic_supply": {
|
||||
"none_or_no_details": {"pv_connection": 0, "percent_roof_area": 0}
|
||||
},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbines_terrain_type": 2
|
||||
},
|
||||
"secondary_heating": {
|
||||
"description": {"value": "Room heaters, electric", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"lzc_energy_sources": [11],
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 270,
|
||||
"floor_heat_loss": 7,
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.4, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 48.45, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 0, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 22.3, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 2,
|
||||
"construction_age_band": "G",
|
||||
"party_wall_construction": "NA",
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "100mm"
|
||||
},
|
||||
{
|
||||
"identifier": "Extension 1",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 260,
|
||||
"floor_heat_loss": 7,
|
||||
"roof_construction": 5,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 2,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.4, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 21.84, "quantity": "square metres"},
|
||||
"party_wall_length": 0,
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 16.6, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 4,
|
||||
"construction_age_band": "H",
|
||||
"party_wall_construction": "NA",
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": 4,
|
||||
"roof_insulation_thickness": 0,
|
||||
"wall_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 23,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 7,
|
||||
"heating_cost_current": {"value": 659, "currency": "GBP"},
|
||||
"insulated_door_count": 0,
|
||||
"co2_emissions_current": 5.8,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 53,
|
||||
"lighting_cost_current": {"value": 115, "currency": "GBP"},
|
||||
"main_heating_controls": [
|
||||
{
|
||||
"description": {"value": "Programmer and room thermostat", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
}
|
||||
],
|
||||
"multiple_glazing_type": 3,
|
||||
"open_fireplaces_count": 0,
|
||||
"has_hot_water_cylinder": "true",
|
||||
"heating_cost_potential": {"value": 470, "currency": "GBP"},
|
||||
"hot_water_cost_current": {"value": 161, "currency": "GBP"},
|
||||
"mechanical_ventilation": 0,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": {"value": 25, "currency": "GBP"},
|
||||
"indicative_cost": "£100 - £350",
|
||||
"improvement_type": "A",
|
||||
"improvement_details": {"improvement_number": 5},
|
||||
"improvement_category": 5,
|
||||
"energy_performance_rating": 54,
|
||||
"environmental_impact_rating": 47
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 2.7,
|
||||
"energy_rating_potential": 78,
|
||||
"lighting_cost_potential": {"value": 65, "currency": "GBP"},
|
||||
"schema_version_original": "LIG-17.1",
|
||||
"hot_water_cost_potential": {"value": 77, "currency": "GBP"},
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 3301,
|
||||
"impact_of_loft_insulation": -565,
|
||||
"space_heating_existing_dwelling": 11351
|
||||
},
|
||||
"energy_consumption_current": 234,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "v92.0.1.1",
|
||||
"energy_consumption_potential": 95,
|
||||
"environmental_impact_current": 46,
|
||||
"fixed_lighting_outlets_count": 13,
|
||||
"current_energy_efficiency_band": "E",
|
||||
"environmental_impact_potential": 72,
|
||||
"has_heated_separate_conservatory": "false",
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"co2_emissions_current_per_floor_area": 57,
|
||||
"low_energy_fixed_lighting_outlets_count": 3
|
||||
}
|
||||
251
datatypes/epc/schema/tests/fixtures/18_0.json
vendored
Normal file
251
datatypes/epc/schema/tests/fixtures/18_0.json
vendored
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{
|
||||
"description": {"value": "Pitched, 100 mm loft insulation", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
{
|
||||
"description": {"value": "Flat, insulated", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
{
|
||||
"description": {"value": "Roof room(s), insulated (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
{
|
||||
"description": {"value": "Solid brick, as built, no insulation (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 1,
|
||||
"environmental_efficiency_rating": 1
|
||||
}
|
||||
],
|
||||
"floors": [
|
||||
{
|
||||
"description": {"value": "Solid, no insulation (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 1,
|
||||
"window": {
|
||||
"description": {"value": "Fully double glazed", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
"lighting": {
|
||||
"description": {"value": "Low energy lighting in 67% of fixed outlets", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
},
|
||||
"postcode": "PT11 4RF",
|
||||
"hot_water": {
|
||||
"description": {"value": "From main system", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
},
|
||||
"post_town": "POSTTOWN",
|
||||
"built_form": 4,
|
||||
"door_count": 2,
|
||||
"glazed_area": 1,
|
||||
"glazing_gap": 12,
|
||||
"region_code": 1,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 1,
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 26,
|
||||
"instantaneous_wwhrs": {
|
||||
"rooms_with_bath_and_or_shower": 1,
|
||||
"rooms_with_mixer_shower_no_bath": 0,
|
||||
"rooms_with_bath_and_mixer_shower": 0
|
||||
},
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 26,
|
||||
"boiler_flue_type": 2,
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": 0,
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2106,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"central_heating_pump_age": 0,
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 16137
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 9.92,
|
||||
"schema_type": "RdSAP-Schema-18.0",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "EAW",
|
||||
"main_heating": [
|
||||
{
|
||||
"description": {"value": "Boiler and radiators, mains gas", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"dwelling_type": {"value": "Mid-terrace house", "language": "1"},
|
||||
"language_code": 1,
|
||||
"property_type": 0,
|
||||
"address_line_1": "1, Bagshot Lane",
|
||||
"address_line_2": "Village",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2017-03-19",
|
||||
"inspection_date": "2017-03-19",
|
||||
"extensions_count": 1,
|
||||
"measurement_type": 1,
|
||||
"total_floor_area": 93,
|
||||
"transaction_type": 5,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 5,
|
||||
"pvc_window_frames": "true",
|
||||
"registration_date": "2017-03-19",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "Y",
|
||||
"meter_type": 1,
|
||||
"photovoltaic_supply": {
|
||||
"none_or_no_details": {"pv_connection": 0, "percent_roof_area": 0}
|
||||
},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbines_terrain_type": 2
|
||||
},
|
||||
"secondary_heating": {
|
||||
"description": {"value": "None", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"lzc_energy_sources": [11],
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 330,
|
||||
"floor_heat_loss": 7,
|
||||
"sap_room_in_roof": {
|
||||
"floor_area": {"value": 9, "quantity": "square metres"},
|
||||
"insulation": "AB",
|
||||
"roof_room_connected": "N",
|
||||
"construction_age_band": "G"
|
||||
},
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 3,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.4, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 29.12, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 11.2, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 5.2, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 4,
|
||||
"construction_age_band": "C",
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "100mm",
|
||||
"wall_insulation_thickness": "NI"
|
||||
},
|
||||
{
|
||||
"identifier": "Extension",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 290,
|
||||
"floor_heat_loss": 7,
|
||||
"roof_construction": 1,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 2,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.4, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 15.6, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 6, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 5.2, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 4,
|
||||
"construction_age_band": "G",
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": 6,
|
||||
"roof_insulation_thickness": "NI",
|
||||
"wall_insulation_thickness": "NI",
|
||||
"flat_roof_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 67,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 5,
|
||||
"heating_cost_current": {"value": 619, "currency": "GBP"},
|
||||
"insulated_door_count": 0,
|
||||
"co2_emissions_current": 3.4,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 69,
|
||||
"lighting_cost_current": {"value": 81, "currency": "GBP"},
|
||||
"main_heating_controls": [
|
||||
{
|
||||
"description": {"value": "Programmer, room thermostat and TRVs", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"multiple_glazing_type": 3,
|
||||
"open_fireplaces_count": 0,
|
||||
"has_hot_water_cylinder": "false",
|
||||
"heating_cost_potential": {"value": 534, "currency": "GBP"},
|
||||
"hot_water_cost_current": {"value": 100, "currency": "GBP"},
|
||||
"mechanical_ventilation": 0,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": {"value": 88, "currency": "GBP"},
|
||||
"indicative_cost": "£4,000 - £14,000",
|
||||
"improvement_type": "Q",
|
||||
"improvement_details": {"improvement_number": 7},
|
||||
"improvement_category": 5,
|
||||
"energy_performance_rating": 72,
|
||||
"environmental_impact_rating": 71
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 1.7,
|
||||
"energy_rating_potential": 85,
|
||||
"lighting_cost_potential": {"value": 61, "currency": "GBP"},
|
||||
"schema_version_original": "LIG-17.0",
|
||||
"hot_water_cost_potential": {"value": 68, "currency": "GBP"},
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 2087,
|
||||
"impact_of_loft_insulation": -214,
|
||||
"impact_of_solid_wall_insulation": -1864,
|
||||
"space_heating_existing_dwelling": 10483
|
||||
},
|
||||
"energy_consumption_current": 230,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "2.0.0.0",
|
||||
"energy_consumption_potential": 115,
|
||||
"environmental_impact_current": 66,
|
||||
"fixed_lighting_outlets_count": 9,
|
||||
"current_energy_efficiency_band": "C",
|
||||
"environmental_impact_potential": 83,
|
||||
"has_heated_separate_conservatory": "false",
|
||||
"potential_energy_efficiency_band": "B",
|
||||
"co2_emissions_current_per_floor_area": 41,
|
||||
"low_energy_fixed_lighting_outlets_count": 6
|
||||
}
|
||||
213
datatypes/epc/schema/tests/fixtures/19_0.json
vendored
Normal file
213
datatypes/epc/schema/tests/fixtures/19_0.json
vendored
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{
|
||||
"description": {"value": "Pitched, 150 mm loft insulation", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
{
|
||||
"description": {"value": "Cavity wall, filled cavity", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
}
|
||||
],
|
||||
"floors": [
|
||||
{
|
||||
"description": {"value": "Solid, no insulation (assumed)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 3,
|
||||
"window": {
|
||||
"description": {"value": "Fully double glazed", "language": "1"},
|
||||
"energy_efficiency_rating": 3,
|
||||
"environmental_efficiency_rating": 3
|
||||
},
|
||||
"lighting": {
|
||||
"description": {"value": "Low energy lighting in 87% of fixed outlets", "language": "1"},
|
||||
"energy_efficiency_rating": 5,
|
||||
"environmental_efficiency_rating": 5
|
||||
},
|
||||
"postcode": "A1 1AA",
|
||||
"hot_water": {
|
||||
"description": {"value": "From main system", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
},
|
||||
"post_town": "Town",
|
||||
"built_form": 2,
|
||||
"door_count": 1,
|
||||
"glazed_area": 1,
|
||||
"region_code": 19,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 1,
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 26,
|
||||
"instantaneous_wwhrs": {
|
||||
"rooms_with_bath_and_or_shower": 1,
|
||||
"rooms_with_mixer_shower_no_bath": 0,
|
||||
"rooms_with_bath_and_mixer_shower": 0
|
||||
},
|
||||
"secondary_fuel_type": 9,
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 26,
|
||||
"boiler_flue_type": 2,
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": 0,
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2106,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"central_heating_pump_age": 0,
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 15274
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"secondary_heating_type": 631,
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 9.94,
|
||||
"schema_type": "RdSAP-Schema-19.0",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "EAW",
|
||||
"main_heating": [
|
||||
{
|
||||
"description": {"value": "Boiler and radiators, mains gas", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"dwelling_type": {"value": "Semi-detached house", "language": "1"},
|
||||
"language_code": 1,
|
||||
"property_type": 0,
|
||||
"address_line_1": "15, Address Lane",
|
||||
"address_line_2": "New Town",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2020-06-04",
|
||||
"inspection_date": "2020-06-03",
|
||||
"extensions_count": 1,
|
||||
"measurement_type": 1,
|
||||
"total_floor_area": 94,
|
||||
"transaction_type": 8,
|
||||
"conservatory_type": 2,
|
||||
"heated_room_count": 5,
|
||||
"pvc_window_frames": "false",
|
||||
"registration_date": "2020-06-04",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "Y",
|
||||
"meter_type": 3,
|
||||
"photovoltaic_supply": {
|
||||
"none_or_no_details": {"pv_connection": 0, "percent_roof_area": 0}
|
||||
},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbines_terrain_type": 2
|
||||
},
|
||||
"secondary_heating": {
|
||||
"description": {"value": "Room heaters, dual fuel (mineral and wood)", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"lzc_energy_sources": [11, 9],
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"wall_thickness": 300,
|
||||
"floor_heat_loss": 7,
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.47, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 39.91, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 8.81, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 13.65, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 2,
|
||||
"construction_age_band": "D",
|
||||
"party_wall_construction": 1,
|
||||
"wall_thickness_measured": "Y",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "150mm",
|
||||
"wall_insulation_thickness": "NI",
|
||||
"floor_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 87,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 5,
|
||||
"heating_cost_current": {"value": 666, "currency": "GBP"},
|
||||
"insulated_door_count": 0,
|
||||
"co2_emissions_current": 3.8,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 66,
|
||||
"lighting_cost_current": {"value": 81, "currency": "GBP"},
|
||||
"main_heating_controls": [
|
||||
{
|
||||
"description": {"value": "Programmer, room thermostat and TRVs", "language": "1"},
|
||||
"energy_efficiency_rating": 4,
|
||||
"environmental_efficiency_rating": 4
|
||||
}
|
||||
],
|
||||
"multiple_glazing_type": 3,
|
||||
"open_fireplaces_count": 0,
|
||||
"has_hot_water_cylinder": "false",
|
||||
"heating_cost_potential": {"value": 615, "currency": "GBP"},
|
||||
"hot_water_cost_current": {"value": 107, "currency": "GBP"},
|
||||
"mechanical_ventilation": 0,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": {"value": 51, "currency": "GBP"},
|
||||
"indicative_cost": "£4,000 - £6,000",
|
||||
"improvement_type": "W2",
|
||||
"improvement_details": {"improvement_number": 58},
|
||||
"improvement_category": 5,
|
||||
"energy_performance_rating": 68,
|
||||
"environmental_impact_rating": 65
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 2.4,
|
||||
"energy_rating_potential": 79,
|
||||
"lighting_cost_potential": {"value": 81, "currency": "GBP"},
|
||||
"schema_version_original": "LIG-19.0",
|
||||
"hot_water_cost_potential": {"value": 74, "currency": "GBP"},
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 2207,
|
||||
"impact_of_loft_insulation": -394,
|
||||
"space_heating_existing_dwelling": 9825
|
||||
},
|
||||
"energy_consumption_current": 222,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "2.1.1.0",
|
||||
"energy_consumption_potential": 137,
|
||||
"environmental_impact_current": 62,
|
||||
"fixed_lighting_outlets_count": 15,
|
||||
"windows_transmission_details": {
|
||||
"u_value": 3.1,
|
||||
"data_source": 2,
|
||||
"solar_transmittance": 0.76
|
||||
},
|
||||
"current_energy_efficiency_band": "D",
|
||||
"environmental_impact_potential": 75,
|
||||
"has_heated_separate_conservatory": "false",
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"co2_emissions_current_per_floor_area": 41,
|
||||
"low_energy_fixed_lighting_outlets_count": 13
|
||||
}
|
||||
225
datatypes/epc/schema/tests/fixtures/20_0_0.json
vendored
Normal file
225
datatypes/epc/schema/tests/fixtures/20_0_0.json
vendored
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{"description": "Pitched, 25 mm loft insulation", "energy_efficiency_rating": 2, "environmental_efficiency_rating": 2},
|
||||
{"description": "Pitched, 250 mm loft insulation", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"walls": [
|
||||
{"description": "Solid brick, as built, no insulation (assumed)", "energy_efficiency_rating": 1, "environmental_efficiency_rating": 1},
|
||||
{"description": "Cavity wall, as built, insulated (assumed)", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"floors": [
|
||||
{"description": "Suspended, no insulation (assumed)", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0},
|
||||
{"description": "Solid, insulated (assumed)", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 1,
|
||||
"window": {"description": "Fully double glazed", "energy_efficiency_rating": 3, "environmental_efficiency_rating": 3},
|
||||
"addendum": {
|
||||
"stone_walls": "true",
|
||||
"system_build": "true",
|
||||
"addendum_numbers": [1, 8]
|
||||
},
|
||||
"lighting": {"description": "Low energy lighting in 50% of fixed outlets", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"postcode": "A0 0AA",
|
||||
"hot_water": {"description": "From main system", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"post_town": "Whitbury",
|
||||
"built_form": 2,
|
||||
"door_count": 2,
|
||||
"glazed_area": 1,
|
||||
"region_code": 1,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 1,
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 26,
|
||||
"instantaneous_wwhrs": {
|
||||
"rooms_with_bath_and_or_shower": 1,
|
||||
"rooms_with_mixer_shower_no_bath": 0,
|
||||
"rooms_with_bath_and_mixer_shower": 0
|
||||
},
|
||||
"secondary_fuel_type": 25,
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 26,
|
||||
"boiler_flue_type": 2,
|
||||
"fan_flue_present": "N",
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": 0,
|
||||
"main_heating_number": 1,
|
||||
"main_heating_control": 2106,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"sap_main_heating_code": 101,
|
||||
"central_heating_pump_age": 0,
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 17507
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 9.8,
|
||||
"sap_windows": [
|
||||
{"orientation": 1, "window_area": 200.1, "window_type": 2, "glazing_type": 1, "window_location": 0},
|
||||
{"orientation": 2, "window_area": 180.2, "window_type": 1, "glazing_type": 2, "window_location": 1}
|
||||
],
|
||||
"schema_type": "RdSAP-Schema-20.0.0",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "EAW",
|
||||
"main_heating": [
|
||||
{"description": "Boiler and radiators, anthracite", "energy_efficiency_rating": 3, "environmental_efficiency_rating": 1},
|
||||
{"description": "Boiler and radiators, mains gas", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"dwelling_type": "Mid-terrace house",
|
||||
"language_code": 1,
|
||||
"property_type": 0,
|
||||
"address_line_1": "1 Some Street",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2020-05-04",
|
||||
"inspection_date": "2020-05-04",
|
||||
"extensions_count": 0,
|
||||
"measurement_type": 1,
|
||||
"sap_flat_details": {
|
||||
"level": 1,
|
||||
"top_storey": "N",
|
||||
"storey_count": 3,
|
||||
"flat_location": 1,
|
||||
"heat_loss_corridor": 2,
|
||||
"unheated_corridor_length": 10
|
||||
},
|
||||
"total_floor_area": 55,
|
||||
"transaction_type": 1,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 5,
|
||||
"registration_date": "2020-05-04",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "Y",
|
||||
"meter_type": 2,
|
||||
"photovoltaic_supply": {
|
||||
"none_or_no_details": {"pv_connection": 0, "percent_roof_area": 50}
|
||||
},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbines_terrain_type": 2
|
||||
},
|
||||
"secondary_heating": {"description": "Room heaters, electric", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0},
|
||||
"lzc_energy_sources": [11],
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"floor_heat_loss": 7,
|
||||
"sap_room_in_roof": {
|
||||
"floor_area": 100,
|
||||
"insulation": "AB",
|
||||
"roof_room_connected": "N",
|
||||
"construction_age_band": "B"
|
||||
},
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.45, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 45.82, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 7.9, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 19.5, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 2,
|
||||
"construction_age_band": "K",
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "N",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "200mm",
|
||||
"wall_insulation_thickness": "NI",
|
||||
"floor_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"low_energy_lighting": 100,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 5,
|
||||
"heating_cost_current": 365.98,
|
||||
"insulated_door_count": 2,
|
||||
"co2_emissions_current": 2.4,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 50,
|
||||
"lighting_cost_current": 123.45,
|
||||
"main_heating_controls": [
|
||||
{"description": "Programmer, room thermostat and TRVs", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
{"description": "Time and temperature zone control", "energy_efficiency_rating": 5, "environmental_efficiency_rating": 5}
|
||||
],
|
||||
"multiple_glazing_type": 2,
|
||||
"open_fireplaces_count": 0,
|
||||
"heating_cost_potential": 250.34,
|
||||
"hot_water_cost_current": 200.4,
|
||||
"insulated_door_u_value": 3,
|
||||
"mechanical_ventilation": 0,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": 360,
|
||||
"indicative_cost": "£100 - £350",
|
||||
"improvement_type": "Z3",
|
||||
"improvement_details": {"improvement_number": 5},
|
||||
"improvement_category": 6,
|
||||
"energy_performance_rating": 50,
|
||||
"environmental_impact_rating": 50
|
||||
},
|
||||
{
|
||||
"sequence": 2,
|
||||
"typical_saving": 99,
|
||||
"indicative_cost": 2000,
|
||||
"improvement_type": "Z2",
|
||||
"improvement_details": {"improvement_number": 1},
|
||||
"improvement_category": 2,
|
||||
"energy_performance_rating": 60,
|
||||
"environmental_impact_rating": 64
|
||||
},
|
||||
{
|
||||
"sequence": 3,
|
||||
"typical_saving": 99,
|
||||
"indicative_cost": 1000,
|
||||
"improvement_type": "Z2",
|
||||
"improvement_details": {
|
||||
"improvement_texts": {
|
||||
"improvement_summary": "An improvement summary",
|
||||
"improvement_description": "An improvement desc"
|
||||
}
|
||||
},
|
||||
"improvement_category": 2,
|
||||
"energy_performance_rating": 60,
|
||||
"environmental_impact_rating": 64
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 1.4,
|
||||
"energy_rating_potential": 72,
|
||||
"lighting_cost_potential": 84.23,
|
||||
"schema_version_original": "SAP-19.0",
|
||||
"hot_water_cost_potential": 180.43,
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 2285,
|
||||
"impact_of_loft_insulation": -2114,
|
||||
"impact_of_cavity_insulation": -122,
|
||||
"impact_of_solid_wall_insulation": -3560,
|
||||
"space_heating_existing_dwelling": 13120
|
||||
},
|
||||
"energy_consumption_current": 230,
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "13.05r16",
|
||||
"energy_consumption_potential": 88,
|
||||
"environmental_impact_current": 52,
|
||||
"fixed_lighting_outlets_count": 16,
|
||||
"windows_transmission_details": {"u_value": 2, "data_source": 2, "solar_transmittance": 0.72},
|
||||
"multiple_glazed_proportion_nr": "NR",
|
||||
"current_energy_efficiency_band": "E",
|
||||
"environmental_impact_potential": 74,
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"co2_emissions_current_per_floor_area": 20,
|
||||
"low_energy_fixed_lighting_outlets_count": 16
|
||||
}
|
||||
245
datatypes/epc/schema/tests/fixtures/21_0_0.json
vendored
Normal file
245
datatypes/epc/schema/tests/fixtures/21_0_0.json
vendored
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{"description": "Pitched, 25 mm loft insulation", "energy_efficiency_rating": 2, "environmental_efficiency_rating": 2},
|
||||
{"description": "Pitched, 250 mm loft insulation", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"walls": [
|
||||
{"description": "Solid brick, as built, no insulation (assumed)", "energy_efficiency_rating": 1, "environmental_efficiency_rating": 1},
|
||||
{"description": "Cavity wall, as built, insulated (assumed)", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"floors": [
|
||||
{"description": "Suspended, no insulation (assumed)", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0},
|
||||
{"description": "Solid, insulated (assumed)", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 1,
|
||||
"window": {"description": "Fully double glazed", "energy_efficiency_rating": 3, "environmental_efficiency_rating": 3},
|
||||
"addendum": {"stone_walls": "true", "system_build": "true", "addendum_numbers": [1, 8]},
|
||||
"lighting": {"description": "Low energy lighting in 50% of fixed outlets", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"postcode": "A0 0AA",
|
||||
"hot_water": {"description": "From main system", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"post_town": "Whitbury",
|
||||
"built_form": 2,
|
||||
"door_count": 3,
|
||||
"region_code": 1,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 1,
|
||||
"shower_outlets": {
|
||||
"shower_outlet": {"shower_wwhrs": 1, "shower_outlet_type": 1}
|
||||
},
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 26,
|
||||
"instantaneous_wwhrs": {"wwhrs_index_number1": 1, "wwhrs_index_number2": 2},
|
||||
"secondary_fuel_type": 25,
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 26,
|
||||
"boiler_flue_type": 2,
|
||||
"fan_flue_present": "N",
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": 0,
|
||||
"main_heating_number": 1,
|
||||
"boiler_ignition_type": 1,
|
||||
"main_heating_control": 2106,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"sap_main_heating_code": 101,
|
||||
"central_heating_pump_age": 0,
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 17507
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 10.2,
|
||||
"sap_windows": [
|
||||
{
|
||||
"pvc_frame": "false",
|
||||
"glazing_gap": 6,
|
||||
"orientation": 1,
|
||||
"window_type": 2,
|
||||
"frame_factor": 1.0,
|
||||
"glazing_type": 14,
|
||||
"window_width": 1.2,
|
||||
"window_height": 2.0,
|
||||
"draught_proofed": "true",
|
||||
"window_location": 0,
|
||||
"window_wall_type": 6,
|
||||
"permanent_shutters_present": "N",
|
||||
"window_transmission_details": {"u_value": 1.0, "data_source": 2, "solar_transmittance": 1.0},
|
||||
"permanent_shutters_insulated": "N"
|
||||
}
|
||||
],
|
||||
"schema_type": "RdSAP-Schema-21.0.0",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "ENG",
|
||||
"main_heating": [
|
||||
{"description": "Boiler and radiators, anthracite", "energy_efficiency_rating": 3, "environmental_efficiency_rating": 1},
|
||||
{"description": "Boiler and radiators, mains gas", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"dwelling_type": "Mid-terrace house",
|
||||
"language_code": 1,
|
||||
"pressure_test": 6,
|
||||
"property_type": 0,
|
||||
"address_line_1": "1 Some Street",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2023-12-01",
|
||||
"inspection_date": "2023-12-01",
|
||||
"wet_rooms_count": 0,
|
||||
"extensions_count": 0,
|
||||
"measurement_type": 1,
|
||||
"sap_flat_details": {
|
||||
"level": 1,
|
||||
"top_storey": "N",
|
||||
"storey_count": 3,
|
||||
"flat_location": 1,
|
||||
"heat_loss_corridor": 2,
|
||||
"unheated_corridor_length": 10
|
||||
},
|
||||
"total_floor_area": 55,
|
||||
"transaction_type": 16,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 5,
|
||||
"registration_date": "2023-12-01",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "Y",
|
||||
"meter_type": 2,
|
||||
"pv_batteries": {"pv_battery": {"battery_capacity": 5}},
|
||||
"pv_connection": 0,
|
||||
"pv_battery_count": 1,
|
||||
"photovoltaic_supply": {"none_or_no_details": {"percent_roof_area": 0}},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbine_details": {"hub_height": 0, "rotor_diameter": 0},
|
||||
"gas_smart_meter_present": "false",
|
||||
"is_dwelling_export_capable": "false",
|
||||
"wind_turbines_terrain_type": 4,
|
||||
"electricity_smart_meter_present": "true"
|
||||
},
|
||||
"secondary_heating": {"description": "Room heaters, electric", "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0},
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"floor_heat_loss": 7,
|
||||
"sap_room_in_roof": {"floor_area": 100, "construction_age_band": "B"},
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.45, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 45.82, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 7.9, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 19.5, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 2,
|
||||
"construction_age_band": "M",
|
||||
"sap_alternative_wall_1": {
|
||||
"wall_area": 10.4,
|
||||
"wall_dry_lined": "N",
|
||||
"wall_construction": 4,
|
||||
"wall_insulation_type": 2,
|
||||
"wall_thickness_measured": "N"
|
||||
},
|
||||
"sap_alternative_wall_2": {
|
||||
"wall_area": 10.8,
|
||||
"wall_dry_lined": "N",
|
||||
"wall_construction": 4,
|
||||
"wall_insulation_type": 2,
|
||||
"wall_thickness_measured": "N"
|
||||
},
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "N",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "200mm",
|
||||
"wall_insulation_thickness": "NI",
|
||||
"floor_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"open_chimneys_count": 1,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 5,
|
||||
"heating_cost_current": 365.98,
|
||||
"insulated_door_count": 2,
|
||||
"co2_emissions_current": 2.4,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 50,
|
||||
"lighting_cost_current": 123.45,
|
||||
"main_heating_controls": [
|
||||
{"description": "Programmer, room thermostat and TRVs", "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
{"description": "Time and temperature zone control", "energy_efficiency_rating": 5, "environmental_efficiency_rating": 5}
|
||||
],
|
||||
"has_hot_water_cylinder": "true",
|
||||
"heating_cost_potential": 250.34,
|
||||
"hot_water_cost_current": 200.4,
|
||||
"insulated_door_u_value": 3,
|
||||
"mechanical_ventilation": 6,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": 360,
|
||||
"indicative_cost": "£100 - £350",
|
||||
"improvement_type": "Z3",
|
||||
"improvement_details": {"improvement_number": 5},
|
||||
"improvement_category": 6,
|
||||
"energy_performance_rating": 50,
|
||||
"environmental_impact_rating": 50
|
||||
},
|
||||
{
|
||||
"sequence": 3,
|
||||
"typical_saving": 99,
|
||||
"indicative_cost": 1000,
|
||||
"improvement_type": "Z2",
|
||||
"improvement_details": {
|
||||
"improvement_texts": {"improvement_description": "Improvement desc"}
|
||||
},
|
||||
"improvement_category": 2,
|
||||
"energy_performance_rating": 60,
|
||||
"environmental_impact_rating": 64
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 1.4,
|
||||
"energy_rating_potential": 72,
|
||||
"lighting_cost_potential": 84.23,
|
||||
"schema_version_original": "SAP-19.0",
|
||||
"hot_water_cost_potential": 180.43,
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 2285,
|
||||
"impact_of_loft_insulation": -2114,
|
||||
"impact_of_cavity_insulation": -122,
|
||||
"impact_of_solid_wall_insulation": -3560,
|
||||
"space_heating_existing_dwelling": 13120
|
||||
},
|
||||
"draughtproofed_door_count": 1,
|
||||
"mechanical_vent_duct_type": 3,
|
||||
"energy_consumption_current": 230,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "13.05r16",
|
||||
"energy_consumption_potential": 88,
|
||||
"environmental_impact_current": 52,
|
||||
"windows_transmission_details": {"u_value": 2, "data_source": 2, "solar_transmittance": 0.72},
|
||||
"cfl_fixed_lighting_bulbs_count": 5,
|
||||
"current_energy_efficiency_band": "E",
|
||||
"environmental_impact_potential": 74,
|
||||
"led_fixed_lighting_bulbs_count": 10,
|
||||
"mechanical_vent_duct_placement": 2,
|
||||
"mechanical_vent_duct_insulation": 2,
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"pressure_test_certificate_number": 0,
|
||||
"mechanical_ventilation_index_number": 12,
|
||||
"co2_emissions_current_per_floor_area": 20,
|
||||
"low_energy_fixed_lighting_bulbs_count": 16,
|
||||
"mechanical_vent_duct_insulation_level": 2,
|
||||
"mechanical_vent_measured_installation": "false",
|
||||
"incandescent_fixed_lighting_bulbs_count": 5
|
||||
}
|
||||
222
datatypes/epc/schema/tests/fixtures/21_0_1.json
vendored
Normal file
222
datatypes/epc/schema/tests/fixtures/21_0_1.json
vendored
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"uprn": 12457,
|
||||
"roofs": [
|
||||
{"description": {"value": "Pitched, 25 mm loft insulation", "language": "1"}, "energy_efficiency_rating": 2, "environmental_efficiency_rating": 2},
|
||||
{"description": {"value": "Pitched, 250 mm loft insulation", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"walls": [
|
||||
{"description": {"value": "Solid brick, as built, no insulation (assumed)", "language": "1"}, "energy_efficiency_rating": 1, "environmental_efficiency_rating": 1},
|
||||
{"description": {"value": "Cavity wall, as built, insulated (assumed)", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"floors": [
|
||||
{"description": {"value": "Suspended, no insulation (assumed)", "language": "1"}, "energy_efficiency_rating": 0, "environmental_efficiency_rating": 0}
|
||||
],
|
||||
"status": "entered",
|
||||
"tenure": 1,
|
||||
"window": {"description": {"value": "Fully double glazed", "language": "1"}, "energy_efficiency_rating": 3, "environmental_efficiency_rating": 3},
|
||||
"addendum": {"stone_walls": "true", "system_build": "true", "addendum_numbers": [1, 13]},
|
||||
"lighting": {"description": {"value": "Low energy lighting in 50% of fixed outlets", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"postcode": "A0 0AA",
|
||||
"hot_water": {"description": {"value": "From main system", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
"post_town": "Whitbury",
|
||||
"built_form": 2,
|
||||
"door_count": 3,
|
||||
"region_code": 1,
|
||||
"report_type": 2,
|
||||
"sap_heating": {
|
||||
"cylinder_size": 1,
|
||||
"shower_outlets": {"shower_outlet": {"shower_wwhrs": 1, "shower_outlet_type": 1}},
|
||||
"water_heating_code": 901,
|
||||
"water_heating_fuel": 26,
|
||||
"instantaneous_wwhrs": {"wwhrs_index_number1": 1, "wwhrs_index_number2": 2},
|
||||
"secondary_fuel_type": 25,
|
||||
"main_heating_details": [
|
||||
{
|
||||
"has_fghrs": "N",
|
||||
"main_fuel_type": 26,
|
||||
"boiler_flue_type": 2,
|
||||
"fan_flue_present": "N",
|
||||
"heat_emitter_type": 1,
|
||||
"emitter_temperature": 0,
|
||||
"main_heating_number": 1,
|
||||
"boiler_ignition_type": 1,
|
||||
"main_heating_control": 2106,
|
||||
"main_heating_category": 2,
|
||||
"main_heating_fraction": 1,
|
||||
"sap_main_heating_code": 101,
|
||||
"central_heating_pump_age": 0,
|
||||
"main_heating_data_source": 1,
|
||||
"main_heating_index_number": 17507
|
||||
}
|
||||
],
|
||||
"immersion_heating_type": "NA",
|
||||
"has_fixed_air_conditioning": "false"
|
||||
},
|
||||
"sap_version": 10.2,
|
||||
"sap_windows": [
|
||||
{
|
||||
"pvc_frame": "false",
|
||||
"glazing_gap": 6,
|
||||
"orientation": 1,
|
||||
"window_type": 2,
|
||||
"frame_factor": 1.0,
|
||||
"glazing_type": 14,
|
||||
"window_width": 1.2,
|
||||
"window_height": 2.0,
|
||||
"draught_proofed": "true",
|
||||
"window_location": 0,
|
||||
"window_wall_type": 6,
|
||||
"permanent_shutters_present": "N",
|
||||
"window_transmission_details": {"u_value": 1.0, "data_source": 2, "solar_transmittance": 1.0},
|
||||
"permanent_shutters_insulated": "N"
|
||||
}
|
||||
],
|
||||
"schema_type": "RdSAP-Schema-21.0.1",
|
||||
"uprn_source": "Energy Assessor",
|
||||
"country_code": "ENG",
|
||||
"main_heating": [
|
||||
{"description": {"value": "Boiler and radiators, anthracite", "language": "1"}, "energy_efficiency_rating": 3, "environmental_efficiency_rating": 1},
|
||||
{"description": {"value": "Boiler and radiators, mains gas", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4}
|
||||
],
|
||||
"dwelling_type": "Mid-terrace house",
|
||||
"language_code": 1,
|
||||
"pressure_test": 6,
|
||||
"property_type": 0,
|
||||
"address_line_1": "1 Some Street",
|
||||
"assessment_type": "RdSAP",
|
||||
"completion_date": "2025-04-04",
|
||||
"inspection_date": "2025-04-04",
|
||||
"wet_rooms_count": 0,
|
||||
"extensions_count": 0,
|
||||
"measurement_type": 1,
|
||||
"sap_flat_details": {
|
||||
"level": 1,
|
||||
"top_storey": "N",
|
||||
"storey_count": 3,
|
||||
"flat_location": 1,
|
||||
"heat_loss_corridor": 2,
|
||||
"unheated_corridor_length": {"value": 10, "quantity": "metres"}
|
||||
},
|
||||
"total_floor_area": 55,
|
||||
"transaction_type": 16,
|
||||
"conservatory_type": 1,
|
||||
"heated_room_count": 5,
|
||||
"registration_date": "2025-04-04",
|
||||
"sap_energy_source": {
|
||||
"mains_gas": "Y",
|
||||
"meter_type": 2,
|
||||
"pv_batteries": {"pv_battery": {"battery_capacity": 5}},
|
||||
"pv_connection": 0,
|
||||
"pv_battery_count": 1,
|
||||
"photovoltaic_supply": {"none_or_no_details": {"percent_roof_area": 0}},
|
||||
"wind_turbines_count": 0,
|
||||
"wind_turbine_details": {"hub_height": 0, "rotor_diameter": 0},
|
||||
"gas_smart_meter_present": "false",
|
||||
"is_dwelling_export_capable": "false",
|
||||
"wind_turbines_terrain_type": 4,
|
||||
"electricity_smart_meter_present": "true"
|
||||
},
|
||||
"secondary_heating": {
|
||||
"description": {"value": "Room heaters, electric", "language": "1"},
|
||||
"energy_efficiency_rating": 0,
|
||||
"environmental_efficiency_rating": 0
|
||||
},
|
||||
"sap_building_parts": [
|
||||
{
|
||||
"identifier": "Main Dwelling",
|
||||
"wall_dry_lined": "N",
|
||||
"floor_heat_loss": 7,
|
||||
"sap_room_in_roof": {"floor_area": 100, "construction_age_band": "B"},
|
||||
"roof_construction": 4,
|
||||
"wall_construction": 4,
|
||||
"building_part_number": 1,
|
||||
"sap_floor_dimensions": [
|
||||
{
|
||||
"floor": 0,
|
||||
"room_height": {"value": 2.45, "quantity": "metres"},
|
||||
"floor_insulation": 1,
|
||||
"total_floor_area": {"value": 45.82, "quantity": "square metres"},
|
||||
"party_wall_length": {"value": 7.9, "quantity": "metres"},
|
||||
"floor_construction": 1,
|
||||
"heat_loss_perimeter": {"value": 19.5, "quantity": "metres"}
|
||||
}
|
||||
],
|
||||
"wall_insulation_type": 2,
|
||||
"construction_age_band": "M",
|
||||
"sap_alternative_wall_1": {"wall_area": 10.4, "wall_dry_lined": "N", "wall_construction": 4, "wall_insulation_type": 2, "wall_thickness_measured": "N"},
|
||||
"sap_alternative_wall_2": {"wall_area": 10.8, "wall_dry_lined": "N", "wall_construction": 4, "wall_insulation_type": 2, "wall_thickness_measured": "N"},
|
||||
"party_wall_construction": 0,
|
||||
"wall_thickness_measured": "N",
|
||||
"roof_insulation_location": 2,
|
||||
"roof_insulation_thickness": "200mm",
|
||||
"wall_insulation_thickness": "NI",
|
||||
"floor_insulation_thickness": "NI"
|
||||
}
|
||||
],
|
||||
"open_chimneys_count": 1,
|
||||
"solar_water_heating": "N",
|
||||
"habitable_room_count": 5,
|
||||
"heating_cost_current": 365.98,
|
||||
"insulated_door_count": 2,
|
||||
"co2_emissions_current": 2.4,
|
||||
"energy_rating_average": 60,
|
||||
"energy_rating_current": 50,
|
||||
"lighting_cost_current": 123.45,
|
||||
"main_heating_controls": [
|
||||
{"description": {"value": "Programmer, room thermostat and TRVs", "language": "1"}, "energy_efficiency_rating": 4, "environmental_efficiency_rating": 4},
|
||||
{"description": {"value": "Time and temperature zone control", "language": "1"}, "energy_efficiency_rating": 5, "environmental_efficiency_rating": 5}
|
||||
],
|
||||
"has_hot_water_cylinder": "true",
|
||||
"heating_cost_potential": 250.34,
|
||||
"hot_water_cost_current": 200.4,
|
||||
"insulated_door_u_value": 3,
|
||||
"mechanical_ventilation": 6,
|
||||
"percent_draughtproofed": 100,
|
||||
"suggested_improvements": [
|
||||
{
|
||||
"sequence": 1,
|
||||
"typical_saving": 139,
|
||||
"indicative_cost": "£220 - £250",
|
||||
"improvement_type": "G",
|
||||
"improvement_details": {"improvement_number": 66},
|
||||
"improvement_category": 5,
|
||||
"energy_performance_rating": 70,
|
||||
"environmental_impact_rating": 70
|
||||
}
|
||||
],
|
||||
"co2_emissions_potential": 1.4,
|
||||
"energy_rating_potential": 72,
|
||||
"lighting_cost_potential": 84.23,
|
||||
"schema_version_original": "SAP-19.0",
|
||||
"hot_water_cost_potential": 180.43,
|
||||
"renewable_heat_incentive": {
|
||||
"water_heating": 2285,
|
||||
"impact_of_loft_insulation": -2114,
|
||||
"impact_of_cavity_insulation": -122,
|
||||
"impact_of_solid_wall_insulation": -3560,
|
||||
"space_heating_existing_dwelling": 13120
|
||||
},
|
||||
"draughtproofed_door_count": 1,
|
||||
"mechanical_vent_duct_type": 3,
|
||||
"energy_consumption_current": 230,
|
||||
"has_fixed_air_conditioning": "false",
|
||||
"multiple_glazed_proportion": 100,
|
||||
"calculation_software_version": "13.05r16",
|
||||
"energy_consumption_potential": 88,
|
||||
"environmental_impact_current": 52,
|
||||
"windows_transmission_details": {"u_value": 2, "data_source": 2, "solar_transmittance": 0.72},
|
||||
"cfl_fixed_lighting_bulbs_count": 5,
|
||||
"current_energy_efficiency_band": "E",
|
||||
"environmental_impact_potential": 74,
|
||||
"led_fixed_lighting_bulbs_count": 10,
|
||||
"mechanical_vent_duct_placement": 2,
|
||||
"mechanical_vent_duct_insulation": 2,
|
||||
"potential_energy_efficiency_band": "C",
|
||||
"pressure_test_certificate_number": 0,
|
||||
"mechanical_ventilation_index_number": 12,
|
||||
"co2_emissions_current_per_floor_area": 20,
|
||||
"low_energy_fixed_lighting_bulbs_count": 16,
|
||||
"mechanical_vent_duct_insulation_level": 2,
|
||||
"mechanical_vent_measured_installation": "false",
|
||||
"incandescent_fixed_lighting_bulbs_count": 0
|
||||
}
|
||||
73
datatypes/epc/schema/tests/helpers.py
Normal file
73
datatypes/epc/schema/tests/helpers.py
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import dataclasses
|
||||
import typing
|
||||
from typing import Any, Dict, Type, TypeVar
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
|
||||
def from_dict(cls: Type[T], data: Dict[str, Any]) -> T:
|
||||
"""
|
||||
Recursively convert a plain dict (e.g. from json.loads) into the given
|
||||
dataclass type, using the field type hints to convert nested structures.
|
||||
|
||||
Handles:
|
||||
- Nested dataclasses
|
||||
- List[SomeDataclass]
|
||||
- Optional[X] / Union[X, None]
|
||||
- Union[DataclassType, primitive] (e.g. Union[Measurement, int])
|
||||
- Primitive pass-through for Union[str, int] etc.
|
||||
"""
|
||||
return _from_dict_impl(cls, data) # type: ignore[return-value]
|
||||
|
||||
|
||||
def _from_dict_impl(cls: Any, data: Any) -> Any:
|
||||
hints = typing.get_type_hints(cls)
|
||||
kwargs: Dict[str, Any] = {}
|
||||
|
||||
for field in dataclasses.fields(cls): # type: ignore[arg-type]
|
||||
has_default = (
|
||||
field.default is not dataclasses.MISSING
|
||||
or field.default_factory is not dataclasses.MISSING # type: ignore[misc]
|
||||
)
|
||||
if field.name not in data:
|
||||
if has_default:
|
||||
continue
|
||||
raise ValueError(f"{cls.__name__}: missing required field '{field.name}'")
|
||||
|
||||
kwargs[field.name] = _coerce(data[field.name], hints[field.name])
|
||||
|
||||
return cls(**kwargs)
|
||||
|
||||
|
||||
def _coerce(value: Any, hint: Any) -> Any:
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
origin = typing.get_origin(hint)
|
||||
args = typing.get_args(hint)
|
||||
|
||||
# Union (includes Optional[X] which is Union[X, None])
|
||||
if origin is typing.Union:
|
||||
if value is None:
|
||||
return None
|
||||
non_none_args = [a for a in args if a is not type(None)]
|
||||
if len(non_none_args) == 1:
|
||||
# Optional[X] — recurse so List[X] and nested dataclasses are handled
|
||||
return _coerce(value, non_none_args[0])
|
||||
# Multi-type Union (e.g. Union[Measurement, int]): try dataclasses first
|
||||
for arg in non_none_args:
|
||||
if dataclasses.is_dataclass(arg) and isinstance(value, dict):
|
||||
return _from_dict_impl(arg, value)
|
||||
# All remaining args are primitives — return value as-is
|
||||
return value
|
||||
|
||||
# List[X]
|
||||
if origin is list:
|
||||
item_hint = args[0]
|
||||
return [_coerce(item, item_hint) for item in value]
|
||||
|
||||
# Plain dataclass
|
||||
if dataclasses.is_dataclass(hint) and isinstance(value, dict):
|
||||
return _from_dict_impl(hint, value)
|
||||
|
||||
return value
|
||||
380
datatypes/epc/schema/tests/test_schema_loading.py
Normal file
380
datatypes/epc/schema/tests/test_schema_loading.py
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
import json
|
||||
import os
|
||||
from typing import Any, Dict
|
||||
|
||||
import pytest
|
||||
|
||||
from datatypes.epc.schema import (
|
||||
RdSapSchema17_0,
|
||||
RdSapSchema17_1,
|
||||
RdSapSchema18_0,
|
||||
RdSapSchema19_0,
|
||||
RdSapSchema20_0_0,
|
||||
RdSapSchema21_0_0,
|
||||
RdSapSchema21_0_1,
|
||||
)
|
||||
from datatypes.epc.schema.common import CostAmount, DescriptionV1, Measurement
|
||||
from datatypes.epc.schema.tests.helpers import from_dict
|
||||
|
||||
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 TestRdSapSchema17_0:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema17_0:
|
||||
return from_dict(RdSapSchema17_0, load("17_0.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-17.0"
|
||||
|
||||
def test_uprn(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.uprn == 12457
|
||||
|
||||
def test_description_is_localised_object(self, epc: RdSapSchema17_0) -> None:
|
||||
assert isinstance(epc.roofs[0].description, DescriptionV1)
|
||||
assert epc.roofs[0].description.value == "(another dwelling above)"
|
||||
assert epc.roofs[0].description.language == "1"
|
||||
|
||||
def test_dwelling_type_is_localised_object(self, epc: RdSapSchema17_0) -> None:
|
||||
assert isinstance(epc.dwelling_type, DescriptionV1)
|
||||
assert epc.dwelling_type.value == "Mid-floor flat"
|
||||
|
||||
def test_costs_are_cost_amount_objects(self, epc: RdSapSchema17_0) -> None:
|
||||
assert isinstance(epc.heating_cost_current, CostAmount)
|
||||
assert epc.heating_cost_current.value == 214
|
||||
assert epc.heating_cost_current.currency == "GBP"
|
||||
|
||||
def test_suggested_improvement_saving_is_cost_amount(self, epc: RdSapSchema17_0) -> None:
|
||||
assert isinstance(epc.suggested_improvements[0].typical_saving, CostAmount)
|
||||
assert epc.suggested_improvements[0].typical_saving.value == 158
|
||||
|
||||
def test_flat_details_populated(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.sap_flat_details is not None
|
||||
assert epc.sap_flat_details.level == 2
|
||||
|
||||
def test_floor_dimensions_use_measurement(self, epc: RdSapSchema17_0) -> None:
|
||||
dim = epc.sap_building_parts[0].sap_floor_dimensions[0]
|
||||
assert isinstance(dim.room_height, Measurement)
|
||||
assert dim.room_height.value == 2.4
|
||||
assert dim.room_height.quantity == "metres"
|
||||
|
||||
def test_alternative_improvements_present(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.alternative_improvements is not None
|
||||
assert len(epc.alternative_improvements) == 1
|
||||
assert epc.alternative_improvements[0].improvement_type == "J2"
|
||||
|
||||
def test_renewable_heat_incentive(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.renewable_heat_incentive.water_heating == 4818
|
||||
assert epc.renewable_heat_incentive.space_heating_existing_dwelling == 2415
|
||||
assert epc.renewable_heat_incentive.impact_of_loft_insulation is None
|
||||
|
||||
def test_glazing_gap_is_string(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.glazing_gap == "16+"
|
||||
|
||||
def test_lzc_energy_sources(self, epc: RdSapSchema17_0) -> None:
|
||||
assert epc.lzc_energy_sources == [11]
|
||||
|
||||
|
||||
class TestRdSapSchema17_1:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema17_1:
|
||||
return from_dict(RdSapSchema17_1, load("17_1.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema17_1) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-17.1"
|
||||
|
||||
def test_description_is_localised_object(self, epc: RdSapSchema17_1) -> None:
|
||||
assert isinstance(epc.roofs[0].description, DescriptionV1)
|
||||
assert epc.roofs[0].description.value == "Pitched, 100 mm loft insulation"
|
||||
|
||||
def test_address_line_2(self, epc: RdSapSchema17_1) -> None:
|
||||
assert epc.address_line_2 == "Lower Moria"
|
||||
|
||||
def test_cylinder_thermostat(self, epc: RdSapSchema17_1) -> None:
|
||||
assert epc.sap_heating.cylinder_thermostat == "Y"
|
||||
|
||||
def test_cylinder_insulation_thickness(self, epc: RdSapSchema17_1) -> None:
|
||||
assert epc.sap_heating.cylinder_insulation_thickness == 12
|
||||
|
||||
def test_boiler_flue_type_in_heating_detail(self, epc: RdSapSchema17_1) -> None:
|
||||
detail = epc.sap_heating.main_heating_details[0]
|
||||
assert detail.boiler_flue_type == 1
|
||||
assert detail.main_heating_index_number == 9049
|
||||
|
||||
def test_extension_party_wall_length_is_int(self, epc: RdSapSchema17_1) -> None:
|
||||
# Extension floor dimension has party_wall_length as a plain int (0)
|
||||
extension = epc.sap_building_parts[1]
|
||||
assert extension.identifier == "Extension 1"
|
||||
dim = extension.sap_floor_dimensions[0]
|
||||
assert dim.party_wall_length == 0
|
||||
|
||||
def test_extension_roof_insulation_thickness_is_int(self, epc: RdSapSchema17_1) -> None:
|
||||
extension = epc.sap_building_parts[1]
|
||||
assert extension.roof_insulation_thickness == 0
|
||||
|
||||
def test_renewable_heat_incentive_has_loft_impact(self, epc: RdSapSchema17_1) -> None:
|
||||
assert epc.renewable_heat_incentive.impact_of_loft_insulation == -565
|
||||
|
||||
def test_multiple_roofs(self, epc: RdSapSchema17_1) -> None:
|
||||
assert len(epc.roofs) == 2
|
||||
|
||||
|
||||
class TestRdSapSchema18_0:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema18_0:
|
||||
return from_dict(RdSapSchema18_0, load("18_0.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema18_0) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-18.0"
|
||||
|
||||
def test_glazing_gap_is_integer(self, epc: RdSapSchema18_0) -> None:
|
||||
assert epc.glazing_gap == 12
|
||||
assert isinstance(epc.glazing_gap, int)
|
||||
|
||||
def test_room_in_roof_present(self, epc: RdSapSchema18_0) -> None:
|
||||
main = epc.sap_building_parts[0]
|
||||
assert main.sap_room_in_roof is not None
|
||||
assert main.sap_room_in_roof.insulation == "AB"
|
||||
assert main.sap_room_in_roof.construction_age_band == "G"
|
||||
|
||||
def test_room_in_roof_floor_area_is_measurement(self, epc: RdSapSchema18_0) -> None:
|
||||
room_in_roof = epc.sap_building_parts[0].sap_room_in_roof
|
||||
assert room_in_roof is not None
|
||||
assert isinstance(room_in_roof.floor_area, Measurement)
|
||||
assert room_in_roof.floor_area.value == 9.0
|
||||
assert room_in_roof.floor_area.quantity == "square metres"
|
||||
|
||||
def test_flat_roof_insulation_on_extension(self, epc: RdSapSchema18_0) -> None:
|
||||
extension = epc.sap_building_parts[1]
|
||||
assert extension.flat_roof_insulation_thickness == "NI"
|
||||
|
||||
def test_description_is_localised_object(self, epc: RdSapSchema18_0) -> None:
|
||||
assert isinstance(epc.walls[0].description, DescriptionV1)
|
||||
|
||||
def test_three_roofs(self, epc: RdSapSchema18_0) -> None:
|
||||
assert len(epc.roofs) == 3
|
||||
|
||||
def test_renewable_heat_incentive_has_solid_wall_impact(self, epc: RdSapSchema18_0) -> None:
|
||||
assert epc.renewable_heat_incentive.impact_of_solid_wall_insulation == -1864
|
||||
|
||||
|
||||
class TestRdSapSchema19_0:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema19_0:
|
||||
return from_dict(RdSapSchema19_0, load("19_0.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema19_0) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-19.0"
|
||||
|
||||
def test_windows_transmission_details(self, epc: RdSapSchema19_0) -> None:
|
||||
wtd = epc.windows_transmission_details
|
||||
assert wtd.u_value == 3.1
|
||||
assert wtd.data_source == 2
|
||||
assert wtd.solar_transmittance == 0.76
|
||||
|
||||
def test_description_is_localised_object(self, epc: RdSapSchema19_0) -> None:
|
||||
assert isinstance(epc.roofs[0].description, DescriptionV1)
|
||||
assert epc.roofs[0].description.value == "Pitched, 150 mm loft insulation"
|
||||
|
||||
def test_glazing_gap_absent(self, epc: RdSapSchema19_0) -> None:
|
||||
assert epc.glazing_gap is None
|
||||
|
||||
def test_secondary_heating_type(self, epc: RdSapSchema19_0) -> None:
|
||||
assert epc.sap_heating.secondary_heating_type == 631
|
||||
|
||||
def test_multiple_lzc_sources(self, epc: RdSapSchema19_0) -> None:
|
||||
assert epc.lzc_energy_sources == [11, 9]
|
||||
|
||||
def test_floor_insulation_thickness_on_building_part(self, epc: RdSapSchema19_0) -> None:
|
||||
assert epc.sap_building_parts[0].floor_insulation_thickness == "NI"
|
||||
|
||||
|
||||
class TestRdSapSchema20_0_0:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema20_0_0:
|
||||
return from_dict(RdSapSchema20_0_0, load("20_0_0.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-20.0.0"
|
||||
|
||||
def test_description_is_plain_string(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert isinstance(epc.roofs[0].description, str)
|
||||
assert epc.roofs[0].description == "Pitched, 25 mm loft insulation"
|
||||
|
||||
def test_dwelling_type_is_plain_string(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert isinstance(epc.dwelling_type, str)
|
||||
assert epc.dwelling_type == "Mid-terrace house"
|
||||
|
||||
def test_costs_are_floats(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert isinstance(epc.heating_cost_current, float)
|
||||
assert epc.heating_cost_current == pytest.approx(365.98)
|
||||
|
||||
def test_suggested_improvement_saving_is_numeric(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.suggested_improvements[0].typical_saving == 360
|
||||
|
||||
def test_indicative_cost_can_be_int(self, epc: RdSapSchema20_0_0) -> None:
|
||||
# Second improvement has indicative_cost as a plain integer
|
||||
assert epc.suggested_improvements[1].indicative_cost == 2000
|
||||
|
||||
def test_improvement_details_with_texts(self, epc: RdSapSchema20_0_0) -> None:
|
||||
# Third improvement uses improvement_texts instead of improvement_number
|
||||
third = epc.suggested_improvements[2]
|
||||
assert third.improvement_details.improvement_number is None
|
||||
assert third.improvement_details.improvement_texts is not None
|
||||
assert third.improvement_details.improvement_texts.improvement_summary == "An improvement summary"
|
||||
|
||||
def test_sap_windows_present(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert len(epc.sap_windows) == 2
|
||||
assert epc.sap_windows[0].window_area == pytest.approx(200.1)
|
||||
assert epc.sap_windows[0].glazing_type == 1
|
||||
|
||||
def test_addendum(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.addendum is not None
|
||||
assert epc.addendum.stone_walls == "true"
|
||||
assert epc.addendum.addendum_numbers == [1, 8]
|
||||
|
||||
def test_flat_details_has_storey_count(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.sap_flat_details is not None
|
||||
assert epc.sap_flat_details.storey_count == 3
|
||||
assert epc.sap_flat_details.unheated_corridor_length == 10
|
||||
|
||||
def test_room_in_roof_floor_area_is_plain_number(self, epc: RdSapSchema20_0_0) -> None:
|
||||
room_in_roof = epc.sap_building_parts[0].sap_room_in_roof
|
||||
assert room_in_roof is not None
|
||||
assert room_in_roof.floor_area == 100
|
||||
assert not isinstance(room_in_roof.floor_area, Measurement)
|
||||
|
||||
def test_renewable_heat_incentive_has_cavity_impact(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.renewable_heat_incentive.impact_of_cavity_insulation == -122
|
||||
|
||||
def test_multiple_glazed_proportion_nr(self, epc: RdSapSchema20_0_0) -> None:
|
||||
assert epc.multiple_glazed_proportion_nr == "NR"
|
||||
|
||||
|
||||
class TestRdSapSchema21_0_0:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema21_0_0:
|
||||
return from_dict(RdSapSchema21_0_0, load("21_0_0.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-21.0.0"
|
||||
|
||||
def test_description_is_plain_string(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert isinstance(epc.roofs[0].description, str)
|
||||
|
||||
def test_pressure_test(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.pressure_test == 6
|
||||
|
||||
def test_wet_rooms_count(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.wet_rooms_count == 0
|
||||
|
||||
def test_instantaneous_wwhrs_uses_index_numbers(self, epc: RdSapSchema21_0_0) -> None:
|
||||
wwhrs = epc.sap_heating.instantaneous_wwhrs
|
||||
assert wwhrs.wwhrs_index_number1 == 1
|
||||
assert wwhrs.wwhrs_index_number2 == 2
|
||||
|
||||
def test_shower_outlets(self, epc: RdSapSchema21_0_0) -> None:
|
||||
outlets = epc.sap_heating.shower_outlets
|
||||
assert outlets is not None
|
||||
assert outlets.shower_outlet.shower_wwhrs == 1
|
||||
assert outlets.shower_outlet.shower_outlet_type == 1
|
||||
|
||||
def test_boiler_ignition_type(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.sap_heating.main_heating_details[0].boiler_ignition_type == 1
|
||||
|
||||
def test_smart_meters(self, epc: RdSapSchema21_0_0) -> None:
|
||||
src = epc.sap_energy_source
|
||||
assert src.electricity_smart_meter_present == "true"
|
||||
assert src.gas_smart_meter_present == "false"
|
||||
|
||||
def test_pv_batteries(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.sap_energy_source.pv_batteries is not None
|
||||
assert epc.sap_energy_source.pv_batteries.pv_battery.battery_capacity == 5
|
||||
|
||||
def test_alternative_walls(self, epc: RdSapSchema21_0_0) -> None:
|
||||
part = epc.sap_building_parts[0]
|
||||
assert part.sap_alternative_wall_1 is not None
|
||||
assert part.sap_alternative_wall_1.wall_area == pytest.approx(10.4)
|
||||
assert part.sap_alternative_wall_2 is not None
|
||||
assert part.sap_alternative_wall_2.wall_area == pytest.approx(10.8)
|
||||
|
||||
def test_detailed_sap_windows(self, epc: RdSapSchema21_0_0) -> None:
|
||||
win = epc.sap_windows[0]
|
||||
assert win.glazing_gap == 6
|
||||
assert win.window_width == pytest.approx(1.2)
|
||||
assert win.window_transmission_details.u_value == pytest.approx(1.0)
|
||||
|
||||
def test_mechanical_vent_fields(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.mechanical_vent_duct_type == 3
|
||||
assert epc.mechanical_ventilation_index_number == 12
|
||||
|
||||
def test_lighting_bulb_counts(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.led_fixed_lighting_bulbs_count == 10
|
||||
assert epc.cfl_fixed_lighting_bulbs_count == 5
|
||||
assert epc.incandescent_fixed_lighting_bulbs_count == 5
|
||||
|
||||
def test_open_chimneys_count(self, epc: RdSapSchema21_0_0) -> None:
|
||||
assert epc.open_chimneys_count == 1
|
||||
|
||||
def test_room_in_roof_has_no_insulation_field(self, epc: RdSapSchema21_0_0) -> None:
|
||||
room_in_roof = epc.sap_building_parts[0].sap_room_in_roof
|
||||
assert room_in_roof is not None
|
||||
assert room_in_roof.construction_age_band == "B"
|
||||
assert not hasattr(room_in_roof, "insulation")
|
||||
|
||||
|
||||
class TestRdSapSchema21_0_1:
|
||||
|
||||
@pytest.fixture
|
||||
def epc(self) -> RdSapSchema21_0_1:
|
||||
return from_dict(RdSapSchema21_0_1, load("21_0_1.json"))
|
||||
|
||||
def test_schema_type(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert epc.schema_type == "RdSAP-Schema-21.0.1"
|
||||
|
||||
def test_description_reverts_to_localised_object(self, epc: RdSapSchema21_0_1) -> None:
|
||||
# Descriptions on energy elements revert to DescriptionV1 in 21.0.1
|
||||
assert isinstance(epc.roofs[0].description, DescriptionV1)
|
||||
assert epc.roofs[0].description.value == "Pitched, 25 mm loft insulation"
|
||||
|
||||
def test_main_heating_description_is_localised_object(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert isinstance(epc.main_heating[0].description, DescriptionV1)
|
||||
assert epc.main_heating[0].description.value == "Boiler and radiators, anthracite"
|
||||
|
||||
def test_dwelling_type_remains_plain_string(self, epc: RdSapSchema21_0_1) -> None:
|
||||
# dwelling_type does NOT revert — stays as plain str in 21.0.1
|
||||
assert isinstance(epc.dwelling_type, str)
|
||||
assert epc.dwelling_type == "Mid-terrace house"
|
||||
|
||||
def test_unheated_corridor_length_is_measurement(self, epc: RdSapSchema21_0_1) -> None:
|
||||
# Changed from plain int (21.0.0) to Measurement object in 21.0.1
|
||||
assert epc.sap_flat_details is not None
|
||||
corridor_length = epc.sap_flat_details.unheated_corridor_length
|
||||
assert isinstance(corridor_length, Measurement)
|
||||
assert corridor_length.value == 10
|
||||
assert corridor_length.quantity == "metres"
|
||||
|
||||
def test_completion_date(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert epc.completion_date == "2025-04-04"
|
||||
|
||||
def test_addendum_numbers(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert epc.addendum is not None
|
||||
assert epc.addendum.addendum_numbers == [1, 13]
|
||||
|
||||
def test_pv_battery_capacity(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert epc.sap_energy_source.pv_batteries is not None
|
||||
assert epc.sap_energy_source.pv_batteries.pv_battery.battery_capacity == 5
|
||||
|
||||
def test_incandescent_bulb_count(self, epc: RdSapSchema21_0_1) -> None:
|
||||
assert epc.incandescent_fixed_lighting_bulbs_count == 0
|
||||
|
|
@ -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
|
||||
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
|
||||
markers =
|
||||
integration: mark a test as an integration test
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue