Carry full-SAP lodged PV arrays through to the domain 🟥

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-29 21:51:09 +00:00
parent e02e6a76e1
commit 4393812638
2 changed files with 33 additions and 0 deletions

View file

@ -137,6 +137,24 @@ class TestFromSapSchema17_1RebaselineFields:
assert result.assessment_type == "SAP"
class TestFullSapPhotovoltaics:
"""Full-SAP certs lodge measured PV under `sap_energy_source.pv_arrays`;
the mapper must carry it to the domain `photovoltaic_arrays` so the
Appendix-M generation credit isn't silently dropped."""
def test_maps_the_lodged_pv_array(self) -> None:
# sap_17_1_house.json lodges one 1.62 kWp array (pitch 3, orientation 6,
# overshading 1).
schema = from_dict(SapSchema17_1, load("sap_17_1_house.json"))
result = EpcPropertyDataMapper.from_sap_schema_17_1(schema)
arrays = result.sap_energy_source.photovoltaic_arrays
assert arrays is not None
assert len(arrays) == 1
assert arrays[0].peak_power == 1.62
class TestFullSapElectricityTariffTranslation:
"""The full-SAP `energy_tariff` code space differs from the RdSAP
`meter_type` one the calculator reads, so the mapper must translate it."""

View file

@ -107,6 +107,20 @@ class SapVentilation:
mechanical_vent_duct_type: Optional[int] = None
@dataclass
class SapPvArray:
"""One measured photovoltaic array lodged on a full-SAP cert (under
`sap_energy_source.pv_arrays`): peak power (kWp), pitch, SAP octant
orientation (1-8), overshading code, and the connection type. Mirrors the
domain `PhotovoltaicArray` the calculator's Appendix M generation uses."""
peak_power: Optional[float] = None
pitch: Optional[int] = None
orientation: Optional[int] = None
overshading: Optional[int] = None
pv_connection: Optional[int] = None
@dataclass
class SapEnergySource:
"""Electricity tariff, on-site generation and lighting. Lighting outlet
@ -118,6 +132,7 @@ class SapEnergySource:
wind_turbine_terrain_type: Optional[int] = None
fixed_lighting_outlets_count: Optional[int] = None
low_energy_fixed_lighting_outlets_count: Optional[int] = None
pv_arrays: Optional[List[SapPvArray]] = None
@dataclass