mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Resolve a historic EPC's stable attributes into cohort code spaces 🟩
property_type/built_form reuse the override code mapping; wall material prefix -> RdSAP wall_construction; E&W age-band strings -> Table S1 letters; main_fuel display text (stripping " (not community)") -> modern RdSAP-20/21 codes; TFA -> float. Unresolvable -> None (filter inactive). Roof construction is deferred: its RdSAP code table isn't pinned in-repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
992950bd9f
commit
bbfcf1385b
1 changed files with 86 additions and 6 deletions
|
|
@ -17,6 +17,68 @@ from dataclasses import dataclass
|
|||
from typing import Optional
|
||||
|
||||
from datatypes.epc.domain.historic_epc import HistoricEpc
|
||||
from domain.epc.property_overrides.override_code_mapping import (
|
||||
built_form_to_code,
|
||||
property_type_to_code,
|
||||
)
|
||||
|
||||
# RdSAP `wall_construction` codes by material prefix — the same table
|
||||
# `wall_type_overlay.py` pins (source: domain/sap10_ml/rdsap_uvalues.py).
|
||||
# The historic description's material is everything before the first comma.
|
||||
_WALL_MATERIAL_CONSTRUCTION: dict[str, int] = {
|
||||
"Granite or whin": 1,
|
||||
"Sandstone": 2,
|
||||
"Solid brick": 3,
|
||||
"Cavity wall": 4,
|
||||
"Timber frame": 5,
|
||||
"System built": 6,
|
||||
"Cob": 7,
|
||||
"Park home wall": 8,
|
||||
}
|
||||
|
||||
# RdSAP Table S1 band letters — the code space cohort building parts carry
|
||||
# (`sap_building_parts[].construction_age_band` is "A".."M" from the API).
|
||||
# The old register lodged the full England-and-Wales display strings; a
|
||||
# pre-2012 cert cannot carry the post-2012 bands, but they cost nothing.
|
||||
_AGE_BAND_LETTERS: dict[str, str] = {
|
||||
"England and Wales: before 1900": "A",
|
||||
"England and Wales: 1900-1929": "B",
|
||||
"England and Wales: 1930-1949": "C",
|
||||
"England and Wales: 1950-1966": "D",
|
||||
"England and Wales: 1967-1975": "E",
|
||||
"England and Wales: 1976-1982": "F",
|
||||
"England and Wales: 1983-1990": "G",
|
||||
"England and Wales: 1991-1995": "H",
|
||||
"England and Wales: 1996-2002": "I",
|
||||
"England and Wales: 2003-2006": "J",
|
||||
"England and Wales: 2007 onwards": "K",
|
||||
"England and Wales: 2007-2011": "K",
|
||||
"England and Wales: 2012-2022": "L",
|
||||
"England and Wales: 2023 onwards": "M",
|
||||
}
|
||||
|
||||
# Modern RdSAP-20/21 `main_fuel` codes (epc_codes.csv), keyed by the base fuel
|
||||
# description — the same family `main_fuel_overlay.py` pins. The old register
|
||||
# suffixes private fuels with " (not community)", stripped before lookup.
|
||||
_FUEL_CODES: dict[str, int] = {
|
||||
"mains gas": 26,
|
||||
"mains gas (community)": 20,
|
||||
"LPG": 27,
|
||||
"bottled LPG": 3,
|
||||
"LPG special condition": 17,
|
||||
"oil": 28,
|
||||
"electricity": 29,
|
||||
"electricity (community)": 25,
|
||||
"house coal": 33,
|
||||
"smokeless coal": 15,
|
||||
"dual fuel (mineral and wood)": 10,
|
||||
"wood logs": 6,
|
||||
"bulk wood pellets": 7,
|
||||
"wood chips": 8,
|
||||
"biomass (community)": 31,
|
||||
}
|
||||
|
||||
_NOT_COMMUNITY_SUFFIX = " (not community)"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
@ -32,12 +94,30 @@ class HistoricConditioning:
|
|||
total_floor_area_m2: Optional[float]
|
||||
|
||||
|
||||
def _wall_construction(description: str) -> Optional[int]:
|
||||
material = description.split(",", 1)[0].strip()
|
||||
return _WALL_MATERIAL_CONSTRUCTION.get(material)
|
||||
|
||||
|
||||
def _main_fuel(description: str) -> Optional[int]:
|
||||
base = description.strip().removesuffix(_NOT_COMMUNITY_SUFFIX)
|
||||
return _FUEL_CODES.get(base)
|
||||
|
||||
|
||||
def _floor_area(raw: str) -> Optional[float]:
|
||||
try:
|
||||
area = float(raw)
|
||||
except ValueError:
|
||||
return None
|
||||
return area if area > 0 else None
|
||||
|
||||
|
||||
def conditioning_from_historic(record: HistoricEpc) -> HistoricConditioning:
|
||||
return HistoricConditioning(
|
||||
property_type=None,
|
||||
built_form=None,
|
||||
wall_construction=None,
|
||||
construction_age_band=None,
|
||||
main_fuel=None,
|
||||
total_floor_area_m2=None,
|
||||
property_type=property_type_to_code(record.property_type),
|
||||
built_form=built_form_to_code(record.built_form),
|
||||
wall_construction=_wall_construction(record.walls_description),
|
||||
construction_age_band=_AGE_BAND_LETTERS.get(record.construction_age_band),
|
||||
main_fuel=_main_fuel(record.main_fuel),
|
||||
total_floor_area_m2=_floor_area(record.total_floor_area),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue