Model/datatypes
Khalim Conn-Kowlessar 71b378b9e5 fix(ventilation): map API mechanical_ventilation enum to §2 MV-kind dispatch
The profiler flagged `mechanical_ventilation=2` as a clean systematic
over-rate: 20 certs, signed +1.90 SAP, only 5% within 0.5 (every one
positive). Root cause: the API path (`from_api_response`) dropped the
doc-level `mechanical_ventilation` field, so `sap_ventilation.
mechanical_ventilation_kind` was always None and the §2 cascade
defaulted to NATURAL — under-stating the ventilation air-change rate
(and hence heat loss) for every mechanical system. (Only the Elmhurst/
Summary path mapped it, via `_ELMHURST_MV_TYPE_TO_KIND`.)

RdSAP-Schema-21 `mechanical_ventilation` enum (epc_codes.csv) →
MechanicalVentilationKind picking the SAP 10.2 §2 (24a..d) effective-ach
formula:
  0 natural                      -> NATURAL (24d)
  1 MV (no heat recovery)        -> MV (24b)
  2 mechanical extract, dc (MEV) -> EXTRACT_OR_PIV_OUTSIDE (24c)
  3 mechanical extract, c (MEV)  -> EXTRACT_OR_PIV_OUTSIDE (24c)
  5 positive input from loft     -> NATURAL (loft-sourced PIV adds no
                                    system air change per RdSAP 10 §2.6)
  6 positive input from outside  -> EXTRACT_OR_PIV_OUTSIDE (24c)
Code 4 (MVHR, 24a) is DEFERRED — its formula needs the lodged
heat-recovery efficiency (PCDB Table 326) the API→cascade path doesn't
yet plumb; mapping it to MVHR with a null efficiency would mis-model it
as MV, so it stays NATURAL (3 scattered certs, accurate at the median).
Unmapped integers raise `UnmappedApiCode` (mirror of `_api_sheltered_
sides` / `_api_type_1_gable_kind`).

Eval: the extract cohort (mech_vent 2/3/6) moved +1.90 -> +0.9 median
(within-0.5 5% -> 35%); 20 improved / 3 regressed (offsetting). Headline
within-0.5 54.24% -> 55.01%, within-1.0 69.64% -> 70.08%, mean|err|
1.248 -> 1.233, 909 computed / 0 raises. The +0.9 residual on MEV is the
fan electricity (§2.6.4 SFP, PCDB Table 322) — a separate follow-up.
2 AAA tests; goldens + full calc/epc/parser regression green; pyright
net-zero.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 23:02:04 +00:00
..
epc fix(ventilation): map API mechanical_ventilation enum to §2 MV-kind dispatch 2026-06-08 23:02:04 +00:00
magicplan typing and renaming 🟪 2026-05-07 13:26:49 +00:00
__init__.py further breaking up code 2023-07-20 12:24:34 +01:00
datatypes.py further breaking up code 2023-07-20 12:24:34 +01:00
enums.py completed build of new demo portfolio - some fixed required still 2023-11-20 14:42:16 +00:00