Switch monthly phase close-ups to NASA SVS Dial-a-Moon at fullscreen

The previous east-flavored composite (tight-crop east region + lunar
texture overlay) was honest but visually limited: 38-px source moon, no
real terminator shadows on quarters, and a faint upscaled-halo
background that was less compelling than just a clean lunar render.

New flow:
- East stays the witness (verifies the moon was visible during the
  collection window) and supplies the timestamp.
- moon_dialamoon.py fetches the NASA SVS Dial-a-Moon render for that
  exact UTC hour. Free, public-domain, real-physics: correct phase,
  libration, and crater shadows for any timestamp.
- moon_composite.render_phase_closeup() places that render at ~92% of
  frame height on a 1920x1080 black background -- the long-telephoto
  look the user asked for.
- One API call per phase event (~36/year), cached forever in
  moon-ref/dialamoon/.

Quarter moons now show real 3D crater shadows along the terminator,
which the prior algorithmic phase-shadow couldn't simulate from a
full-moon reference.

Adds MOON_REQUIRE_EAST_VERIFY=true|false toggle so the user can choose
"only post when east saw it" (default, current behavior) vs "post every
cycle regardless of weather over east."

Drops the install-time lunar reference download (no longer needed) and
the now-unused per-phase phase-shadow path stays in moon_composite.py
for reference / future reuse.

https://claude.ai/code/session_015PBVDESC3KLMbq1LpA6qLn
This commit is contained in:
Claude
2026-05-01 11:54:46 +00:00
parent 5fb7ff09a3
commit 28c3c1dc63
6 changed files with 394 additions and 79 deletions
+14 -4
View File
@@ -6,7 +6,7 @@ Automated sky / timelapse camera scripts that produce:
- **Four Seasons timelapse** — daily clips sized to each Vivaldi movement's music duration, assembled automatically into per-movement montages (with music + attribution overlay) and a full-year video
- **Full-day timelapse** — a fixed-fps timelapse of every image captured that day, kept for a configurable retention window
- **Nightly moon-track timelapse** — every east night frame where the moon is visible is cropped around the moon and stitched into a short mp4 (the moon roughly held still while clouds and stars drift past)
- **Monthly moon-phase close-ups** — one composite per phase (full moon, first quarter, third quarter), framed as if east took it through a 65× telephoto. The sky/halo/parallactic-angle/timing are real-from-east; the lunar surface texture is borrowed from a cached high-res reference (no software can recover detail your camera didn't capture). Posted to Mattermost.
- **Monthly moon-phase close-ups** — one full-screen image per phase (full moon, first quarter, third quarter). East acts as the witness, confirming the moon was visible in your sky during the collection window and supplying the timestamp. The image itself is a NASA SVS Dial-a-Moon render for that exact UTC hour — accurate phase, real libration, correct crater shadows — sized to fill the frame (~92% of height) on a black background, the way a long-telephoto shot looks. Posted to Mattermost.
---
@@ -303,12 +303,22 @@ python3 moon_phase.py info 2026-04-29T21:07:00Z
|---|---|---|
| Sunrise video | `SCHEDULE_SUNRISE` (default 03:00 local) | A few minutes after sunrise + `SUNRISE_POST_MIN` |
| Moon-track timelapse | `SCHEDULE_MOON_TRACK` (default 02:30 local) | ~5 min after the timer, covers the previous night |
| 🌕 Full Moon composite | `SCHEDULE_MOON_PHASE` (default 09:30 local) | 3 days after exact full moon (configurable: `MOON_FULL_POST_DELAY_DAYS`) |
| 🌓 First Quarter composite | same timer | 2 days after exact first quarter (configurable: `MOON_QUARTER_POST_DELAY_DAYS`) — best-effort, see geometry note below |
| 🌗 Third Quarter composite | same timer | 2 days after exact third quarter |
| 🌕 Full Moon close-up | `SCHEDULE_MOON_PHASE` (default 09:30 local) | 3 days after exact full moon (configurable: `MOON_FULL_POST_DELAY_DAYS`) |
| 🌓 First Quarter close-up | same timer | 2 days after exact first quarter (configurable: `MOON_QUARTER_POST_DELAY_DAYS`) — best-effort, see geometry note below |
| 🌗 Third Quarter close-up | same timer | 2 days after exact third quarter |
The moon-phase timer fires every day; the script no-ops on days that aren't a post-day for any phase, so you'll see exactly three posts per lunar cycle in Mattermost (sometimes only two if first quarter detection fails — see geometry note in `sky-cam.conf`).
### How the moon close-ups work
The phase posts are **honest composites**: east is the witness, NASA is the photographer.
- East scans the collection window (D-1 .. D+2 for full, D-1 .. D+1 for quarters), runs moon detection on each frame, and picks the moment closest to the exact phase that meets quality / altitude / illumination thresholds.
- That picked moment becomes the timestamp we send to NASA's [SVS Dial-a-Moon](https://svs.gsfc.nasa.gov/api/dialamoon/) — a free public service that returns a real-physics moon render for any UTC hour, complete with correct phase, libration, and crater shadows.
- The render is sized to fill ~92% of a 1920×1080 frame on a black background and posted to Mattermost with a caption listing the witnessed-by-east moment and the NASA attribution.
- One API call per phase event (~36/year), cached forever locally.
- If you'd rather post the NASA render every cycle regardless of weather over east, set `MOON_REQUIRE_EAST_VERIFY=false` in `sky-cam.conf`.
**Check capture status**:
```bash
systemctl --user status sky-cam-capture-east.service