fix: pass bare topos to sunrise_sunset(), not earth+topos observer

skyfield's sunrise_sunset() internally computes ephemeris['earth'] + topos,
so passing the already-combined _observer caused a double-add ValueError.
Store _topos separately and use it only for almanac calls; _observer
(earth + topos) continues to be used for direct .at() observations.

https://claude.ai/code/session_01JieSeNQZ3X6fhsb11YyJrK
This commit is contained in:
Claude
2026-05-02 12:43:03 +00:00
parent 3bb17d0093
commit 318af0dbf5
+5 -3
View File
@@ -67,6 +67,7 @@ _EPH_PATH = _here / 'de421.bsp'
_ts = None
_eph = None
_observer = None
_topos = None # bare geographic position; sunrise_sunset() adds earth itself
def _lazy():
@@ -75,7 +76,7 @@ def _lazy():
Lets the module be imported by tests and by --help paths even when
skyfield is missing or the ephemeris hasn't been downloaded yet.
"""
global _ts, _eph, _observer
global _ts, _eph, _observer, _topos
if _ts is not None:
return
from skyfield.api import Loader, wgs84
@@ -85,7 +86,8 @@ def _lazy():
_eph = loader('de421.bsp')
else:
_eph = loader('de421.bsp') # downloads on first run
_observer = _eph['earth'] + wgs84.latlon(LATITUDE, LONGITUDE)
_topos = wgs84.latlon(LATITUDE, LONGITUDE)
_observer = _eph['earth'] + _topos
def _to_utc(when: datetime) -> datetime:
@@ -192,7 +194,7 @@ def sun_events_in_range(
from skyfield.almanac import find_discrete, sunrise_sunset
t0 = _t(search_start)
t1 = _t(search_end)
times, values = find_discrete(t0, t1, sunrise_sunset(_eph, _observer))
times, values = find_discrete(t0, t1, sunrise_sunset(_eph, _topos))
return [(t.utc_datetime(), bool(v)) for t, v in zip(times, values)]