mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Normalize RdSAP lighting mapping on the degraded 17.0/19.0 paths
PRD #1385, lighting family. The 17.0 and 19.0 API mappers hardcoded every fixed-lighting bulb count to 0, dropping the lodged lighting mix that the reference-complete 17.1/18.0/20.0 paths read. The schema lodges total + low-energy OUTLET counts (ADR-0028); mirror the reference split — low-energy outlets → low_energy bulbs, the remainder → incandescent — so the SAP lighting-energy calc sees the real low-energy credit instead of assuming none. led/cfl stay 0 (reduced-field certs don't split those); 21.0.x use a different bulb-based lighting schema and are out of scope. The `total - low_energy` subtraction is safe: all 37 local 17.0/19.0 fixtures have low_energy <= total (no negative incandescent), matching the reference paths that already do this unclamped. Verification: new test 2 passed; test_mapper_corpus 6002 passed; SAP-accuracy / RealCertExpectation regressions 56 passed (no pinned shifts); pyright unchanged (39 -> 39, pre-existing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cf4c56df2e
commit
a3bdcccfb1
2 changed files with 77 additions and 2 deletions
|
|
@ -603,9 +603,18 @@ class EpcPropertyDataMapper:
|
|||
insulated_door_count=schema.insulated_door_count,
|
||||
draughtproofed_door_count=None,
|
||||
percent_draughtproofed=schema.percent_draughtproofed,
|
||||
# ADR-0028: the schema lodges total + low-energy OUTLET counts, not a
|
||||
# bulb split — mirror the 17.1/18.0/20.0 paths (low-energy outlets →
|
||||
# low_energy bulbs; the remainder → incandescent). Hardcoding all
|
||||
# bulb counts to 0 dropped the lodged lighting mix, understating the
|
||||
# low-energy lighting credit in the SAP lighting-energy calc.
|
||||
led_fixed_lighting_bulbs_count=0,
|
||||
cfl_fixed_lighting_bulbs_count=0,
|
||||
incandescent_fixed_lighting_bulbs_count=0,
|
||||
incandescent_fixed_lighting_bulbs_count=(
|
||||
schema.fixed_lighting_outlets_count
|
||||
- schema.low_energy_fixed_lighting_outlets_count
|
||||
),
|
||||
low_energy_fixed_lighting_bulbs_count=schema.low_energy_fixed_lighting_outlets_count,
|
||||
roofs=EpcPropertyDataMapper._map_energy_elements(schema.roofs),
|
||||
walls=EpcPropertyDataMapper._map_energy_elements(schema.walls),
|
||||
floors=EpcPropertyDataMapper._map_energy_elements(schema.floors),
|
||||
|
|
@ -1577,9 +1586,18 @@ class EpcPropertyDataMapper:
|
|||
insulated_door_count=schema.insulated_door_count,
|
||||
draughtproofed_door_count=None,
|
||||
percent_draughtproofed=schema.percent_draughtproofed,
|
||||
# ADR-0028: the schema lodges total + low-energy OUTLET counts, not a
|
||||
# bulb split — mirror the 17.1/18.0/20.0 paths (low-energy outlets →
|
||||
# low_energy bulbs; the remainder → incandescent). Hardcoding all
|
||||
# bulb counts to 0 dropped the lodged lighting mix, understating the
|
||||
# low-energy lighting credit in the SAP lighting-energy calc.
|
||||
led_fixed_lighting_bulbs_count=0,
|
||||
cfl_fixed_lighting_bulbs_count=0,
|
||||
incandescent_fixed_lighting_bulbs_count=0,
|
||||
incandescent_fixed_lighting_bulbs_count=(
|
||||
schema.fixed_lighting_outlets_count
|
||||
- schema.low_energy_fixed_lighting_outlets_count
|
||||
),
|
||||
low_energy_fixed_lighting_bulbs_count=schema.low_energy_fixed_lighting_outlets_count,
|
||||
roofs=EpcPropertyDataMapper._map_energy_elements(schema.roofs),
|
||||
walls=EpcPropertyDataMapper._map_energy_elements(schema.walls),
|
||||
floors=EpcPropertyDataMapper._map_energy_elements(schema.floors),
|
||||
|
|
|
|||
57
tests/datatypes/epc/domain/test_mapper_lighting_parity.py
Normal file
57
tests/datatypes/epc/domain/test_mapper_lighting_parity.py
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
"""Regression: the degraded RdSAP paths (17.0, 19.0) must carry the lodged
|
||||
fixed-lighting outlet counts, like the reference-complete 17.1/18.0/20.0 paths.
|
||||
|
||||
PRD #1385 (mapper normalization), lighting family. Both paths hardcoded every
|
||||
bulb count to 0, dropping the lodged lighting mix. The schema lodges total +
|
||||
low-energy OUTLET counts (ADR-0028); the reference paths split them as
|
||||
low-energy → low_energy bulbs and the remainder → incandescent, feeding the SAP
|
||||
lighting-energy calc. (21.0.x use a different bulb-based lighting schema and are
|
||||
out of scope for this slice.)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from datatypes.epc.domain.mapper import EpcPropertyDataMapper
|
||||
|
||||
# 17.0 cert: fixed_lighting_outlets_count=10, low_energy=5 → incandescent 5.
|
||||
_FIXTURE_17_0 = Path("tests/fixtures/epc_prediction/PE71NT/cert-26619d8e7f8e.json")
|
||||
# 19.0 cert: fixed_lighting_outlets_count=8, low_energy=5 → incandescent 3.
|
||||
_FIXTURE_19_0 = Path("tests/fixtures/epc_prediction/PE71NT/cert-21b634bc4b59.json")
|
||||
|
||||
|
||||
def _load(path: Path, schema_type: str) -> dict[str, Any]:
|
||||
data: dict[str, Any] = json.loads(path.read_text())
|
||||
assert data["schema_type"] == schema_type
|
||||
return data
|
||||
|
||||
|
||||
def test_17_0_path_carries_lighting_outlet_counts() -> None:
|
||||
data = _load(_FIXTURE_17_0, "RdSAP-Schema-17.0")
|
||||
assert data["fixed_lighting_outlets_count"] == 10
|
||||
assert data["low_energy_fixed_lighting_outlets_count"] == 5
|
||||
|
||||
epc = EpcPropertyDataMapper.from_api_response(data)
|
||||
|
||||
# Was hardcoded 0/0/0. Low-energy outlets carry through; the remainder is
|
||||
# incandescent; led/cfl stay 0 (reduced-field certs don't split those).
|
||||
assert epc.low_energy_fixed_lighting_bulbs_count == 5
|
||||
assert epc.incandescent_fixed_lighting_bulbs_count == 5
|
||||
assert epc.led_fixed_lighting_bulbs_count == 0
|
||||
assert epc.cfl_fixed_lighting_bulbs_count == 0
|
||||
|
||||
|
||||
def test_19_0_path_carries_lighting_outlet_counts() -> None:
|
||||
data = _load(_FIXTURE_19_0, "RdSAP-Schema-19.0")
|
||||
assert data["fixed_lighting_outlets_count"] == 8
|
||||
assert data["low_energy_fixed_lighting_outlets_count"] == 5
|
||||
|
||||
epc = EpcPropertyDataMapper.from_api_response(data)
|
||||
|
||||
assert epc.low_energy_fixed_lighting_bulbs_count == 5
|
||||
assert epc.incandescent_fixed_lighting_bulbs_count == 3
|
||||
assert epc.led_fixed_lighting_bulbs_count == 0
|
||||
assert epc.cfl_fixed_lighting_bulbs_count == 0
|
||||
Loading…
Add table
Reference in a new issue