From be5735867ef79597c2d68a9b8927eb708d023262 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 00:14:59 +0000 Subject: [PATCH 1/5] Remove all hardcoded deployment values; read from sky-cam.conf - sunrise_video.10s.sh: use $TIMEZONE (was hardcoded America/New_York), $SUNRISE_PRE_MIN/$SUNRISE_POST_MIN for capture window, $SUNRISE_TARGET_SECS for output duration (was wrong value 8 in a script named 10s) - fullday-video.sh: remove hardcoded FULLDAY_FPS/RETENTION_DAYS; both now come from sky-cam.conf - 4-seasons.sh, montage-mvt.sh: export TIMEZONE after sourcing conf so season_info.py subprocess picks it up via env rather than falling back to its hardcoded America/New_York default - sky-cam.conf: add SUNRISE_PRE_MIN, SUNRISE_POST_MIN, SUNRISE_TARGET_SECS, FULLDAY_FPS, RETENTION_DAYS https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- 4-seasons.sh | 1 + fullday-video.sh | 3 +-- montage-mvt.sh | 1 + sky-cam.conf | 11 +++++++++++ sunrise_video.10s.sh | 17 ++++++++--------- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/4-seasons.sh b/4-seasons.sh index 0109c1f..8502960 100755 --- a/4-seasons.sh +++ b/4-seasons.sh @@ -12,6 +12,7 @@ set -x SCRIPT_DIR="$(dirname "$(realpath "$0")")" source "$SCRIPT_DIR/sky-cam.conf" +export TIMEZONE # make it visible to season_info.py subprocess # ── Configuration ────────────────────────────────────────────────────────────── base_dir="$BASE_DIR" diff --git a/fullday-video.sh b/fullday-video.sh index 25d0ac6..e3bb633 100755 --- a/fullday-video.sh +++ b/fullday-video.sh @@ -12,8 +12,7 @@ source "$SCRIPT_DIR/sky-cam.conf" # ── Configuration ────────────────────────────────────────────────────────────── base_dir="$BASE_DIR" -FULLDAY_FPS=5 # timelapse frame rate — adjust to taste -RETENTION_DAYS=10 # full-day videos older than this are deleted +# FULLDAY_FPS and RETENTION_DAYS come from sky-cam.conf # ── Date / paths ────────────────────────────────────────────────────────────── yesterday=$(date --date="yesterday" +%Y-%m-%d) diff --git a/montage-mvt.sh b/montage-mvt.sh index 5885ff5..eac3436 100755 --- a/montage-mvt.sh +++ b/montage-mvt.sh @@ -20,6 +20,7 @@ set -euo pipefail SCRIPT_DIR="$(dirname "$(realpath "$0")")" source "$SCRIPT_DIR/sky-cam.conf" +export TIMEZONE # make it visible to season_info.py subprocess # ── Configuration ────────────────────────────────────────────────────────────── base_dir="$BASE_DIR" diff --git a/sky-cam.conf b/sky-cam.conf index 85df032..447b594 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -96,6 +96,17 @@ LATITUDE=38.123456 LONGITUDE=-97.654321 TIMEZONE=America/New_York +# ── Sunrise video tuning ────────────────────────────────────────────────────── +# How many minutes before/after sunrise to include in the daily clip. +SUNRISE_PRE_MIN=70 +SUNRISE_POST_MIN=10 +# Target duration (seconds) for the speed-adjusted sunrise video. +SUNRISE_TARGET_SECS=10 + +# ── Full-day timelapse tuning ───────────────────────────────────────────────── +FULLDAY_FPS=5 # frame rate of the timelapse video +RETENTION_DAYS=10 # delete full-day videos older than this many days + # ── Mattermost — daily sunrise upload ───────────────────────────────────────── mattermost_url=https://your-mattermost-server.example.com access_token=your-access-token-here diff --git a/sunrise_video.10s.sh b/sunrise_video.10s.sh index 0ed4db0..2119670 100644 --- a/sunrise_video.10s.sh +++ b/sunrise_video.10s.sh @@ -28,11 +28,11 @@ fi # Output the sunrise time in UTC echo "Sunrise time (UTC): $sunrise_time" -# Set the time zone to Eastern US time (America/New_York) -export TZ="America/New_York" +# Export timezone so date and subprocesses use the configured local time. +export TZ="$TIMEZONE" -# Convert sunrise time from UTC to Eastern Time (ET) -sunrise_time_et=$(TZ="America/New_York" date -d "$sunrise_time" +"%H-%M-%S") +# Convert sunrise time from UTC to local time. +sunrise_time_et=$(TZ="$TIMEZONE" date -d "$sunrise_time" +"%H-%M-%S") # Output the converted sunrise time in Eastern Time echo "Sunrise time (Eastern Time): $sunrise_time_et" @@ -46,9 +46,9 @@ time_to_seconds() { # Convert sunrise time (in Eastern Time) to seconds since midnight sunrise_seconds=$(time_to_seconds "$sunrise_time_et") -# Calculate the start and end times (60 minutes before sunrise and 15 minutes after sunrise) -start_seconds=$((sunrise_seconds - 70 * 60)) # 60 minutes before sunrise -end_seconds=$((sunrise_seconds + 10 * 60)) # 20 minutes after sunrise +# Calculate the capture window around sunrise. +start_seconds=$((sunrise_seconds - SUNRISE_PRE_MIN * 60)) +end_seconds=$((sunrise_seconds + SUNRISE_POST_MIN * 60)) # Output the start and end times in seconds for debugging echo "Start seconds: $start_seconds" @@ -110,8 +110,7 @@ echo "Initial video duration: $video_duration" IFS=':' read -r hours minutes seconds <<< $(echo $video_duration | cut -d '.' -f1) # Extract time total_seconds=$(($hours * 3600 + $minutes * 60 + $seconds)) # Convert to total seconds -# Target video duration: 10 seconds -target_duration=8 +target_duration=$SUNRISE_TARGET_SECS # Calculate the speed-up factor to make the video fit into the target duration of 10 seconds speed_up_factor=$(echo "scale=3; $total_seconds / $target_duration" | bc) From d20a0d94ae436708a6469e03cf7b67c0d0a80d8f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 00:19:59 +0000 Subject: [PATCH 2/5] Fix sunrise output filename to reflect SUNRISE_TARGET_SECS from conf The output video was always named -sunrise-10s.mp4 regardless of the configured duration. Both sunrise_video.10s.sh and sunrise2mm.py now derive the filename from SUNRISE_TARGET_SECS so changing it in conf produces correctly named files that the uploader still finds. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- sunrise2mm.py | 4 ++-- sunrise_video.10s.sh | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sunrise2mm.py b/sunrise2mm.py index 9bafcfe..9f6240d 100644 --- a/sunrise2mm.py +++ b/sunrise2mm.py @@ -53,8 +53,8 @@ if not os.path.isdir(output_dir): print(f"Error: The directory {output_dir} does not exist. The video may not have been created yet.") exit(1) -# Find the sunrise video file for today (e.g., 2024-11-05-sunrise-10s.mp4) -final_video_file = os.path.join(output_dir, f"{today_date_str}-sunrise-10s.mp4") +target_secs = config.get('SUNRISE_TARGET_SECS', '10') +final_video_file = os.path.join(output_dir, f"{today_date_str}-sunrise-{target_secs}s.mp4") # Debugging: print the full path of the video file to make sure it's correct print(f"Looking for video file: {final_video_file}") diff --git a/sunrise_video.10s.sh b/sunrise_video.10s.sh index 2119670..70b9485 100644 --- a/sunrise_video.10s.sh +++ b/sunrise_video.10s.sh @@ -112,15 +112,14 @@ total_seconds=$(($hours * 3600 + $minutes * 60 + $seconds)) # Convert to total target_duration=$SUNRISE_TARGET_SECS -# Calculate the speed-up factor to make the video fit into the target duration of 10 seconds speed_up_factor=$(echo "scale=3; $total_seconds / $target_duration" | bc) echo "Calculated speed-up factor: $speed_up_factor" # Output filename for the second movie (speed-adjusted) -final_video="$output_dir/$current_date-sunrise-10s.mp4" +final_video="$output_dir/$current_date-sunrise-${SUNRISE_TARGET_SECS}s.mp4" # Apply the speed adjustment using the setpts filter -echo "Adjusting video speed to target duration of 10 seconds..." +echo "Adjusting video speed to ${SUNRISE_TARGET_SECS}s..." ffmpeg -i "$first_movie" -filter:v "setpts=PTS/$speed_up_factor" -y "$final_video" # Check the duration of the adjusted video From 3addb06ce8792e7c8b3e584cf8e855aa687edd0a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 00:26:40 +0000 Subject: [PATCH 3/5] Rename sunrise output to daily-sunrise.mp4 (duration-agnostic) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Video duration is still controlled by SUNRISE_TARGET_SECS in conf, but the filename no longer encodes it — so changing the duration doesn't break anything and the name stays stable day to day. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- sunrise2mm.py | 3 +-- sunrise_video.10s.sh | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sunrise2mm.py b/sunrise2mm.py index 9f6240d..6b3c0d0 100644 --- a/sunrise2mm.py +++ b/sunrise2mm.py @@ -53,8 +53,7 @@ if not os.path.isdir(output_dir): print(f"Error: The directory {output_dir} does not exist. The video may not have been created yet.") exit(1) -target_secs = config.get('SUNRISE_TARGET_SECS', '10') -final_video_file = os.path.join(output_dir, f"{today_date_str}-sunrise-{target_secs}s.mp4") +final_video_file = os.path.join(output_dir, f"{today_date_str}-daily-sunrise.mp4") # Debugging: print the full path of the video file to make sure it's correct print(f"Looking for video file: {final_video_file}") diff --git a/sunrise_video.10s.sh b/sunrise_video.10s.sh index 70b9485..04082bd 100644 --- a/sunrise_video.10s.sh +++ b/sunrise_video.10s.sh @@ -116,7 +116,7 @@ speed_up_factor=$(echo "scale=3; $total_seconds / $target_duration" | bc) echo "Calculated speed-up factor: $speed_up_factor" # Output filename for the second movie (speed-adjusted) -final_video="$output_dir/$current_date-sunrise-${SUNRISE_TARGET_SECS}s.mp4" +final_video="$output_dir/$current_date-daily-sunrise.mp4" # Apply the speed adjustment using the setpts filter echo "Adjusting video speed to ${SUNRISE_TARGET_SECS}s..." From 4ca1f579d233844aa135bb7b19bd8ea595662ce2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 00:52:24 +0000 Subject: [PATCH 4/5] =?UTF-8?q?Rename=20sunrise=5Fvideo.10s.sh=20=E2=86=92?= =?UTF-8?q?=20daily=5Fsunrise=5Fvideo.sh?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Name no longer implies a fixed duration. Updated all references: install.sh, sky-cam.conf script map, systemd/sky-cam-sunrise.service. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- sunrise_video.10s.sh => daily_sunrise_video.sh | 0 install.sh | 2 +- sky-cam.conf | 2 +- systemd/sky-cam-sunrise.service | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename sunrise_video.10s.sh => daily_sunrise_video.sh (100%) diff --git a/sunrise_video.10s.sh b/daily_sunrise_video.sh similarity index 100% rename from sunrise_video.10s.sh rename to daily_sunrise_video.sh diff --git a/install.sh b/install.sh index b3e16d8..0dfb66d 100755 --- a/install.sh +++ b/install.sh @@ -77,7 +77,7 @@ echo " wrote sky-cam-notify-failure@.service" # Sunrise video → Mattermost (run after sunrise window ends) write_service "sky-cam-sunrise" \ "daily sunrise video → Mattermost" \ - "sunrise_video.10s.sh" \ + "daily_sunrise_video.sh" \ "After=network-online.target\nWants=network-online.target\n" write_timer "sky-cam-sunrise" "daily sunrise video" "*-*-* 09:00:00" diff --git a/sky-cam.conf b/sky-cam.conf index 447b594..591546c 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -37,7 +37,7 @@ # ----------------------------------------------------------------------------- # # You run / schedule: -# sunrise_video.10s.sh — daily at 09:00 (via systemd) +# daily_sunrise_video.sh — daily at 09:00 (via systemd) # grabs today's sunrise images, makes a 10-second # video, uploads it to Mattermost # diff --git a/systemd/sky-cam-sunrise.service b/systemd/sky-cam-sunrise.service index 2f58c2d..6467355 100644 --- a/systemd/sky-cam-sunrise.service +++ b/systemd/sky-cam-sunrise.service @@ -7,6 +7,6 @@ OnFailure=sky-cam-notify-failure@%n.service [Service] Type=oneshot # ── Edit this path ──────────────────────────────────────────────────────────── -ExecStart=/home/motion/drives/local-2tb/sunrise-scripts/sunrise_video.10s.sh +ExecStart=/home/motion/drives/local-2tb/sunrise-scripts/daily_sunrise_video.sh StandardOutput=journal StandardError=journal From f8c1b4522da16dc1ba46f561a642ddfb39d660ff Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Apr 2026 00:59:31 +0000 Subject: [PATCH 5/5] Add file dependency map to sky-cam.conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documents who calls whom and exactly which files to update if any script is renamed — so future-you doesn't have to grep. https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- sky-cam.conf | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/sky-cam.conf b/sky-cam.conf index 591546c..57b1d4a 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -72,8 +72,76 @@ # Helpers (called by the scripts above, not run directly): # notify.sh — sends notifications via ntfy / email / Mattermost # season_info.py — outputs astronomical season/movement/year for a date -# sunrise.py — outputs today's sunrise time (used by sunrise_video) +# sunrise.py — outputs today's sunrise time (used by daily_sunrise_video) # sunrise2mm.py — uploads the sunrise video to Mattermost +# sunrise_overlay.py — burns a timestamp overlay onto the sunrise video +# +# ----------------------------------------------------------------------------- +# FILE DEPENDENCIES — who calls whom, and what to update if you rename a file +# ----------------------------------------------------------------------------- +# +# sky-cam.conf (this file) +# ← sourced by every .sh script; read by sunrise.py, sunrise2mm.py +# → if renamed: update the 'source' line at the top of ALL scripts +# (don't rename it — just edit it in place) +# +# install.sh +# ← run manually; reads this conf +# → if renamed: update the note at the top of this conf file only +# generates → systemd unit files (sky-cam-*.service / .timer) +# and sky-cam-notify-failure@.service +# +# daily_sunrise_video.sh +# ← called by systemd sky-cam-sunrise.timer (09:00) +# → if renamed: update install.sh (write_service call, line ~80) +# then re-run install.sh to regenerate the unit +# calls → sunrise.py, sunrise_overlay.py, sunrise2mm.py +# +# 4-seasons.sh +# ← called by systemd sky-cam-4seasons.timer (01:00) +# → if renamed: update install.sh (write_service call, line ~86) +# then re-run install.sh +# calls → season_info.py, montage-mvt.sh +# +# fullday-video.sh +# ← called by systemd sky-cam-fullday.timer (02:00) +# → if renamed: update install.sh (write_service call, line ~93) +# then re-run install.sh +# +# montage-mvt.sh +# ← called by 4-seasons.sh on the last day of each movement +# → if renamed: update 4-seasons.sh (the exec line near the bottom) +# calls → season_info.py, notify.sh, year-end-join.sh +# +# year-end-join.sh +# ← called by montage-mvt.sh at end of Autumn Mvt 3 +# → if renamed: update montage-mvt.sh (the exec line at the bottom) +# calls → notify.sh +# +# notify.sh +# ← called by montage-mvt.sh, year-end-join.sh +# also referenced in install.sh for the OnFailure= failure template +# → if renamed: update montage-mvt.sh, year-end-join.sh, install.sh +# +# season_info.py +# ← called by 4-seasons.sh and montage-mvt.sh +# → if renamed: update 4-seasons.sh and montage-mvt.sh (the eval lines) +# +# sunrise.py +# ← called by daily_sunrise_video.sh +# → if renamed: update daily_sunrise_video.sh +# +# sunrise_overlay.py +# ← called by daily_sunrise_video.sh +# → if renamed: update daily_sunrise_video.sh +# +# sunrise2mm.py +# ← called by daily_sunrise_video.sh +# → if renamed: update daily_sunrise_video.sh +# +# stitch-cameras.py +# ← run manually only; no script calls it +# → safe to rename with no other changes needed # # =============================================================================