From 74a74570fcb9dede7da3710d823ab624db81f3a0 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Apr 2026 13:30:02 +0000 Subject: [PATCH] Move location/music/ntfy config to .env; add paths to notifications MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sky-cam.conf: - MUSIC_DIR now uses override pattern (MUSIC_DIR="${MUSIC_DIR:-$SCRIPT_DIR/music}") so the real path can be set in .env without hardcoding it - LATITUDE/LONGITUDE use override pattern; set real coords in .env to keep location private and out of git - NTFY_URL now uses override pattern with empty default; set in .env - NTFY_ENABLED moved out of comments into active config with false default sunrise.py: - Reads .env after sky-cam.conf so .env values override (same source order as sky-cam.conf itself) - Handles ${VAR:-default} bash syntax when parsing sky-cam.conf values All completion notifications now include the full output file path so you can tell at a glance where the file landed: - daily_sunrise_video.sh: "filename — Xs, sunrise at HH:MM | /full/path" - 4-seasons.sh: "filename — Xs | /full/path" - montage-mvt.sh: "filename | checks | /full/path | verify: ..." - year-end-join.sh: "filename — Xmin | /full/path" (also adds [cam] to title) install.sh .env.example now includes LATITUDE, LONGITUDE, MUSIC_DIR, NTFY_URL https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ --- 4-seasons.sh | 2 +- daily_sunrise_video.sh | 2 +- install.sh | 13 ++++++++++++- montage-mvt.sh | 2 +- sky-cam.conf | 14 ++++++++------ sunrise.py | 30 ++++++++++++++++++++++-------- year-end-join.sh | 4 ++-- 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/4-seasons.sh b/4-seasons.sh index 510c738..23bf3da 100755 --- a/4-seasons.sh +++ b/4-seasons.sh @@ -131,7 +131,7 @@ if awk "BEGIN{exit !($drift > 0.5)}"; then fi "$SCRIPT_DIR/notify.sh" "[$CAM_NAME] $SEASON Mvt$MVT_NUM Day$DAY_OF_MVT/$DAYS_IN_MVT saved ($yesterday)" \ - "$(basename "$final_file") — ${adjusted}s" || true + "$(basename "$final_file") — ${adjusted}s | $final_file" || true # ── Auto-trigger montage on last day of movement ────────────────────────────── if [ "$IS_LAST_DAY" = "true" ]; then diff --git a/daily_sunrise_video.sh b/daily_sunrise_video.sh index e398e31..e1795d6 100755 --- a/daily_sunrise_video.sh +++ b/daily_sunrise_video.sh @@ -336,7 +336,7 @@ if $step3b_ok; then if ! $TEST_MODE; then [ -f "${cam_audio:-}" ] && rm -f "${cam_audio:-}" "$SCRIPT_DIR/notify.sh" "Sunrise ready: $current_date" \ - "$(basename "$final_video") — ${actual_dur}s, sunrise at ${SR_TIME}" || true + "$(basename "$final_video") — ${actual_dur}s, sunrise at ${SR_TIME} | $final_video" || true # ── Rolling retention ───────────────────────────────────────────────── retain="${SUNRISE_RETENTION_DAYS:-10}" diff --git a/install.sh b/install.sh index f2088bd..3690adb 100755 --- a/install.sh +++ b/install.sh @@ -264,12 +264,23 @@ env_example="$HERE/.env.example" echo "CAM_RTSP_${cam}='rtsp://admin:PASSWORD@192.168.1.XXX:554/stream1'" done echo "" + echo "# Location — used by sunrise.py to calculate sunrise time each day." + echo "# Right-click your location in Google Maps to get coordinates." + echo "LATITUDE=0.0000" + echo "LONGITUDE=0.0000" + echo "" + echo "# Music directory — path to your Four Seasons music files." + echo "# Files must be named so that the season and Mvt number appear in the filename," + echo "# e.g. 'Vivaldi_Spring_Mvt1.mp3'. Defaults to a 'music' subfolder next to the scripts." + echo "# MUSIC_DIR=/path/to/your/music/4 Seasons" + echo "" echo "# Mattermost upload" echo "mattermost_url=https://your-mattermost-server.example.com" echo "access_token=your-access-token-here" echo "channel_id=your-daily-upload-channel-id-here" echo "" - echo "# Notifications (uncomment whichever you use)" + echo "# Notifications" + echo "# ntfy — set NTFY_ENABLED=true in sky-cam.conf, then set your topic URL here:" echo "#NTFY_URL=https://ntfy.sh/your-topic" echo "#EMAIL_TO=you@example.com" echo "#MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here" diff --git a/montage-mvt.sh b/montage-mvt.sh index 430279c..3d6812d 100755 --- a/montage-mvt.sh +++ b/montage-mvt.sh @@ -222,7 +222,7 @@ if ffmpeg -loglevel warning \ "$SCRIPT_DIR/notify.sh" \ "Montage ready: $SEASON Mvt $MVT_NUM ($ASTRO_YEAR) [$CAM_NAME]" \ - "$(basename "$output_file") | $checks | verify: ./verify-mvt.sh $ASTRO_YEAR $SEASON $MVT_NUM $CAM_NAME" \ + "$(basename "$output_file") | $checks | $output_file | verify: ./verify-mvt.sh $ASTRO_YEAR $SEASON $MVT_NUM $CAM_NAME" \ || true else mv "$sped_file" "$output_file" diff --git a/sky-cam.conf b/sky-cam.conf index fdf6bc0..f418eaa 100644 --- a/sky-cam.conf +++ b/sky-cam.conf @@ -149,7 +149,7 @@ SCRIPT_DIR="${SCRIPT_DIR:-$(dirname "$(realpath "${BASH_SOURCE[0]}")")}" # an external drive or network mount (recommended for production). BASE_DIR="${BASE_DIR:-$SCRIPT_DIR/data}" MOVIES_DIR="${MOVIES_DIR:-$BASE_DIR/movies}" # override if videos live on a different drive -MUSIC_DIR="/home/motion/drives/local-2tb/music/4 Seasons" +MUSIC_DIR="${MUSIC_DIR:-$SCRIPT_DIR/music}" # ── Location & timezone ─────────────────────────────────────────────────────── # Used by sunrise.py to calculate sunrise time each day. @@ -162,9 +162,11 @@ MUSIC_DIR="/home/motion/drives/local-2tb/music/4 Seasons" # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones # (use the value in the "TZ identifier" column, e.g. America/Chicago) # -LATITUDE=25.0000 -LONGITUDE=-38.0000 -TIMEZONE=America/New_York +# Set your real values in .env — these placeholder defaults keep the file +# shareable without leaking your exact location. +LATITUDE="${LATITUDE:-25.0000}" +LONGITUDE="${LONGITUDE:-0.0000}" +TIMEZONE="${TIMEZONE:-America/New_York}" # ── Cameras ─────────────────────────────────────────────────────────────────── # List every camera name here (space-separated inside the parentheses). @@ -334,8 +336,8 @@ AMBIENT_RETENTION_DAYS=30 # delete files older than this; 0 = keep # ntfy — push notifications, zero signup for self-hosted or free cloud tier: # Self-hosted: https://docs.ntfy.sh/install/ # Cloud: pick any topic name at ntfy.sh (no account needed) -#NTFY_ENABLED=true -#NTFY_URL=https://ntfy.sh/your-topic-here +NTFY_ENABLED="${NTFY_ENABLED:-false}" +NTFY_URL="${NTFY_URL:-}" # set in .env — keeps your topic URL out of git # Email — requires the 'mail' command (package: mailutils or s-nail). # Configure outbound SMTP via /etc/ssmtp/ssmtp.conf or msmtp. diff --git a/sunrise.py b/sunrise.py index 5d2fbc1..9db1156 100755 --- a/sunrise.py +++ b/sunrise.py @@ -1,26 +1,40 @@ +#!/usr/bin/env python3 from datetime import datetime import pathlib +import re + import pytz from suntime import Sun -# Locate sky-cam.conf next to this script (works regardless of cwd). _here = pathlib.Path(__file__).resolve().parent def _read_conf(path): conf = {} - with open(path) as f: - for line in f: - line = line.strip() - if line and not line.startswith('#') and '=' in line: + try: + with open(path) as f: + for line in f: + line = line.strip() + if not line or line.startswith('#') or '=' not in line: + continue k, v = line.split('=', 1) - conf[k.strip()] = v.strip() + k = k.strip() + v = v.strip().strip('"').strip("'") + # Extract default from bash ${VAR:-default} pattern + m = re.match(r'^\$\{[^}]+:-([^}]*)\}$', v) + if m: + v = m.group(1).strip('"').strip("'") + conf[k] = v + except FileNotFoundError: + pass return conf conf = _read_conf(_here / 'sky-cam.conf') +# .env overrides sky-cam.conf — mirrors the sourcing order at the bottom of sky-cam.conf +conf.update(_read_conf(_here / '.env')) for _key in ('LATITUDE', 'LONGITUDE', 'TIMEZONE'): - if _key not in conf: - raise SystemExit(f"sunrise.py: {_key} not set in sky-cam.conf") + if not conf.get(_key): + raise SystemExit(f"sunrise.py: {_key} not set in sky-cam.conf or .env") latitude = float(conf['LATITUDE']) longitude = float(conf['LONGITUDE']) diff --git a/year-end-join.sh b/year-end-join.sh index 3ae21f8..9b8311f 100755 --- a/year-end-join.sh +++ b/year-end-join.sh @@ -92,6 +92,6 @@ fi # ── Notify ──────────────────────────────────────────────────────────────────── "$SCRIPT_DIR/notify.sh" \ - "Four Seasons $ASTRO_YEAR complete" \ - "${CAM_NAME}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements)" \ + "Four Seasons $ASTRO_YEAR complete [$CAM_NAME]" \ + "${CAM_NAME}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements) | $output_file" \ || true