mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Dispatch PasHub mechanical ventilation into the §2 ACH cascade 🟩
The surveyed "Ventilation type" label never reached mechanical_ventilation_kind, so ventilation_from_cert silently defaulted every mechanical system to NATURAL (24d), dropping its ACH heat loss — 76/205 cohort fixtures lodge dMEV/MEV/PIV (issue #1590 bug 4). Mapping mirrors the gov-API _API_MECHANICAL_VENTILATION_TO_KIND table (PIV-from-loft is "as natural"). Harness: within-0.5 12.2% -> 18.5%, MAE 2.538 -> 1.730 — the campaign's largest single move; floors ratcheted to 0.18 / 1.75. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5220b51961
commit
090e16ddc2
2 changed files with 39 additions and 2 deletions
|
|
@ -80,7 +80,11 @@ _MANIFEST_PATH = _FIXTURES_DIR / "manifest.json"
|
|||
# Both are tracked for verification (pre_sap correctness vs a deeper modelling
|
||||
# gap) — see docs/HANDOVER_PASHUB_838_PROBLEM_PROPERTIES.md. Re-baselined to the
|
||||
# full-coverage aggregate; ratchet back DOWN as those two are resolved.
|
||||
_MIN_WITHIN_HALF: float = 0.12
|
||||
# Ratcheted 0.12 -> 0.18 / 2.55 -> 1.75 by #1590 bug 4 (mechanical ventilation
|
||||
# dispatched into the §2 ACH cascade instead of defaulting to NATURAL): 76/205
|
||||
# cohort fixtures lodge a mechanical system; observed 18.5% within-0.5,
|
||||
# MAE 1.730 — the campaign's largest single move.
|
||||
_MIN_WITHIN_HALF: float = 0.18
|
||||
# Ratcheted 2.71 -> 2.64 by #1590 bug 2 (roof "Insulation At: None" -> explicit
|
||||
# zero thickness): observed MAE 2.632 — the two ~7-SAP roof over-raters
|
||||
# (507665533138 / 507670893756) correcting is exactly 14/205 ≈ 0.07 of MAE.
|
||||
|
|
@ -89,7 +93,7 @@ _MIN_WITHIN_HALF: float = 0.12
|
|||
# under-rate closing.
|
||||
# Ratcheted 2.58 -> 2.55 by #1590 bug 3 (PV Connection label -> gov-API int:
|
||||
# "Not connected" no longer silently credited): observed MAE 2.538.
|
||||
_MAX_SAP_MAE: float = 2.55
|
||||
_MAX_SAP_MAE: float = 1.75
|
||||
|
||||
_KNOWN_GAP_REASON = (
|
||||
"pashub `from_site_notes` mapper does not int-code a main-heating "
|
||||
|
|
|
|||
|
|
@ -6142,9 +6142,42 @@ def _map_sap_heating(
|
|||
)
|
||||
|
||||
|
||||
# PasHub surveyed "Ventilation type" label → `MechanicalVentilationKind` enum
|
||||
# name for the §2 cascade dispatch, mirroring the gov-API table
|
||||
# `_API_MECHANICAL_VENTILATION_TO_KIND` (dMEV=3 / MEV=2 / PIV-outside=6 →
|
||||
# EXTRACT_OR_PIV_OUTSIDE; PIV-from-loft=5 is "as natural" → None). Left None,
|
||||
# `ventilation_from_cert` silently defaults a mechanical system to NATURAL
|
||||
# (24d), dropping its ACH heat loss (issue #1590 bug 4).
|
||||
_PASHUB_VENTILATION_TYPE_TO_KIND: Dict[str, Optional[str]] = {
|
||||
"Natural": None,
|
||||
"Mechanical Extract - Decentralised": "EXTRACT_OR_PIV_OUTSIDE",
|
||||
"Mechanical Extract - Centralised": "EXTRACT_OR_PIV_OUTSIDE",
|
||||
"Positive Input - From Outside": "EXTRACT_OR_PIV_OUTSIDE",
|
||||
"Positive Input - From Loft (As Natural)": None,
|
||||
}
|
||||
|
||||
|
||||
def _pashub_mechanical_ventilation_kind(
|
||||
ventilation_type: Optional[str],
|
||||
) -> Optional[str]:
|
||||
"""Resolve a PasHub surveyed Ventilation type label to the
|
||||
`MechanicalVentilationKind` enum name at the mapper boundary (ADR-0015).
|
||||
Blank stays None (natural); a non-empty label the lookup does not cover
|
||||
strict-raises `UnmappedPasHubLabel` so the gap is fixed here, never
|
||||
silently under-stating ventilation heat loss downstream."""
|
||||
if not ventilation_type:
|
||||
return None
|
||||
if ventilation_type not in _PASHUB_VENTILATION_TYPE_TO_KIND:
|
||||
raise UnmappedPasHubLabel("ventilation type", ventilation_type)
|
||||
return _PASHUB_VENTILATION_TYPE_TO_KIND[ventilation_type]
|
||||
|
||||
|
||||
def _map_sap_ventilation(ventilation: Ventilation) -> SapVentilation:
|
||||
return SapVentilation(
|
||||
ventilation_type=ventilation.ventilation_type,
|
||||
mechanical_ventilation_kind=_pashub_mechanical_ventilation_kind(
|
||||
ventilation.ventilation_type
|
||||
),
|
||||
draught_lobby=ventilation.draught_lobby,
|
||||
pressure_test=ventilation.pressure_test,
|
||||
open_flues_count=ventilation.number_of_open_flues,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue