Treat a same-family fuel refinement as consistent, not a mismatch 🟩

Compare fuel families (not exact codes), so a solid-fuel room heater refined to
smokeless/dual/biomass is consistent; only a different family (gas/electric on a
solid heater) is logged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-30 17:18:51 +00:00
parent 27f6b8e9ae
commit 13a6a213fb

View file

@ -96,6 +96,20 @@ def overlays_from(overrides: ResolvedPropertyOverrides) -> list[EpcSimulation]:
return overlays
# Coarse fuel family per RdSAP `main_fuel` code (main_fuel_overlay._FUEL_CODES),
# for the plausibility check. The natural fuel a solid-fuel archetype drags
# (house coal) is a *default* across the ambiguous solid family, so a same-family
# override (smokeless / dual fuel / biomass) is a refinement, not a contradiction
# — only a different family (gas/electric on a solid heater) is flagged.
_FUEL_FAMILY: dict[int, str] = {
26: "gas", 20: "gas",
27: "lpg", 3: "lpg", 17: "lpg",
28: "oil",
29: "electricity", 25: "electricity",
33: "solid", 15: "solid", 10: "solid", 31: "solid",
}
def _override_value(overrides: ResolvedPropertyOverrides, component: str) -> Optional[str]:
for row in overrides.rows:
if row.override_component == component:
@ -119,9 +133,13 @@ def flag_fuel_mismatch(overrides: ResolvedPropertyOverrides) -> None:
if fuel_overlay is not None and fuel_overlay.heating is not None
else None
)
if natural is None or override_fuel is None:
if natural is None or not isinstance(override_fuel, int):
return
if natural != override_fuel:
natural_family = _FUEL_FAMILY.get(natural)
override_family = _FUEL_FAMILY.get(override_fuel)
if natural_family is None or override_family is None:
return
if natural_family != override_family:
logger.warning(
"Landlord main_fuel %r contradicts the natural fuel of heating "
"system %r (override is honoured; flagged for review)",