Move location/music/ntfy config to .env; add paths to notifications
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
This commit is contained in:
+1
-1
@@ -131,7 +131,7 @@ if awk "BEGIN{exit !($drift > 0.5)}"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
"$SCRIPT_DIR/notify.sh" "[$CAM_NAME] $SEASON Mvt$MVT_NUM Day$DAY_OF_MVT/$DAYS_IN_MVT saved ($yesterday)" \
|
"$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 ──────────────────────────────
|
# ── Auto-trigger montage on last day of movement ──────────────────────────────
|
||||||
if [ "$IS_LAST_DAY" = "true" ]; then
|
if [ "$IS_LAST_DAY" = "true" ]; then
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ if $step3b_ok; then
|
|||||||
if ! $TEST_MODE; then
|
if ! $TEST_MODE; then
|
||||||
[ -f "${cam_audio:-}" ] && rm -f "${cam_audio:-}"
|
[ -f "${cam_audio:-}" ] && rm -f "${cam_audio:-}"
|
||||||
"$SCRIPT_DIR/notify.sh" "Sunrise ready: $current_date" \
|
"$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 ─────────────────────────────────────────────────
|
# ── Rolling retention ─────────────────────────────────────────────────
|
||||||
retain="${SUNRISE_RETENTION_DAYS:-10}"
|
retain="${SUNRISE_RETENTION_DAYS:-10}"
|
||||||
|
|||||||
+12
-1
@@ -264,12 +264,23 @@ env_example="$HERE/.env.example"
|
|||||||
echo "CAM_RTSP_${cam}='rtsp://admin:PASSWORD@192.168.1.XXX:554/stream1'"
|
echo "CAM_RTSP_${cam}='rtsp://admin:PASSWORD@192.168.1.XXX:554/stream1'"
|
||||||
done
|
done
|
||||||
echo ""
|
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 upload"
|
||||||
echo "mattermost_url=https://your-mattermost-server.example.com"
|
echo "mattermost_url=https://your-mattermost-server.example.com"
|
||||||
echo "access_token=your-access-token-here"
|
echo "access_token=your-access-token-here"
|
||||||
echo "channel_id=your-daily-upload-channel-id-here"
|
echo "channel_id=your-daily-upload-channel-id-here"
|
||||||
echo ""
|
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 "#NTFY_URL=https://ntfy.sh/your-topic"
|
||||||
echo "#EMAIL_TO=you@example.com"
|
echo "#EMAIL_TO=you@example.com"
|
||||||
echo "#MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here"
|
echo "#MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here"
|
||||||
|
|||||||
+1
-1
@@ -222,7 +222,7 @@ if ffmpeg -loglevel warning \
|
|||||||
|
|
||||||
"$SCRIPT_DIR/notify.sh" \
|
"$SCRIPT_DIR/notify.sh" \
|
||||||
"Montage ready: $SEASON Mvt $MVT_NUM ($ASTRO_YEAR) [$CAM_NAME]" \
|
"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
|
|| true
|
||||||
else
|
else
|
||||||
mv "$sped_file" "$output_file"
|
mv "$sped_file" "$output_file"
|
||||||
|
|||||||
+8
-6
@@ -149,7 +149,7 @@ SCRIPT_DIR="${SCRIPT_DIR:-$(dirname "$(realpath "${BASH_SOURCE[0]}")")}"
|
|||||||
# an external drive or network mount (recommended for production).
|
# an external drive or network mount (recommended for production).
|
||||||
BASE_DIR="${BASE_DIR:-$SCRIPT_DIR/data}"
|
BASE_DIR="${BASE_DIR:-$SCRIPT_DIR/data}"
|
||||||
MOVIES_DIR="${MOVIES_DIR:-$BASE_DIR/movies}" # override if videos live on a different drive
|
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 ───────────────────────────────────────────────────────
|
# ── Location & timezone ───────────────────────────────────────────────────────
|
||||||
# Used by sunrise.py to calculate sunrise time each day.
|
# 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
|
# https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
# (use the value in the "TZ identifier" column, e.g. America/Chicago)
|
# (use the value in the "TZ identifier" column, e.g. America/Chicago)
|
||||||
#
|
#
|
||||||
LATITUDE=25.0000
|
# Set your real values in .env — these placeholder defaults keep the file
|
||||||
LONGITUDE=-38.0000
|
# shareable without leaking your exact location.
|
||||||
TIMEZONE=America/New_York
|
LATITUDE="${LATITUDE:-25.0000}"
|
||||||
|
LONGITUDE="${LONGITUDE:-0.0000}"
|
||||||
|
TIMEZONE="${TIMEZONE:-America/New_York}"
|
||||||
|
|
||||||
# ── Cameras ───────────────────────────────────────────────────────────────────
|
# ── Cameras ───────────────────────────────────────────────────────────────────
|
||||||
# List every camera name here (space-separated inside the parentheses).
|
# 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:
|
# ntfy — push notifications, zero signup for self-hosted or free cloud tier:
|
||||||
# Self-hosted: https://docs.ntfy.sh/install/
|
# Self-hosted: https://docs.ntfy.sh/install/
|
||||||
# Cloud: pick any topic name at ntfy.sh (no account needed)
|
# Cloud: pick any topic name at ntfy.sh (no account needed)
|
||||||
#NTFY_ENABLED=true
|
NTFY_ENABLED="${NTFY_ENABLED:-false}"
|
||||||
#NTFY_URL=https://ntfy.sh/your-topic-here
|
NTFY_URL="${NTFY_URL:-}" # set in .env — keeps your topic URL out of git
|
||||||
|
|
||||||
# Email — requires the 'mail' command (package: mailutils or s-nail).
|
# Email — requires the 'mail' command (package: mailutils or s-nail).
|
||||||
# Configure outbound SMTP via /etc/ssmtp/ssmtp.conf or msmtp.
|
# Configure outbound SMTP via /etc/ssmtp/ssmtp.conf or msmtp.
|
||||||
|
|||||||
+22
-8
@@ -1,26 +1,40 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import pathlib
|
import pathlib
|
||||||
|
import re
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from suntime import Sun
|
from suntime import Sun
|
||||||
|
|
||||||
# Locate sky-cam.conf next to this script (works regardless of cwd).
|
|
||||||
_here = pathlib.Path(__file__).resolve().parent
|
_here = pathlib.Path(__file__).resolve().parent
|
||||||
|
|
||||||
def _read_conf(path):
|
def _read_conf(path):
|
||||||
conf = {}
|
conf = {}
|
||||||
with open(path) as f:
|
try:
|
||||||
for line in f:
|
with open(path) as f:
|
||||||
line = line.strip()
|
for line in f:
|
||||||
if line and not line.startswith('#') and '=' in line:
|
line = line.strip()
|
||||||
|
if not line or line.startswith('#') or '=' not in line:
|
||||||
|
continue
|
||||||
k, v = line.split('=', 1)
|
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
|
return conf
|
||||||
|
|
||||||
conf = _read_conf(_here / 'sky-cam.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'):
|
for _key in ('LATITUDE', 'LONGITUDE', 'TIMEZONE'):
|
||||||
if _key not in conf:
|
if not conf.get(_key):
|
||||||
raise SystemExit(f"sunrise.py: {_key} not set in sky-cam.conf")
|
raise SystemExit(f"sunrise.py: {_key} not set in sky-cam.conf or .env")
|
||||||
|
|
||||||
latitude = float(conf['LATITUDE'])
|
latitude = float(conf['LATITUDE'])
|
||||||
longitude = float(conf['LONGITUDE'])
|
longitude = float(conf['LONGITUDE'])
|
||||||
|
|||||||
+2
-2
@@ -92,6 +92,6 @@ fi
|
|||||||
|
|
||||||
# ── Notify ────────────────────────────────────────────────────────────────────
|
# ── Notify ────────────────────────────────────────────────────────────────────
|
||||||
"$SCRIPT_DIR/notify.sh" \
|
"$SCRIPT_DIR/notify.sh" \
|
||||||
"Four Seasons $ASTRO_YEAR complete" \
|
"Four Seasons $ASTRO_YEAR complete [$CAM_NAME]" \
|
||||||
"${CAM_NAME}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements)" \
|
"${CAM_NAME}-${ASTRO_YEAR}.mp4 — ${total_min} minutes ($found movements) | $output_file" \
|
||||||
|| true
|
|| true
|
||||||
|
|||||||
Reference in New Issue
Block a user