mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-27 23:35:01 +00:00
Extract the PasHub per-system PV block and diverter flag 🟩
"Photovoltaic array kWp Known? Yes" lodges a per-system block (kWp, pitch, orientation, overshading) instead of the percent-roof estimate; the extractor only read the estimate, so measured PV never reached the mapper and the Appendix M credit was silently zero (issue #1590 bug 1). Harness MAE 2.632 -> 2.571 (fixture 507639151843's 13.5-SAP under-rate closes to +0.5); ceiling ratcheted to 2.58. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
80de9b0c04
commit
f92d4f26b8
2 changed files with 38 additions and 1 deletions
|
|
@ -18,6 +18,7 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import (
|
|||
MainBuildingMeasurements,
|
||||
MainHeating,
|
||||
PasHubRdSapSiteNotes,
|
||||
PvArrayDetail,
|
||||
Renewables,
|
||||
RoomCountElements,
|
||||
RoofSpace,
|
||||
|
|
@ -435,8 +436,41 @@ class PasHubRdSapSiteNotesExtractor:
|
|||
hydro=self._bool_in(r_section, "Is the dwelling connected to Hydro?"),
|
||||
pv_connection=pv_connection,
|
||||
percent_roof_covered_pv=percent_roof,
|
||||
pv_diverter_present=self._optional_bool_in(
|
||||
r_section, "Is there a PV diverter?"
|
||||
),
|
||||
pv_arrays=self._pv_arrays_in(r_section),
|
||||
)
|
||||
|
||||
def _pv_arrays_in(self, r_section: List[str]) -> Optional[List[PvArrayDetail]]:
|
||||
"""The "Photovoltaic array kWp Known? Yes" form lodges a per-system
|
||||
block instead of the percent-roof estimate: "Number of PV systems?"
|
||||
then "PV {n}: kWp value / Photovoltaic Pitch / Orientation /
|
||||
Overshading" per system. Dropped detail silently zeroes the Appendix M
|
||||
PV credit downstream (issue #1590 bug 1)."""
|
||||
systems_raw = self._get_in(r_section, "Number of PV systems?")
|
||||
if systems_raw is None:
|
||||
return None
|
||||
arrays: List[PvArrayDetail] = []
|
||||
for n in range(1, int(systems_raw) + 1):
|
||||
kwp_raw = self._get_in(r_section, f"PV {n}: kWp value:")
|
||||
pitch_raw = self._get_in(r_section, f"PV {n}: Photovoltaic Pitch?")
|
||||
arrays.append(
|
||||
PvArrayDetail(
|
||||
kwp=float(kwp_raw.split()[0]) if kwp_raw else None,
|
||||
pitch_degrees=(
|
||||
int(pitch_raw.split()[0]) if pitch_raw else None
|
||||
),
|
||||
orientation=self._get_in(
|
||||
r_section, f"PV {n}: Photovoltaic Orientation?"
|
||||
),
|
||||
overshading=self._get_in(
|
||||
r_section, f"PV {n}: Photovoltaic Overshading:"
|
||||
),
|
||||
)
|
||||
)
|
||||
return arrays or None
|
||||
|
||||
def extract_room_count_elements(self) -> RoomCountElements:
|
||||
rce_section = self._section("Room Count Elements", "Customer Response")
|
||||
heated_rooms_raw = self._get_in(rce_section, "Number of heated rooms?")
|
||||
|
|
|
|||
|
|
@ -84,7 +84,10 @@ _MIN_WITHIN_HALF: float = 0.12
|
|||
# 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.
|
||||
_MAX_SAP_MAE: float = 2.64
|
||||
# Ratcheted 2.64 -> 2.58 by #1590 bug 1 (surveyed PV arrays now reach the
|
||||
# Appendix M input): observed MAE 2.571 — 507639151843's 13.5-SAP zero-PV-credit
|
||||
# under-rate closing.
|
||||
_MAX_SAP_MAE: float = 2.58
|
||||
|
||||
_KNOWN_GAP_REASON = (
|
||||
"pashub `from_site_notes` mapper does not int-code a main-heating "
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue