SolarPotential carries panel dims + per-segment centre/area 🟥

The Dwelling-Roof Cap (ADR-0038) sizes by usable roof area and ranks segments
by distance from the dwelling, so the projection must carry each panel's
footprint and each segment's centre + area (from roofSegmentStats).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Khalim Conn-Kowlessar 2026-06-26 12:12:12 +00:00
parent 58f6b868a7
commit cf2780ed77

View file

@ -103,6 +103,43 @@ def test_projection_first_config_single_segment() -> None:
assert segment.sap_pitch_code == 2 # ~32° → 30°
def test_projection_reads_panel_dimensions() -> None:
# The Dwelling-Roof Cap (ADR-0038) sizes the array by usable roof area, so
# it needs each panel's physical footprint — Google reports it at the
# solarPotential level.
potential = SolarPotential.from_building_insights(_insights())
assert potential is not None
assert potential.panel_height_m is not None
assert potential.panel_width_m is not None
assert abs(potential.panel_height_m - 1.879) <= 1e-4
assert abs(potential.panel_width_m - 1.045) <= 1e-4
def test_projection_enriches_segments_with_centre_and_area() -> None:
# The Dwelling-Roof Cap (ADR-0038) ranks segments by distance from the
# dwelling and bounds the array by usable roof area, so each segment must
# carry its centre + area — sourced from the top-level roofSegmentStats,
# keyed by segmentIndex (the per-config roofSegmentSummaries omit them).
insights = _insights()
stats_by_index = {
int(s["segmentIndex"]): s
for s in insights["solarPotential"]["roofSegmentStats"]
}
potential = SolarPotential.from_building_insights(insights)
assert potential is not None
segment = potential.configurations[0].segments[0] # segment_index == 1
expected = stats_by_index[segment.segment_index]
assert segment.area_m2 is not None
assert abs(segment.area_m2 - expected["stats"]["areaMeters2"]) <= 1e-4
assert segment.center_latitude is not None
assert segment.center_longitude is not None
assert abs(segment.center_latitude - expected["center"]["latitude"]) <= 1e-9
assert abs(segment.center_longitude - expected["center"]["longitude"]) <= 1e-9
def test_projection_largest_config_spans_all_segments() -> None:
# Arrange
insights = _insights()