Add nightly moon-track timelapse and monthly moon-phase composites
Two new jobs operate on the SUNRISE_CAM, sharing three Python helpers (moon_phase, moon_detect, moon_composite) and one cached lunar texture: - moon-track.sh: nightly batch detects the moon in each east frame, crops a 480x480 box around it, stitches into an mp4 that holds the moon roughly centred while clouds and stars drift past. - moon-phase-monthly.sh: daily check that runs whichever phase composite is due that day. Handles full moon (posts D+3), first quarter (D+2, best-effort due to daytime-only geometry from east), and third quarter (D+2). Picks the frame closest in time to the exact phase moment that meets quality / altitude / illumination thresholds, then composites the cached lunar texture into it -- sky/halo/parallactic-angle/timing real from east, surface detail borrowed from the reference image. Honest-by-design: a 38-px white blob from a wide-field IP camera cannot be enhanced into crater detail by software. The composite makes the borrowing explicit and constrains everything else (when, where, sky, orientation) to match what east actually saw. install.sh now downloads the skyfield ephemeris (de421.bsp) and the default lunar reference (Wikipedia CC BY-SA full-moon photo) on first run. Both can be overridden via .env. https://claude.ai/code/session_015PBVDESC3KLMbq1LpA6qLn
This commit is contained in:
+66
@@ -225,6 +225,72 @@ EOF
|
||||
done
|
||||
fi
|
||||
|
||||
# ── Moon jobs: nightly tracker + monthly full-moon composite ────────────────
|
||||
# Both jobs target the SUNRISE_CAM (the east-facing camera). They share three
|
||||
# Python helpers (moon_phase.py, moon_detect.py, moon_composite.py) and one
|
||||
# downloaded asset (the lunar reference texture).
|
||||
if [ "${MOON_TRACK_ENABLED:-true}" = "true" ] || [ "${MOON_FULL_ENABLED:-true}" = "true" ]; then
|
||||
# Pre-download skyfield ephemeris so first run doesn't hit the network at
|
||||
# an inopportune moment. Stored next to the scripts.
|
||||
if [ ! -f "$HERE/de421.bsp" ]; then
|
||||
echo "Downloading skyfield ephemeris (de421.bsp, ~17 MB)..."
|
||||
if curl -fsSL -o "$HERE/de421.bsp" \
|
||||
"https://ssd.jpl.nasa.gov/ftp/eph/planets/bsp/de421.bsp"; then
|
||||
echo " ok"
|
||||
else
|
||||
echo " WARNING: ephemeris download failed — moon jobs will retry on first run"
|
||||
rm -f "$HERE/de421.bsp"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Lunar reference texture for moon_phase_monthly.py. Default URL is the
|
||||
# Wikipedia "FullMoon2010" by Gregory H. Revera (CC BY-SA 3.0), 3500×3500.
|
||||
# Override MOON_REFERENCE_URL in .env to use a different source — any
|
||||
# high-res photo of a full moon on a black background works.
|
||||
ref_dir="${MOON_REFERENCE_DIR:-$HERE/moon-ref}"
|
||||
ref_path="${MOON_REFERENCE_PATH:-$ref_dir/full-moon.jpg}"
|
||||
ref_url="${MOON_REFERENCE_URL:-https://upload.wikimedia.org/wikipedia/commons/e/e1/FullMoon2010.jpg}"
|
||||
if [ ! -f "$ref_path" ]; then
|
||||
mkdir -p "$(dirname "$ref_path")"
|
||||
echo "Downloading lunar reference texture..."
|
||||
if curl -fsSL -o "$ref_path" "$ref_url"; then
|
||||
echo " ok → $ref_path"
|
||||
else
|
||||
echo " WARNING: lunar reference download failed"
|
||||
echo " Drop a high-res full-moon JPEG at $ref_path manually,"
|
||||
echo " or set MOON_REFERENCE_URL in .env and re-run install.sh."
|
||||
rm -f "$ref_path"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Nightly moon-track job — runs on the SUNRISE_CAM only.
|
||||
if [ "${MOON_TRACK_ENABLED:-true}" = "true" ]; then
|
||||
write_service "sky-cam-moon-track" \
|
||||
"$SUNRISE_CAM: nightly moon tracking timelapse" \
|
||||
"moon-track.sh $SUNRISE_CAM"
|
||||
write_timer "sky-cam-moon-track" \
|
||||
"$SUNRISE_CAM: nightly moon tracking timelapse" \
|
||||
"${SCHEDULE_MOON_TRACK:-02:30:00}"
|
||||
timers+=("sky-cam-moon-track")
|
||||
fi
|
||||
|
||||
# Moon-phase composite job — runs daily; the Python helper internally checks
|
||||
# full / first-quarter / third-quarter and only acts when today is the
|
||||
# matching post-day for one of them. One timer covers all three phases.
|
||||
if [ "${MOON_FULL_ENABLED:-true}" = "true" ] \
|
||||
|| [ "${MOON_FIRST_QUARTER_ENABLED:-true}" = "true" ] \
|
||||
|| [ "${MOON_THIRD_QUARTER_ENABLED:-true}" = "true" ]; then
|
||||
write_service "sky-cam-moon-phase" \
|
||||
"$SUNRISE_CAM: monthly moon-phase composite (full + quarters)" \
|
||||
"moon-phase-monthly.sh" \
|
||||
$'After=network-online.target\nWants=network-online.target\n'
|
||||
write_timer "sky-cam-moon-phase" \
|
||||
"$SUNRISE_CAM: monthly moon-phase composite" \
|
||||
"${SCHEDULE_MOON_PHASE:-09:30:00}"
|
||||
timers+=("sky-cam-moon-phase")
|
||||
fi
|
||||
|
||||
# ── Per-camera Four Seasons jobs ─────────────────────────────────────────────
|
||||
# Reads CAMERAS and SCHEDULE_SEASONS_<cam> from sky-cam.conf.
|
||||
# Script receives the camera name as $1 so it knows which camera to process.
|
||||
|
||||
Reference in New Issue
Block a user