Model/domain/epc/property_overlays/main_fuel_overlay.py
Jun-te Kim 21bb55f414 Decode bottled/special LPG, community electric/biomass, dual-fuel, smokeless coal 🟩
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 14:18:55 +00:00

41 lines
1.4 KiB
Python

"""Map a Landlord-Override main-fuel value to a heating Simulation Overlay.
A main-fuel value is one canonical gov-EPC `main_fuel` description ("mains gas",
"electricity", …). The calculator reads the dwelling's primary fuel from
`main_heating_details[0].main_fuel_type` as the RdSAP **int code**, so the
overlay decomposes the value into that code and emits a whole-dwelling
`HeatingOverlay` (fuel is not a per-building-part attribute, so `building_part`
is ignored). Codes follow the modern RdSAP-20/21 `(not community)` family the
gov-EPC API baseline uses. Unresolvable values produce no overlay.
"""
from __future__ import annotations
from typing import Optional
from domain.modelling.simulation import EpcSimulation, HeatingOverlay
# RdSAP-20/21 `main_fuel` `(not community)` codes (epc_codes.csv `main_fuel`).
_FUEL_CODES: dict[str, int] = {
"mains gas": 26,
"mains gas (community)": 20,
"LPG (bulk)": 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,
"biomass (community)": 31,
}
def fuel_overlay_for(
main_fuel_value: str, building_part: int
) -> Optional[EpcSimulation]:
code = _FUEL_CODES.get(main_fuel_value)
if code is None:
return None
return EpcSimulation(heating=HeatingOverlay(main_fuel_type=code))