Commit graph

5 commits

Author SHA1 Message Date
Adriano Caloiaro
567845f88e
fix(weather): apply Beer-Lambert extinction to clear-sky model
The simple atmosphericCeiling*sin(elevation) model overestimates clear-sky
radiation at low sun angles because it ignores the longer atmospheric path
light travels near the horizon. At 5° elevation the path is ~11x vertical,
making the real clear-sky ceiling ~26 W/m² rather than the 83 W/m² the
naive model predicts — causing sunny low-angle readings to be misclassified
as mostly cloudy.

Replace with the Beer-Lambert correction:
  expectedClearSky = 950 * exp(-opticalDepth / sin(elevation)) * sin(elevation)

opticalDepth=0.1 (clear atmosphere) produces accurate values across all
angles: ~26 W/m² at 5°, ~93 W/m² at 10°, ~715 W/m² at solar noon.
2026-04-12 07:39:31 -06:00
Adriano Caloiaro
367ab3ec98
refactor(weather): derive conditions from solar elevation angle
Replace the sinusoidal day model with solarPosition(), which computes the
actual solar elevation and hour angle from latitude, longitude, and UTC time.
Expected clear-sky radiation at any moment is simply atmosphericCeiling *
sin(elevation), eliminating all hardcoded or approximated sunrise/sunset
windows.

Dawn/dusk is now detected when the sun is geometrically below the horizon
but the sensor still reads positive (scattered twilight), and morning vs.
afternoon is determined from the sign of the hour angle rather than a
clock-time comparison.
2026-04-11 19:48:53 -06:00
Adriano Caloiaro
7099961ba3
fix(weather): derive clear-sky peak from latitude and date, use current time for sun-angle
Replace the hardcoded peakSolarRadiation constant with solarNoonPeak(), which
scales the atmospheric ceiling (950 W/m²) by sin(solar elevation angle). Elevation
is computed from the current latitude and solar declination (function of day-of-year),
so the normalization is accurate across seasons and locations rather than assuming
equatorial/summer-solstice conditions.

Also switch the sun-angle time calculation from d.LastUpdated to time.Now() so
that a stale cache entry (e.g. after a Starlink connectivity gap) doesn't cause the
wrong time-of-day to be used when inferring conditions.
2026-04-11 19:15:09 -06:00
Adriano Caloiaro
ef7c36af37
feat(weather): add dawn and dusk conditions based on solar sensor
Detect twilight by checking when the solar radiation sensor reads low but
positive values (< 30 W/m²) while the sun is geometrically near the horizon
(sinusoidal fraction < 0.2 or outside model daylight hours). Morning/afternoon
local time distinguishes dawn from dusk without hard-coding sunrise/sunset times.
2026-04-11 12:28:38 -06:00
Adriano Caloiaro
2aa59c57b0
feat: append location snapshots to WebDAV JSON log on each poll 2026-04-10 08:45:50 -06:00