mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-30 13:10:47 +00:00
Parse and map all RdSAP-Schema-18.0 corpus certs 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
024f3926af
commit
51309328e6
2 changed files with 52 additions and 32 deletions
|
|
@ -747,7 +747,12 @@ class EpcPropertyDataMapper:
|
|||
uprn=schema.uprn,
|
||||
assessment_type=schema.assessment_type,
|
||||
sap_version=schema.sap_version,
|
||||
dwelling_type=schema.dwelling_type.value,
|
||||
# ADR-0028: 18.0 lodges dwelling_type as str OR localised dict.
|
||||
dwelling_type=(
|
||||
schema.dwelling_type
|
||||
if isinstance(schema.dwelling_type, str)
|
||||
else schema.dwelling_type.value
|
||||
),
|
||||
property_type=str(schema.property_type),
|
||||
built_form=str(schema.built_form),
|
||||
address_line_1=schema.address_line_1,
|
||||
|
|
@ -842,6 +847,7 @@ class EpcPropertyDataMapper:
|
|||
)
|
||||
)
|
||||
if es.photovoltaic_supply
|
||||
and es.photovoltaic_supply.none_or_no_details
|
||||
else None
|
||||
),
|
||||
),
|
||||
|
|
@ -895,7 +901,7 @@ class EpcPropertyDataMapper:
|
|||
),
|
||||
sap_room_in_roof=(
|
||||
SapRoomInRoof(
|
||||
floor_area=bp.sap_room_in_roof.floor_area.value,
|
||||
floor_area=_measurement_value(bp.sap_room_in_roof.floor_area),
|
||||
construction_age_band=bp.sap_room_in_roof.construction_age_band,
|
||||
)
|
||||
if bp.sap_room_in_roof
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class PhotovoltaicSupplyNoneOrNoDetails:
|
|||
|
||||
@dataclass
|
||||
class PhotovoltaicSupply:
|
||||
none_or_no_details: PhotovoltaicSupplyNoneOrNoDetails
|
||||
none_or_no_details: Optional[PhotovoltaicSupplyNoneOrNoDetails] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -85,30 +85,38 @@ class SapFloorDimension:
|
|||
|
||||
@dataclass
|
||||
class SapRoomInRoof:
|
||||
"""Room-in-roof details. floor_area is a Measurement object in schema 18.0."""
|
||||
"""Room-in-roof details. floor_area is usually a Measurement object in 18.0,
|
||||
but 6/1000 certs lodge it as a plain number (ADR-0028) — read via
|
||||
`_measurement_value`, which coerces both shapes."""
|
||||
|
||||
floor_area: Measurement
|
||||
floor_area: Union[Measurement, int, float]
|
||||
insulation: str
|
||||
roof_room_connected: str
|
||||
construction_age_band: str
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(kw_only=True)
|
||||
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]
|
||||
# Data-driven required→optional (ADR-0028): 17/1000 certs lodge a
|
||||
# conservatory-shaped part carrying only {double_glazed, floor_area,
|
||||
# glazed_perimeter, room_height} — none of the construction fields. Every
|
||||
# field is Optional (the 21.0.1/20.0.0 precedent); the all-None part flows
|
||||
# through harmlessly because the conservatory's effect is carried separately
|
||||
# by conservatory_type.
|
||||
identifier: Optional[str] = None
|
||||
wall_dry_lined: Optional[str] = None
|
||||
wall_thickness: Optional[int] = None
|
||||
floor_heat_loss: Optional[int] = None
|
||||
roof_construction: Optional[int] = None
|
||||
wall_construction: Optional[int] = None
|
||||
building_part_number: Optional[int] = None
|
||||
sap_floor_dimensions: Optional[List[SapFloorDimension]] = None
|
||||
wall_insulation_type: Optional[int] = None
|
||||
construction_age_band: Optional[str] = None
|
||||
party_wall_construction: Optional[Union[int, str]] = None
|
||||
wall_thickness_measured: Optional[str] = None
|
||||
roof_insulation_location: Optional[Union[int, str]] = None
|
||||
roof_insulation_thickness: Optional[Union[str, int]] = None
|
||||
sap_room_in_roof: Optional[SapRoomInRoof] = None
|
||||
wall_insulation_thickness: Optional[str] = None
|
||||
floor_insulation_thickness: Optional[str] = None
|
||||
|
|
@ -140,15 +148,18 @@ class SuggestedImprovement:
|
|||
environmental_impact_rating: int
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(kw_only=True)
|
||||
class AlternativeImprovement:
|
||||
sequence: int
|
||||
typical_saving: CostAmount
|
||||
improvement_type: str
|
||||
improvement_details: ImprovementDetails
|
||||
improvement_category: int
|
||||
energy_performance_rating: int
|
||||
environmental_impact_rating: int
|
||||
# ADR-0028: 165/1000 lodge a reduced alternative-improvement shape (only
|
||||
# improvement_details/-type). Parse-only — the mapper does not read
|
||||
# alternative_improvements — so every field is Optional.
|
||||
sequence: Optional[int] = None
|
||||
typical_saving: Optional[CostAmount] = None
|
||||
improvement_type: Optional[str] = None
|
||||
improvement_details: Optional[ImprovementDetails] = None
|
||||
improvement_category: Optional[int] = None
|
||||
energy_performance_rating: Optional[int] = None
|
||||
environmental_impact_rating: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -175,8 +186,9 @@ class RdSapSchema18_0:
|
|||
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
|
||||
# ADR-0028: glazing_gap is lodged as int (e.g. 12 mm), str ("16+"), or
|
||||
# omitted across the corpus (433/1000) — widen + default, not int-required.
|
||||
glazing_gap: Optional[Union[int, str]] = None
|
||||
region_code: int
|
||||
report_type: int
|
||||
sap_heating: SapHeating
|
||||
|
|
@ -185,7 +197,9 @@ class RdSapSchema18_0:
|
|||
uprn_source: str
|
||||
country_code: str
|
||||
main_heating: List[EnergyElement]
|
||||
dwelling_type: DescriptionV1
|
||||
# ADR-0028: 392/1000 lodge dwelling_type as a plain str, not a localised
|
||||
# DescriptionV1 object (matches 20.0.0). Widen so both shapes parse.
|
||||
dwelling_type: Union[str, DescriptionV1]
|
||||
language_code: int
|
||||
property_type: int
|
||||
address_line_1: str
|
||||
|
|
@ -198,7 +212,7 @@ class RdSapSchema18_0:
|
|||
transaction_type: int
|
||||
conservatory_type: int
|
||||
heated_room_count: int
|
||||
pvc_window_frames: str
|
||||
pvc_window_frames: Optional[str] = None
|
||||
registration_date: str
|
||||
sap_energy_source: SapEnergySource
|
||||
secondary_heating: EnergyElement
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue