Extract the PasHub per-system PV block and diverter flag 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-07-14 21:35:34 +00:00
parent 1282f81a72
commit 80de9b0c04

View file

@ -21,6 +21,7 @@ from datatypes.epc.surveys.pashub_rdsap_site_notes import (
MainBuildingConstruction,
MainBuildingMeasurements,
MainHeating,
PvArrayDetail,
Renewables,
RoomCountElements,
RoofSpace,
@ -646,6 +647,64 @@ class TestRenewablesPvConnection:
assert renewables.percent_roof_covered_pv == 45
class TestRenewablesPvArrays:
"""When "Photovoltaic array kWp Known?" is Yes, the survey lodges a
per-system block ("Number of PV systems?", then "PV {n}: kWp value /
Photovoltaic Pitch / Orientation / Overshading") instead of the
percent-roof estimate. The extractor must capture it dropped detail
silently zeroes the Appendix M PV credit (issue #1590 bug 1; verbatim
lines from accuracy fixture deal 507639151843).
"""
# The real kWp-known block, verbatim from the 507639151843 site notes.
_KWP_KNOWN_BLOCK = [
"Photovoltaic array kWp Known?",
"Yes",
"Number of PV systems?",
"1",
"PV 1: kWp value:",
"2.43 kWp",
"PV 1: Photovoltaic Pitch?",
"30 Degrees",
"PV 1: Photovoltaic Orientation?",
"South East",
"PV 1: Photovoltaic Overshading:",
"None or very little",
]
@pytest.fixture
def renewables(self) -> Renewables:
# Arrange — fixture 3's Renewables section with its "kWp Known? No +
# percent roof" block swapped for the real kWp-known block.
lines = load_text_fixture_3()
start = lines.index("Photovoltaic array kWp Known?")
end = lines.index("Number of PV batteries:")
spliced = lines[:start] + self._KWP_KNOWN_BLOCK + lines[end:]
return PasHubRdSapSiteNotesExtractor(spliced).extract_renewables()
def test_pv_array_detail_is_captured(self, renewables: Renewables) -> None:
assert renewables.pv_arrays == [
PvArrayDetail(
kwp=2.43,
pitch_degrees=30,
orientation="South East",
overshading="None or very little",
)
]
def test_pv_diverter_is_captured(self, renewables: Renewables) -> None:
assert renewables.pv_diverter_present is False # fixture 3 lodges "No"
def test_no_pv_block_leaves_arrays_absent(self) -> None:
# Arrange / Act — fixture 3 as lodged (kWp Known? No, percent path).
renewables = PasHubRdSapSiteNotesExtractor(
load_text_fixture_3()
).extract_renewables()
# Assert
assert renewables.pv_arrays is None
class TestRoomCountElements:
@pytest.fixture
def rce(self) -> RoomCountElements: