Skip to content

Commit 75dc758

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 with PDF report export. 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 75dc758

13 files changed

Lines changed: 2335 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: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
- **PDF report export** with site summary and energy analysis
17+
18+
## Quick Start
19+
20+
```matlab
21+
% Launch the interactive app
22+
SolarPanelApp()
23+
```
24+
25+
1. Enter an address and click **Load** to fetch satellite imagery
26+
2. Click **+ Add Panel** to draw panel rectangles on the roof
27+
3. Adjust tilt with the slider or click **Optimize** for maximum yield
28+
4. View daily power curves and monthly energy bar charts in real time
29+
30+
## Scripts
31+
32+
| Script | Description |
33+
|--------|-------------|
34+
| `AddressSolarAnalysis.m` | Enter any address and get a full year solar analysis |
35+
| `SolarPanelDemo.m` | Demonstrates core functions: sun position, irradiance, panel power |
36+
| `SolarPotentialMap.m` | Visualizes solar potential across the United States |
37+
38+
## Key Functions
39+
40+
| Function | Description |
41+
|----------|-------------|
42+
| `sunPosition` | Solar altitude and azimuth for any location and time |
43+
| `solarPanelPower` | Instantaneous panel power output (W) given conditions |
44+
| `clearnessIndex` | Monthly clearness index from latitude/longitude |
45+
| `ambientTemperature` | Hourly ambient temperature from sinusoidal model |
46+
| `geocodeAddress` | Convert street address to lat/lon via OpenStreetMap Nominatim |
47+
48+
## Requirements
49+
50+
- MATLAB&reg; R2023a or later
51+
- Mapping Toolbox&trade; (satellite basemap imagery)
52+
- MATLAB Report Generator&trade; (optional, for PDF export)
53+
- Internet connection (required for basemap tiles and address geocoding via OpenStreetMap Nominatim)

0 commit comments

Comments
 (0)