Skip to content

Commit 8e8dc9d

Browse files
cps13claude
andcommitted
Add solar-power-app — interactive rooftop solar panel planner
Interactive MATLAB app for planning rooftop solar installations. Enter any address to load satellite imagery, draw panels, optimize tilt, and estimate annual energy yield. Includes live scripts for address-based analysis, core function demos, and US solar potential mapping. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 48d33a6 commit 8e8dc9d

15 files changed

Lines changed: 2588 additions & 0 deletions
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# MATLAB temporary files
2+
*.asv
3+
*.m~
4+
*.autosave
5+
6+
# Simulink autosave
7+
*.slxc
8+
slprj/
9+
10+
# Generated outputs
11+
SolarReport.pdf
12+
13+
# Tooling
14+
.claude/
15+
.mcp.json
16+
17+
# OS files
18+
.DS_Store
19+
Thumbs.db
20+
desktop.ini
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
%[text] # Solar Analysis for Any Address
2+
%[text] Enter a street address and get a complete solar energy analysis for that location. Uses the OpenStreetMap Nominatim geocoder to convert the address to coordinates, then computes sun position and panel output across the year.
3+
4+
%%
5+
%[text] ## Enter Your Address
6+
%[text] Change the address below to analyze any location.
7+
8+
address = "3 Apple Hill Drive, Natick, MA";
9+
10+
%%
11+
%[text] ## Geocode the Address
12+
13+
[lat, lon, displayName] = geocodeAddress(address);
14+
fprintf("Location: %s\n", displayName)
15+
fprintf("Coordinates: %.4f°N, %.4f°E\n", lat, lon)
16+
17+
%%
18+
%[text] ## Panel Configuration
19+
20+
panelEfficiency = 0.20;
21+
panelArea = 1.6; % m^2
22+
panelTilt = abs(lat); % rule-of-thumb: tilt = latitude
23+
panelAzimuth = 180; % south-facing (northern hemisphere)
24+
25+
%%
26+
%[text] ## Show Location on Map
27+
%[text] Display the location on a geographic map with satellite basemap.
28+
29+
figure('Position', [100 100 700 500])
30+
geoplot(lat, lon, 'rp', 'MarkerSize', 20, 'MarkerFaceColor', 'r')
31+
geobasemap satellite
32+
title(sprintf("Solar Analysis Site: %s", address))
33+
geolimits([lat-0.01 lat+0.01], [lon-0.01 lon+0.01])
34+
35+
%%
36+
%[text] ## Sun Path Diagram
37+
%[text] Compute sun paths for solstices and equinoxes at this location.
38+
39+
figure('Position', [100 100 600 600])
40+
dates = [datetime(2024,3,20), datetime(2024,6,21), ...
41+
datetime(2024,9,22), datetime(2024,12,21)];
42+
labels = ["Spring Equinox", "Summer Solstice", "Autumn Equinox", "Winter Solstice"];
43+
colors = [0.2 0.7 0.3; 0.85 0.33 0.1; 0.6 0.4 0.0; 0.1 0.4 0.8];
44+
45+
polaraxes;
46+
hold on
47+
for k = 1:4
48+
t = datetime(dates(k), 'TimeZone', 'UTC') + minutes(0:5:1439);
49+
[az, el] = sunPosition(lat, lon, t);
50+
daytime = el > 0;
51+
polarplot(deg2rad(az(daytime)), 90 - el(daytime), ...
52+
'Color', colors(k,:), 'LineWidth', 2)
53+
end
54+
hold off
55+
ax = gca;
56+
ax.ThetaZeroLocation = 'top';
57+
ax.ThetaDir = 'clockwise';
58+
ax.RLim = [0 90];
59+
ax.RTickLabel = {'90°','60°','30°',''};
60+
title(sprintf("Sun Path — %s (%.2f°N)", address, lat))
61+
legend(labels, 'Location', 'southoutside', 'Orientation', 'horizontal')
62+
63+
%%
64+
%[text] ## Monthly Energy Yield
65+
%[text] Compute the expected monthly clear-sky energy production.
66+
67+
daysPerMonth = [31 29 31 30 31 30 31 31 30 31 30 31];
68+
monthlyEnergy = zeros(1, 12);
69+
70+
for m = 1:12
71+
t = datetime(2024, m, 15, 'TimeZone', 'UTC') + hours(0:23);
72+
[az, el] = sunPosition(lat, lon, t);
73+
w = solarPanelPower(panelEfficiency, panelArea, az, el, panelTilt, panelAzimuth);
74+
dailyKWh = sum(w) / 1000;
75+
monthlyEnergy(m) = dailyKWh * daysPerMonth(m);
76+
end
77+
78+
annualTotal = sum(monthlyEnergy);
79+
80+
%%
81+
%[text] Plot the monthly breakdown.
82+
83+
figure
84+
bar(1:12, monthlyEnergy, 'FaceColor', [0.9 0.5 0.1], 'EdgeColor', 'none')
85+
xlabel("Month")
86+
ylabel("Energy (kWh)")
87+
title(sprintf("Monthly Solar Energy — %s", address))
88+
subtitle(sprintf("Annual total: %.0f kWh/panel (clear sky) | Tilt: %.0f° South", ...
89+
annualTotal, panelTilt))
90+
xticklabels(["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"])
91+
grid on
92+
93+
%%
94+
%[text] ## Daily Power Curves by Season
95+
%[text] Show how power output varies through the day for each season.
96+
97+
figure
98+
hold on
99+
dailyYield = zeros(1, 4);
100+
for k = 1:4
101+
t = datetime(dates(k), 'TimeZone', 'UTC') + minutes(0:10:1439);
102+
[az, el] = sunPosition(lat, lon, t);
103+
w = solarPanelPower(panelEfficiency, panelArea, az, el, panelTilt, panelAzimuth);
104+
plot(hours(t - t(1)), w, 'Color', colors(k,:), 'LineWidth', 1.5)
105+
dailyYield(k) = trapz(hours(t - t(1)), w) / 1000;
106+
end
107+
hold off
108+
xlabel("Hour of Day (UTC)")
109+
ylabel("Power (W)")
110+
title(sprintf("Daily Power Profiles — %s", address))
111+
legend(labels + " (" + compose("%.1f", dailyYield) + " kWh)", 'Location', 'northwest')
112+
grid on
113+
xlim([0 24])
114+
115+
%%
116+
%[text] ## Summary
117+
%[text] This analysis provides clear-sky estimates. Actual production will be lower due to:
118+
%[text] - Cloud cover and weather
119+
%[text] - Shading from buildings and trees
120+
%[text] - Panel degradation and inverter losses
121+
%[text] - Temperature effects \
122+
%[text]
123+
%[text] A typical derating factor is 0.75–0.80 for real-world conditions. Multiply the annual total by this factor for a more realistic estimate.
124+
125+
realisticEstimate = annualTotal * 0.77;
126+
fprintf("Realistic annual estimate (77%% derating): %.0f kWh/panel\n", realisticEstimate)
127+
128+
%%
129+
%[text] ---
130+
%[text] *Functions used: `geocodeAddress`, `sunPosition`, `solarPanelPower`, `geoplot`*
131+
132+
%[appendix]{"version":"1.0"}
133+
%---
134+
%[metadata:view]
135+
% data: {"layout":"inline"}
136+
%---

