From e8b6f19a3a9e389e7b85b0d112ead96a01e832fa Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Sun, 17 May 2026 12:25:59 +0000 Subject: [PATCH] fix(16d): predicted_lighting_kwh handles None bulb counts EPC bulb-count fields are Optional[int]; 1k-cert sanity-check from slice 16h hit None + None TypeError. Coerce to 0 before sum. --- packages/domain/src/domain/ml/demand.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/domain/src/domain/ml/demand.py b/packages/domain/src/domain/ml/demand.py index 7a4810ba..c8b2c1f3 100644 --- a/packages/domain/src/domain/ml/demand.py +++ b/packages/domain/src/domain/ml/demand.py @@ -120,19 +120,23 @@ def predicted_hot_water_kwh( def predicted_lighting_kwh( total_floor_area_m2: Optional[float], - cfl_count: int, - led_count: int, - incandescent_count: int, + cfl_count: Optional[int], + led_count: Optional[int], + incandescent_count: Optional[int], ) -> float: """Annual lighting kWh (SAP10.2 Section L simplified). Base demand ~ 9.3 * TFA kWh/yr; reduced by low-energy bulb share. LED bulbs cut consumption by ~50%, CFL by ~40%, incandescent by 0%. + Missing counts treated as zero. """ if total_floor_area_m2 is None or total_floor_area_m2 <= 0: return 0.0 - total_bulbs = max(1, cfl_count + led_count + incandescent_count) - led_share = led_count / total_bulbs - cfl_share = cfl_count / total_bulbs + cfl = cfl_count or 0 + led = led_count or 0 + inc = incandescent_count or 0 + total_bulbs = max(1, cfl + led + inc) + led_share = led / total_bulbs + cfl_share = cfl / total_bulbs reduction = 0.5 * led_share + 0.4 * cfl_share return 9.3 * total_floor_area_m2 * (1.0 - reduction)