Covers: installing git, first clone, pulling updates, stash vs reset
--hard, checking diffs, switching branches, and a note that .env is
never touched by git pulls.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
- verify-mvt.sh: remove dead first _info= line (used MVT_START before
defined); fix JPEG size loop to accumulate bytes correctly and display
human-readable total; show size in delete confirmation
- montage-mvt.sh: grep -c uses || echo 0 instead of || true to be
unambiguous about the no-match value under set -e
- capture.sh, capture-watchdog.sh: require camera name arg, remove
silent SUNRISE_CAM fallback
- migrate-seasons.sh: require --cam arg, error if missing
- README.md, sky-cam.conf: remove stale fullday-video.sh references;
README pipeline diagram updated to show verify-mvt.sh
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
No script defaults to SUNRISE_CAM (east) for the seasons pipeline.
Every direction is treated equally — camera name is a required arg,
not an optional override.
- 4-seasons.sh: $1 required, exits with usage if missing
- montage-mvt.sh: arg order changed to <cam> [date]; $1 required
- year-end-join.sh: $2 (cam) required
- verify-mvt.sh: $4 (cam) required
- migrate-seasons.sh: example commands updated to new arg order
- README.md: montage-mvt.sh examples updated
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
capture-watchdog.sh: long-running script that checks the newest JPEG mtime
in each camera's output directory every CAPTURE_STALE_SECS/3 seconds (min 5s).
Sends a stall notification via notify.sh if no new frame has arrived within
CAPTURE_STALE_SECS. Sends a recovery notification once new frames resume.
Only alerts if the camera was previously working (avoids false positives on
first start or overnight before the first frame of the day).
sky-cam.conf: CAPTURE_STALE_SECS=30 added next to CAPTURE_INTERVAL with a
note that it should be at least 2x the interval.
install.sh: generates sky-cam-watchdog-<cam>.service for every camera that
has a RTSP URL configured. The watchdog service starts after and alongside
the capture service, restarts on failure, and is enabled/started with the
same loop as the capture service.
README.md: note about watchdog and journalctl command for its logs.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
montage-mvt.sh, year-end-join.sh: CAM_NAME fallback referenced undefined
\$CAM_NAME — crashes under set -euo pipefail on manual runs without args.
Fixed to fall back to \$SUNRISE_CAM (same fix applied earlier to other scripts).
notify.sh: Mattermost notification guard only checked MM_NOTIFY_CHANNEL_ID,
not mattermost_url or access_token. If those are unset, curl would send a
malformed request silently. Added guards for all three required values.
install.sh: seasons/fullday service units had literal \n in After=/Wants=
lines because bash does not interpret \n in heredoc variable expansions.
Changed to \$'...' syntax so actual newlines are written, making valid
systemd unit files. Also: audio capture timer now uses \$SCHEDULE_SUNRISE
instead of hardcoded 03:00, keeping it in sync if the user changes the
schedule.
sunrise-audio-capture.sh: record_start_sec could theoretically go negative
(sunrise very early + large SUNRISE_TARGET_SECS). Added floor-at-zero guard.
daily_sunrise_video.sh: added comment explaining why audio_offset is always 0.
README.md: fix CAM_RTSP_sunrise example to CAM_RTSP_east.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
Cameras are now named by direction (east, north, south, west) throughout
config defaults, examples, and documentation. The config key SUNRISE_CAM
is unchanged — it still means 'which camera faces east and gets the sunrise
job'. Only the camera instance name value changes from 'sunrise' to 'east'.
sky-cam.conf: CAMERAS=(east), SUNRISE_CAM=east, SCHEDULE_*_east,
example comments updated to show all four compass points.
README.md: all command examples updated (4-seasons.sh east, journalctl
sky-cam-capture-east, etc.) — phenomenon references ('sunrise window',
'sunrise time') left unchanged.
bootstrap.sh: example updated to show compass directions.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
- Step 1 is now dependency installation (apt + pip3) before anything else
- SCRIPT_DIR removed from config table (auto-detected)
- RTSP/Mattermost credentials moved to .env section (step 4)
- install.sh now shown as generating .env.example before credentials are filled in
- Schedule settings explained: SEASONS/FULLDAY process yesterday; SUNRISE waits internally
- How it works: audio capture described as SUNRISE_TARGET_SECS centred on sunrise
- daily_sunrise_video.sh pipeline updated: steps 3a/3b shown separately
- Resilience section replaced with four-tier audio/overlay matrix table
- Camera audio section updated: exact duration, centred split, odd-second rule
- Manual operations: examples use explicit camera name argument
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
daily_sunrise_video.sh: use \$MOVIES_DIR instead of \$BASE_DIR/movies so the
override in sky-cam.conf is respected when videos live on a separate drive.
capture.sh: default camera name falls back to \$SUNRISE_CAM (not the
undefined \$CAM_NAME) when no argument is passed.
sunrise2mm.py: also loads .env after sky-cam.conf so Mattermost credentials
moved to .env are actually visible to the upload script.
sunrise.py: raise a clear error message when LATITUDE/LONGITUDE/TIMEZONE
are missing from sky-cam.conf instead of an opaque KeyError.
4-seasons.sh, montage-mvt.sh: capture season_info.py output before eval so
a Python failure exits cleanly with a diagnostic message rather than
silently continuing with undefined variables.
bootstrap.sh: add system package install step (ffmpeg bc fonts-dejavu) and
show the .env setup step after install.sh generates .env.example.
README.md: correct Python package names and add fonts-dejavu dependency.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
daily_sunrise_video.sh: derive CAM_NAME from $1 (defaulting to SUNRISE_CAM)
instead of an undefined variable; this was causing empty image/output paths.
install.sh: pass $SUNRISE_CAM as argument to daily_sunrise_video.sh so it
matches the pattern used by every other per-camera script.
sunrise2mm.py: use SUNRISE_CAM config key (not the undefined CAM_NAME) to
locate the output directory; fixes silent path mismatch on non-default names.
4-seasons.sh: remove stray `set -x` that was flooding systemd logs with
shell trace output.
README.md: correct Python dependencies from `ephem` to `suntime pytz` to
match what sunrise.py actually imports.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
Removes dependency on MotionEye or any NVR software. Everything is now
CLI/ffmpeg configured entirely from sky-cam.conf.
capture.sh
Long-running systemd service (one per camera) that pulls frames from the
camera's RTSP stream at CAPTURE_INTERVAL seconds, writing HH-MM-SS.jpg
into BASE_DIR/<cam>/YYYY-MM-DD/. Restarts at midnight for the new date
directory; auto-reconnects on camera disconnect.
sunrise-audio-capture.sh
One-shot service triggered at 03:00. Waits until (sunrise minus
SUNRISE_PRE_MIN minus AUDIO_PRE_BUFFER_MIN), then records the RTSP audio
stream for the full sunrise window. Output deleted after mixing.
daily_sunrise_video.sh
Step 3 now mixes in sunrise-audio.m4a when AUDIO_ENABLED=true and the
file exists. Audio is centred on actual sunrise time at natural speed
while the video plays as the sped-up timelapse. Uses filter_complex
when audio is present (can't combine -vf with -filter_complex).
install.sh
Generates sky-cam-capture-<cam>.service for each camera with CAM_RTSP_<cam>
set, and sky-cam-audio-capture.{service,timer} when AUDIO_ENABLED=true.
sky-cam.conf
New settings: CAM_RTSP_<cam>, CAPTURE_INTERVAL, AUDIO_ENABLED,
AUDIO_PRE_BUFFER_MIN, CAPTURE_AUDIO_BITRATE.
https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