Examples/solar-power-app/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Solar Panel Planner for MATLAB&reg;
2+
3+
![Solar Panel Planner App](hero.gif)
4+
5+
An interactive application for planning rooftop solar panel installations using satellite imagery, sun-position modeling, and energy yield estimation in MATLAB&reg;.
6+
7+
## Overview
8+
9+
This app lets you enter any street address, view the rooftop on a satellite map, draw solar panel rectangles interactively, and estimate annual energy production. It models:
10+
11+
- **Sun position** throughout the year (altitude and azimuth for any latitude/longitude)
12+
- **Clear-sky irradiance** with air mass and atmospheric effects
13+
- **Temperature derating** using NOCT (Nominal Operating Cell Temperature) model
14+
- **Clearness index** from NASA POWER monthly averages
15+
- **Panel tilt optimization** for maximum annual yield
16+
17+
## Quick Start
18+
19+
```matlab
20+
% Launch the interactive app
21+
SolarPanelApp()
22+
```
23+
24+
1. Enter an address and click **Load** to fetch satellite imagery
25+
2. Click **+ Add Panel** to draw panel rectangles on the roof
26+
3. Adjust tilt with the slider or click **Optimize** for maximum yield
27+
4. View daily power curves and monthly energy bar charts in real time
28+
29+
## Scripts
30+
31+
| Script | Description |
32+
|--------|-------------|
33+
| `AddressSolarAnalysis.m` | Enter any address and get a full year solar analysis |
34+
| `SolarPanelDemo.m` | Demonstrates core functions: sun position, irradiance, panel power |
35+
| `SolarPotentialMap.m` | Visualizes solar potential across the United States |
36+
37+
## Key Functions
38+
39+
| Function | Description |
40+
|----------|-------------|
41+
| `sunPosition` | Solar altitude and azimuth for any location and time |
42+
| `solarPanelPower` | Instantaneous panel power output (W) given conditions |
43+
| `clearnessIndex` | Monthly clearness index from latitude/longitude |
44+
| `ambientTemperature` | Hourly ambient temperature from sinusoidal model |
45+
| `geocodeAddress` | Convert street address to lat/lon via OpenStreetMap Nominatim |
46+
| `fetchBuildings` | Fetch building footprints from OpenStreetMap Overpass API |
47+
| `packPanels` | Fit panel rectangles within a building polygon |
48+
49+
## Requirements
50+
51+
- MATLAB&reg; R2023a or later
52+
- Mapping Toolbox&trade;
53+
- MATLAB Report Generator&trade; (optional, for PDF export)
54+
- Internet connection (satellite basemap, geocoding, building footprints)

0 commit comments

Comments
 (0)