Use fixed obs time for NASA fetch and atmosphere check

Previous approach: scan a 3-day window, find best moon detection,
use that timestamp.  Problems: fuzzy composite (multi-day scan could
pick a frame far from actual full moon), no clear tie between the
NASA render and a specific observable moment.

New approach — MOON_OBS_TIME_LOCAL (default 22:30 local):
  On the night of the exact phase event, look at east frames in a
  ±MOON_OBS_WINDOW_MIN (default 30 min) window around the configured
  time.  The frame closest to that time determines atmosphere opacity;
  the same time (rounded to hour) drives the NASA Dial-a-Moon fetch.
  This gives one definitive moment per phase per month.

moon_phase_monthly.py:
  - PHASE_SPEC stripped to just post_delay + enabled_key (all window/
    illumination filtering removed — obs time is the only selector)
  - run_phase() replaced with obs-time logic; opacity derived from
    detect_moon quality on that single frame
  - MOON_FULL_POST_DELAY_DAYS / MOON_QUARTER_POST_DELAY_DAYS default
    changed to 1 (post morning after the phase, frames already on disk)

moon_composite.py:
  - atmosphere blur default: output_width//10 (192px) → output_width//20
    (96px) so cloud shapes survive the blur

sky-cam.conf:
  - MOON_OBS_TIME_LOCAL=22:30, MOON_OBS_WINDOW_MIN=30
  - Post delay defaults updated to 1

test_moon_composite.py:
  - Tries real NASA SVS Dial-a-Moon API first; procedural disc only as
    fallback if API unreachable
  - Runs detect_moon on the east frame to compute real opacity
  - Single output (test_composite_out.jpg)

https://claude.ai/code/session_01HkTxpNSTWtViZzxbrbKytR
This commit is contained in:
Claude
2026-05-01 22:03:57 +00:00
parent c09b872f52
commit 9e2852fd73
4 changed files with 208 additions and 170 deletions
+21 -8
View File
@@ -491,15 +491,28 @@ MOON_TRACK_FPS=12 # output mp4 framerate
MOON_TRACK_CRF=24 # output mp4 CRF
MOON_TRACK_RETENTION_DAYS=90 # delete tracker mp4s older than this; 0 = forever
# Full-moon monthly tuning ────────────────────────────────────────────────────
# How many days after the exact full moon to post. 3 = waits for D-1..D+2
# nights to be on disk, then runs the morning of D+3.
MOON_FULL_POST_DELAY_DAYS=3
# Observation time ────────────────────────────────────────────────────────────
# Local time used to select the east camera frame and the NASA Dial-a-Moon
# render for each phase post. The script looks at east frames within
# ±MOON_OBS_WINDOW_MIN of this time on the night of the exact phase event,
# picks the one closest to the target time, and uses it to:
# 1. Determine atmospheric conditions (clear / hazy / overcast)
# 2. Set the atmosphere overlay opacity on the NASA moon image
# 3. Round to the nearest hour for the NASA API call
#
# 22:30 works well for full moon and first quarter (both visible after dark).
# For third quarter (rises after midnight), consider 02:30 or leave at 22:30
# and accept that the moon may be below the horizon — the script will warn
# and post a clean NASA render instead.
MOON_OBS_TIME_LOCAL=22:30
MOON_OBS_WINDOW_MIN=30 # ±minutes around obs time to check east frames
# Quarter (half-moon) tuning ──────────────────────────────────────────────────
# 2 = waits for D-1, D, D+1 nights, runs the morning of D+2.
MOON_QUARTER_POST_DELAY_DAYS=2
MOON_QUARTER_MIN_ILLUMINATION=0.46 # ±4% of 50%: waxing/waning within 4% of exact quarter
# Post delay ──────────────────────────────────────────────────────────────────
# How many days after the exact phase to run the post. The post delay gives
# time for the obs-night frames to land on disk before the job runs.
MOON_FULL_POST_DELAY_DAYS=1 # post the morning after the full moon
MOON_QUARTER_POST_DELAY_DAYS=1 # post the morning after each quarter
MOON_QUARTER_MIN_ILLUMINATION=0.46
MOON_QUARTER_MAX_ILLUMINATION=0.54
# Frame-acceptance thresholds — a candidate must beat all three to qualify.