From 13a6a213fb318b1bbbbddd34f20c3050c37d3945 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Tue, 30 Jun 2026 17:18:51 +0000 Subject: [PATCH] =?UTF-8?q?Treat=20a=20same-family=20fuel=20refinement=20a?= =?UTF-8?q?s=20consistent,=20not=20a=20mismatch=20=F0=9F=9F=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../property/landlord_override_overlays.py | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/repositories/property/landlord_override_overlays.py b/repositories/property/landlord_override_overlays.py index 5f47a3b39..29ebcea00 100644 --- a/repositories/property/landlord_override_overlays.py +++ b/repositories/property/landlord_override_overlays.py @@ -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)",