Multi-camera support; schedules in conf; comment out notifications
sky-cam.conf: - CAMERAS array replaces single CAM_NAME; add a name, add its schedules, re-run install.sh — no script editing needed - SCHEDULE_SUNRISE, SCHEDULE_SEASONS_<cam>, SCHEDULE_FULLDAY_<cam> replace hardcoded times in install.sh - Notification options commented out (uncomment to enable) - Lat/lon set to mid-Atlantic (25.0, -38.0) as neutral placeholder install.sh: - Loops over CAMERAS to generate per-camera sky-cam-seasons-<cam> and sky-cam-fullday-<cam> timers with schedules from conf - Sunrise timer remains a single sky-cam-sunrise unit (SUNRISE_CAM only) fullday-video.sh, 4-seasons.sh, montage-mvt.sh, year-end-join.sh: - Each accepts camera name as an argument (systemd passes it via ExecStart) and falls back to conf default when run manually without an arg - Camera name propagates through the full call chain: 4-seasons → montage-mvt → year-end-join https://claude.ai/code/session_01C4jbd3waXG3eKZYbGUjLUQ
This commit is contained in:
+4
-1
@@ -14,6 +14,9 @@ SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
|||||||
source "$SCRIPT_DIR/sky-cam.conf"
|
source "$SCRIPT_DIR/sky-cam.conf"
|
||||||
export TIMEZONE # make it visible to season_info.py subprocess
|
export TIMEZONE # make it visible to season_info.py subprocess
|
||||||
|
|
||||||
|
# Camera name: first argument overrides conf (systemd passes it via ExecStart).
|
||||||
|
CAM_NAME="${1:-$CAM_NAME}"
|
||||||
|
|
||||||
# ── Configuration ──────────────────────────────────────────────────────────────
|
# ── Configuration ──────────────────────────────────────────────────────────────
|
||||||
base_dir="$BASE_DIR"
|
base_dir="$BASE_DIR"
|
||||||
music_base_dir="$MUSIC_DIR"
|
music_base_dir="$MUSIC_DIR"
|
||||||
@@ -102,5 +105,5 @@ if [ "$IS_LAST_DAY" = "true" ]; then
|
|||||||
echo "Last day of $SEASON Mvt $MVT_NUM — triggering montage compilation..."
|
echo "Last day of $SEASON Mvt $MVT_NUM — triggering montage compilation..."
|
||||||
# Pass $yesterday so montage-mvt.sh looks up the correct movement
|
# Pass $yesterday so montage-mvt.sh looks up the correct movement
|
||||||
# (running the next morning, "today" would already be the next movement).
|
# (running the next morning, "today" would already be the next movement).
|
||||||
"$SCRIPT_DIR/montage-mvt.sh" "$yesterday"
|
"$SCRIPT_DIR/montage-mvt.sh" "$yesterday" "$CAM_NAME"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ set -euo pipefail
|
|||||||
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
||||||
source "$SCRIPT_DIR/sky-cam.conf"
|
source "$SCRIPT_DIR/sky-cam.conf"
|
||||||
|
|
||||||
|
# Camera name: first argument overrides conf (systemd passes it via ExecStart).
|
||||||
|
CAM_NAME="${1:-$CAM_NAME}"
|
||||||
|
|
||||||
# ── Configuration ──────────────────────────────────────────────────────────────
|
# ── Configuration ──────────────────────────────────────────────────────────────
|
||||||
base_dir="$BASE_DIR"
|
base_dir="$BASE_DIR"
|
||||||
# FULLDAY_FPS and RETENTION_DAYS come from sky-cam.conf
|
# FULLDAY_FPS and RETENTION_DAYS come from sky-cam.conf
|
||||||
|
|||||||
+42
-22
@@ -6,7 +6,8 @@
|
|||||||
# ./install.sh --system # installs to /etc/systemd/system (needs sudo)
|
# ./install.sh --system # installs to /etc/systemd/system (needs sudo)
|
||||||
#
|
#
|
||||||
# Run this once after editing sky-cam.conf, and again whenever sky-cam.conf
|
# Run this once after editing sky-cam.conf, and again whenever sky-cam.conf
|
||||||
# changes (e.g. SCRIPT_DIR moves). No other file needs editing.
|
# changes (e.g. SCRIPT_DIR moves, cameras added, schedules changed).
|
||||||
|
# No other file needs editing.
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ write_service() {
|
|||||||
local unit="$1" description="$2" script="$3" extra="${4:-}"
|
local unit="$1" description="$2" script="$3" extra="${4:-}"
|
||||||
cat > "$UNIT_DIR/${unit}.service" <<EOF
|
cat > "$UNIT_DIR/${unit}.service" <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Sky-Cam ($CAM_NAME) — $description
|
Description=Sky-Cam — $description
|
||||||
${extra}OnFailure=sky-cam-notify-failure@%n.service
|
${extra}OnFailure=sky-cam-notify-failure@%n.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
@@ -50,10 +51,10 @@ write_timer() {
|
|||||||
local unit="$1" description="$2" calendar="$3"
|
local unit="$1" description="$2" calendar="$3"
|
||||||
cat > "$UNIT_DIR/${unit}.timer" <<EOF
|
cat > "$UNIT_DIR/${unit}.timer" <<EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Sky-Cam ($CAM_NAME) — $description
|
Description=Sky-Cam — $description
|
||||||
|
|
||||||
[Timer]
|
[Timer]
|
||||||
OnCalendar=$calendar
|
OnCalendar=*-*-* $calendar
|
||||||
Persistent=true
|
Persistent=true
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
@@ -73,32 +74,51 @@ ExecStart=$SCRIPT_DIR/notify.sh "sky-cam job failed: %i" "systemd unit %i failed
|
|||||||
EOF
|
EOF
|
||||||
echo " wrote sky-cam-notify-failure@.service"
|
echo " wrote sky-cam-notify-failure@.service"
|
||||||
|
|
||||||
# ── Three daily jobs ──────────────────────────────────────────────────────────
|
# ── Sunrise video — SUNRISE_CAM only ─────────────────────────────────────────
|
||||||
# Sunrise video → Mattermost (run after sunrise window ends)
|
|
||||||
write_service "sky-cam-sunrise" \
|
write_service "sky-cam-sunrise" \
|
||||||
"daily sunrise video → Mattermost" \
|
"$SUNRISE_CAM: daily sunrise video → Mattermost" \
|
||||||
"daily_sunrise_video.sh" \
|
"daily_sunrise_video.sh" \
|
||||||
"After=network-online.target\nWants=network-online.target\n"
|
"After=network-online.target\nWants=network-online.target\n"
|
||||||
write_timer "sky-cam-sunrise" "daily sunrise video" "*-*-* 09:00:00"
|
write_timer "sky-cam-sunrise" "$SUNRISE_CAM: daily sunrise video" "$SCHEDULE_SUNRISE"
|
||||||
|
|
||||||
# Four Seasons daily clip (auto-triggers montage + year-end on last days)
|
timers=(sky-cam-sunrise)
|
||||||
write_service "sky-cam-4seasons" \
|
|
||||||
"Four Seasons daily clip" \
|
|
||||||
"4-seasons.sh" \
|
|
||||||
"After=network-online.target\nWants=network-online.target\n"
|
|
||||||
write_timer "sky-cam-4seasons" "Four Seasons daily clip" "*-*-* 01:00:00"
|
|
||||||
|
|
||||||
# Full-day timelapse with 10-day retention
|
# ── Per-camera Four Seasons and full-day jobs ─────────────────────────────────
|
||||||
write_service "sky-cam-fullday" \
|
# Reads CAMERAS, SCHEDULE_SEASONS_<cam>, SCHEDULE_FULLDAY_<cam> from sky-cam.conf.
|
||||||
"full-day timelapse" \
|
# Scripts receive the camera name as $1 so they know which camera to process.
|
||||||
"fullday-video.sh"
|
for cam in "${CAMERAS[@]}"; do
|
||||||
write_timer "sky-cam-fullday" "full-day timelapse" "*-*-* 02:00:00"
|
sched_seasons_var="SCHEDULE_SEASONS_${cam}"
|
||||||
|
sched_fullday_var="SCHEDULE_FULLDAY_${cam}"
|
||||||
|
|
||||||
|
if [ -n "${!sched_seasons_var:-}" ]; then
|
||||||
|
write_service "sky-cam-seasons-${cam}" \
|
||||||
|
"${cam}: Four Seasons daily clip" \
|
||||||
|
"4-seasons.sh ${cam}" \
|
||||||
|
"After=network-online.target\nWants=network-online.target\n"
|
||||||
|
write_timer "sky-cam-seasons-${cam}" "${cam}: Four Seasons daily clip" \
|
||||||
|
"${!sched_seasons_var}"
|
||||||
|
timers+=("sky-cam-seasons-${cam}")
|
||||||
|
else
|
||||||
|
echo " WARNING: SCHEDULE_SEASONS_${cam} not set — skipping seasons timer for ${cam}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "${!sched_fullday_var:-}" ]; then
|
||||||
|
write_service "sky-cam-fullday-${cam}" \
|
||||||
|
"${cam}: full-day timelapse" \
|
||||||
|
"fullday-video.sh ${cam}"
|
||||||
|
write_timer "sky-cam-fullday-${cam}" "${cam}: full-day timelapse" \
|
||||||
|
"${!sched_fullday_var}"
|
||||||
|
timers+=("sky-cam-fullday-${cam}")
|
||||||
|
else
|
||||||
|
echo " WARNING: SCHEDULE_FULLDAY_${cam} not set — skipping fullday timer for ${cam}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# ── Reload and enable ─────────────────────────────────────────────────────────
|
# ── Reload and enable ─────────────────────────────────────────────────────────
|
||||||
echo ""
|
echo ""
|
||||||
$SC daemon-reload
|
$SC daemon-reload
|
||||||
|
|
||||||
for timer in sky-cam-sunrise sky-cam-4seasons sky-cam-fullday; do
|
for timer in "${timers[@]}"; do
|
||||||
$SC enable --now "${timer}.timer" \
|
$SC enable --now "${timer}.timer" \
|
||||||
&& echo " enabled + started ${timer}.timer" \
|
&& echo " enabled + started ${timer}.timer" \
|
||||||
|| echo " WARNING: could not enable ${timer}.timer"
|
|| echo " WARNING: could not enable ${timer}.timer"
|
||||||
@@ -108,8 +128,8 @@ echo ""
|
|||||||
echo "Done. Check status with:"
|
echo "Done. Check status with:"
|
||||||
if $SYSTEM_MODE; then
|
if $SYSTEM_MODE; then
|
||||||
echo " sudo systemctl list-timers 'sky-cam-*'"
|
echo " sudo systemctl list-timers 'sky-cam-*'"
|
||||||
echo " sudo journalctl -u sky-cam-4seasons.service -f"
|
echo " sudo journalctl -u sky-cam-seasons-${CAMERAS[0]}.service -f"
|
||||||
else
|
else
|
||||||
echo " systemctl --user list-timers 'sky-cam-*'"
|
echo " systemctl --user list-timers 'sky-cam-*'"
|
||||||
echo " journalctl --user -u sky-cam-4seasons.service -f"
|
echo " journalctl --user -u sky-cam-seasons-${CAMERAS[0]}.service -f"
|
||||||
fi
|
fi
|
||||||
|
|||||||
+5
-1
@@ -22,6 +22,10 @@ SCRIPT_DIR="$(dirname "$(realpath "$0")")"
|
|||||||
source "$SCRIPT_DIR/sky-cam.conf"
|
source "$SCRIPT_DIR/sky-cam.conf"
|
||||||
export TIMEZONE # make it visible to season_info.py subprocess
|
export TIMEZONE # make it visible to season_info.py subprocess
|
||||||
|
|
||||||
|
# Args: [date] [camera-name]
|
||||||
|
# Camera name: second argument overrides conf (passed through from 4-seasons.sh).
|
||||||
|
CAM_NAME="${2:-$CAM_NAME}"
|
||||||
|
|
||||||
# ── Configuration ──────────────────────────────────────────────────────────────
|
# ── Configuration ──────────────────────────────────────────────────────────────
|
||||||
base_dir="$BASE_DIR"
|
base_dir="$BASE_DIR"
|
||||||
music_base_dir="$MUSIC_DIR"
|
music_base_dir="$MUSIC_DIR"
|
||||||
@@ -167,5 +171,5 @@ echo "Done: $output_file"
|
|||||||
# ── Trigger year-end join on last Autumn movement ────────────────────────────
|
# ── Trigger year-end join on last Autumn movement ────────────────────────────
|
||||||
if [ "$SEASON" = "Autumn" ] && [ "$MVT_NUM" = "3" ]; then
|
if [ "$SEASON" = "Autumn" ] && [ "$MVT_NUM" = "3" ]; then
|
||||||
echo "Last movement of astronomical year $ASTRO_YEAR — triggering year-end join..."
|
echo "Last movement of astronomical year $ASTRO_YEAR — triggering year-end join..."
|
||||||
"$SCRIPT_DIR/year-end-join.sh" "$ASTRO_YEAR"
|
"$SCRIPT_DIR/year-end-join.sh" "$ASTRO_YEAR" "$CAM_NAME"
|
||||||
fi
|
fi
|
||||||
|
|||||||
+87
-62
@@ -20,13 +20,14 @@
|
|||||||
# Then edit ExecStart= in each .service file to match your SCRIPT_DIR, then:
|
# Then edit ExecStart= in each .service file to match your SCRIPT_DIR, then:
|
||||||
#
|
#
|
||||||
# systemctl --user daemon-reload
|
# systemctl --user daemon-reload
|
||||||
# systemctl --user enable --now sky-cam-sunrise.timer # 09:00 daily
|
# systemctl --user enable --now sky-cam-sunrise.timer
|
||||||
# systemctl --user enable --now sky-cam-4seasons.timer # 01:00 daily
|
# systemctl --user enable --now sky-cam-seasons-sunrise.timer
|
||||||
# systemctl --user enable --now sky-cam-fullday.timer # 02:00 daily
|
# systemctl --user enable --now sky-cam-fullday-sunrise.timer
|
||||||
|
# # one sky-cam-seasons-<cam>.timer and sky-cam-fullday-<cam>.timer per camera
|
||||||
#
|
#
|
||||||
# Check status:
|
# Check status:
|
||||||
# systemctl --user list-timers 'sky-cam-*'
|
# systemctl --user list-timers 'sky-cam-*'
|
||||||
# journalctl --user -u sky-cam-4seasons.service -f
|
# journalctl --user -u sky-cam-seasons-sunrise.service -f
|
||||||
#
|
#
|
||||||
# System-wide (replace --user with no flag, prepend sudo):
|
# System-wide (replace --user with no flag, prepend sudo):
|
||||||
# sudo cp systemd/*.service systemd/*.timer /etc/systemd/system/
|
# sudo cp systemd/*.service systemd/*.timer /etc/systemd/system/
|
||||||
@@ -37,44 +38,44 @@
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# You run / schedule:
|
# You run / schedule:
|
||||||
# daily_sunrise_video.sh — daily at 09:00 (via systemd)
|
# daily_sunrise_video.sh — daily at SCHEDULE_SUNRISE (via systemd, SUNRISE_CAM only)
|
||||||
# grabs today's sunrise images, makes a 10-second
|
# grabs images around sunrise, makes a short video,
|
||||||
# video, uploads it to Mattermost
|
# uploads it to Mattermost
|
||||||
#
|
#
|
||||||
# 4-seasons.sh — daily at 01:00 (via systemd)
|
# 4-seasons.sh <cam> — daily at SCHEDULE_SEASONS_<cam> (via systemd, per camera)
|
||||||
# makes yesterday's daily clip sized to its share
|
# makes yesterday's daily clip sized to its share
|
||||||
# of the matching Vivaldi movement's music duration;
|
# of the matching Vivaldi movement's music duration;
|
||||||
# on the last day of a movement, auto-triggers
|
# on the last day of a movement, auto-triggers
|
||||||
# montage-mvt.sh
|
# montage-mvt.sh
|
||||||
#
|
#
|
||||||
# fullday-video.sh — daily at 02:00 (via systemd)
|
# fullday-video.sh <cam> — daily at SCHEDULE_FULLDAY_<cam> (via systemd, per camera)
|
||||||
# full-day timelapse at fixed fps; deletes files
|
# full-day timelapse at fixed fps; deletes videos
|
||||||
# older than 10 days automatically
|
# older than RETENTION_DAYS automatically
|
||||||
#
|
#
|
||||||
# install.sh — run once at setup, and again if this file changes
|
# install.sh — run once at setup, and again if this file changes
|
||||||
# generates and installs systemd units from conf
|
# generates and installs systemd units from conf
|
||||||
#
|
#
|
||||||
# stitch-cameras.py — run manually when needed
|
# stitch-cameras.py — run manually when needed
|
||||||
# stitches north + sunrise into a panorama
|
# stitches north + sunrise into a panorama
|
||||||
# usage: python3 stitch-cameras.py north.jpg sunrise.jpg prefix [focal]
|
# usage: python3 stitch-cameras.py north.jpg sunrise.jpg prefix [focal]
|
||||||
#
|
#
|
||||||
# Auto-triggered (do not run directly):
|
# Auto-triggered (do not run directly):
|
||||||
# montage-mvt.sh — called by 4-seasons.sh on last day of each movement
|
# montage-mvt.sh — called by 4-seasons.sh on last day of each movement
|
||||||
# concatenates all daily clips for the movement,
|
# concatenates all daily clips for the movement,
|
||||||
# speed-adjusts to match music, overlays attribution,
|
# speed-adjusts to match music, overlays attribution,
|
||||||
# sends completion notification; on last Autumn
|
# sends completion notification; on last Autumn
|
||||||
# movement also triggers year-end-join.sh
|
# movement also triggers year-end-join.sh
|
||||||
#
|
#
|
||||||
# year-end-join.sh — called by montage-mvt.sh at end of Autumn Mvt 3
|
# year-end-join.sh — called by montage-mvt.sh at end of Autumn Mvt 3
|
||||||
# concatenates all 12 movement montages into one
|
# concatenates all 12 movement montages into one
|
||||||
# Four Seasons year video, sends notification
|
# Four Seasons year video, sends notification
|
||||||
#
|
#
|
||||||
# Helpers (called by the scripts above, not run directly):
|
# Helpers (called by the scripts above, not run directly):
|
||||||
# notify.sh — sends notifications via ntfy / email / Mattermost
|
# notify.sh — sends notifications via ntfy / email / Mattermost
|
||||||
# season_info.py — outputs astronomical season/movement/year for a date
|
# season_info.py — outputs astronomical season/movement/year for a date
|
||||||
# sunrise.py — outputs today's sunrise time (used by daily_sunrise_video)
|
# sunrise.py — outputs today's sunrise time (used by daily_sunrise_video)
|
||||||
# sunrise2mm.py — uploads the sunrise video to Mattermost
|
# sunrise2mm.py — uploads the sunrise video to Mattermost
|
||||||
# sunrise_overlay.py — burns a timestamp overlay onto the sunrise video
|
# 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
|
# FILE DEPENDENCIES — who calls whom, and what to update if you rename a file
|
||||||
@@ -92,20 +93,20 @@
|
|||||||
# and sky-cam-notify-failure@.service
|
# and sky-cam-notify-failure@.service
|
||||||
#
|
#
|
||||||
# daily_sunrise_video.sh
|
# daily_sunrise_video.sh
|
||||||
# ← called by systemd sky-cam-sunrise.timer (09:00)
|
# ← called by systemd sky-cam-sunrise.timer (SCHEDULE_SUNRISE)
|
||||||
# → if renamed: update install.sh (write_service call, line ~80)
|
# → if renamed: update install.sh (write_service call ~line 70)
|
||||||
# then re-run install.sh to regenerate the unit
|
# then re-run install.sh to regenerate the unit
|
||||||
# calls → sunrise.py, sunrise_overlay.py, sunrise2mm.py
|
# calls → sunrise.py, sunrise_overlay.py, sunrise2mm.py
|
||||||
#
|
#
|
||||||
# 4-seasons.sh
|
# 4-seasons.sh
|
||||||
# ← called by systemd sky-cam-4seasons.timer (01:00)
|
# ← called by systemd sky-cam-seasons-<cam>.timer (SCHEDULE_SEASONS_<cam>)
|
||||||
# → if renamed: update install.sh (write_service call, line ~86)
|
# → if renamed: update install.sh (write_service call ~line 85)
|
||||||
# then re-run install.sh
|
# then re-run install.sh
|
||||||
# calls → season_info.py, montage-mvt.sh
|
# calls → season_info.py, montage-mvt.sh
|
||||||
#
|
#
|
||||||
# fullday-video.sh
|
# fullday-video.sh
|
||||||
# ← called by systemd sky-cam-fullday.timer (02:00)
|
# ← called by systemd sky-cam-fullday-<cam>.timer (SCHEDULE_FULLDAY_<cam>)
|
||||||
# → if renamed: update install.sh (write_service call, line ~93)
|
# → if renamed: update install.sh (write_service call ~line 93)
|
||||||
# then re-run install.sh
|
# then re-run install.sh
|
||||||
#
|
#
|
||||||
# montage-mvt.sh
|
# montage-mvt.sh
|
||||||
@@ -149,10 +150,6 @@
|
|||||||
# Full path to the directory containing this file and all the scripts.
|
# Full path to the directory containing this file and all the scripts.
|
||||||
SCRIPT_DIR=/home/motion/drives/local-2tb/sunrise-scripts
|
SCRIPT_DIR=/home/motion/drives/local-2tb/sunrise-scripts
|
||||||
|
|
||||||
# Camera name — subfolder under BASE_DIR (images) and BASE_DIR/movies (videos).
|
|
||||||
# E.g. "sunrise" → images: $BASE_DIR/sunrise/YYYY-MM-DD/ videos: $BASE_DIR/movies/sunrise/
|
|
||||||
CAM_NAME=sunrise
|
|
||||||
|
|
||||||
# ── Storage ───────────────────────────────────────────────────────────────────
|
# ── Storage ───────────────────────────────────────────────────────────────────
|
||||||
BASE_DIR=/home/motion/drives/local-2tb
|
BASE_DIR=/home/motion/drives/local-2tb
|
||||||
MUSIC_DIR=/home/motion/drives/local-2tb/music/4 Seasons
|
MUSIC_DIR=/home/motion/drives/local-2tb/music/4 Seasons
|
||||||
@@ -160,10 +157,38 @@ MUSIC_DIR=/home/motion/drives/local-2tb/music/4 Seasons
|
|||||||
# ── Location & timezone ───────────────────────────────────────────────────────
|
# ── Location & timezone ───────────────────────────────────────────────────────
|
||||||
# Used by sunrise.py to calculate sunrise time each day.
|
# Used by sunrise.py to calculate sunrise time each day.
|
||||||
# TIMEZONE must be a valid IANA name: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
# TIMEZONE must be a valid IANA name: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||||
LATITUDE=38.123456
|
LATITUDE=25.0000
|
||||||
LONGITUDE=-97.654321
|
LONGITUDE=-38.0000
|
||||||
TIMEZONE=America/New_York
|
TIMEZONE=America/New_York
|
||||||
|
|
||||||
|
# ── Cameras ───────────────────────────────────────────────────────────────────
|
||||||
|
# List every camera name here (space-separated inside the parentheses).
|
||||||
|
# Each name becomes a subfolder under BASE_DIR (images) and BASE_DIR/movies.
|
||||||
|
# To add a camera: add its name here, add its schedules below, re-run install.sh.
|
||||||
|
#
|
||||||
|
CAMERAS=(sunrise) # e.g. CAMERAS=(sunrise north west)
|
||||||
|
SUNRISE_CAM=sunrise # which camera faces east (gets the sunrise video job)
|
||||||
|
|
||||||
|
# ── Schedules ─────────────────────────────────────────────────────────────────
|
||||||
|
# SCHEDULE_SUNRISE when to run daily_sunrise_video.sh (SUNRISE_CAM only)
|
||||||
|
# SCHEDULE_SEASONS_<cam> when to run 4-seasons.sh for each camera
|
||||||
|
# SCHEDULE_FULLDAY_<cam> when to run fullday-video.sh for each camera
|
||||||
|
#
|
||||||
|
# Times are HH:MM:SS (24-hour). Space cameras at least 30 min apart.
|
||||||
|
# install.sh reads these and generates one systemd timer per camera per job.
|
||||||
|
#
|
||||||
|
SCHEDULE_SUNRISE=09:00:00
|
||||||
|
|
||||||
|
SCHEDULE_SEASONS_sunrise=01:00:00
|
||||||
|
SCHEDULE_FULLDAY_sunrise=02:00:00
|
||||||
|
|
||||||
|
# Uncomment and fill in for each camera you add to CAMERAS above:
|
||||||
|
#SCHEDULE_SEASONS_north=01:30:00
|
||||||
|
#SCHEDULE_FULLDAY_north=02:30:00
|
||||||
|
#
|
||||||
|
#SCHEDULE_SEASONS_west=02:00:00
|
||||||
|
#SCHEDULE_FULLDAY_west=03:00:00
|
||||||
|
|
||||||
# ── Sunrise video tuning ──────────────────────────────────────────────────────
|
# ── Sunrise video tuning ──────────────────────────────────────────────────────
|
||||||
# How many minutes before/after sunrise to include in the daily clip.
|
# How many minutes before/after sunrise to include in the daily clip.
|
||||||
SUNRISE_PRE_MIN=70
|
SUNRISE_PRE_MIN=70
|
||||||
@@ -181,23 +206,23 @@ access_token=your-access-token-here
|
|||||||
channel_id=your-daily-upload-channel-id-here
|
channel_id=your-daily-upload-channel-id-here
|
||||||
|
|
||||||
# ── Notifications — montage / year-end complete + any job failure ─────────────
|
# ── Notifications — montage / year-end complete + any job failure ─────────────
|
||||||
# Notifications fire when a movement montage or the year video finishes.
|
# Notifications fire when a movement montage or the year video finishes,
|
||||||
# They also fire automatically via systemd OnFailure= if any daily job fails.
|
# and via systemd OnFailure= if any daily job fails.
|
||||||
# Enable one or more methods below.
|
# Uncomment and configure one or more methods to enable.
|
||||||
|
|
||||||
# ntfy — push notifications, zero signup required for self-hosted:
|
# ntfy — push notifications, zero signup for self-hosted or free cloud tier:
|
||||||
# https://docs.ntfy.sh/install/
|
# Self-hosted: https://docs.ntfy.sh/install/
|
||||||
# or use the free cloud tier at ntfy.sh (pick any topic name)
|
# Cloud: pick any topic name at ntfy.sh (no account needed)
|
||||||
NTFY_ENABLED=false
|
#NTFY_ENABLED=true
|
||||||
NTFY_URL=https://ntfy.sh/your-topic-here
|
#NTFY_URL=https://ntfy.sh/your-topic-here
|
||||||
|
|
||||||
# Email — requires the 'mail' command on the system (package: mailutils or s-nail).
|
# Email — requires the 'mail' command (package: mailutils or s-nail).
|
||||||
# For outbound SMTP configure /etc/ssmtp/ssmtp.conf or msmtp.
|
# Configure outbound SMTP via /etc/ssmtp/ssmtp.conf or msmtp.
|
||||||
EMAIL_ENABLED=false
|
#EMAIL_ENABLED=true
|
||||||
EMAIL_TO=you@example.com
|
#EMAIL_TO=you@example.com
|
||||||
EMAIL_FROM=skycam@localhost
|
#EMAIL_FROM=skycam@localhost
|
||||||
|
|
||||||
# Mattermost text post — reuses the URL and token above, but posts to this
|
# Mattermost text post — reuses mattermost_url and access_token above.
|
||||||
# channel (can be the same daily channel or a separate private/admin channel).
|
# Can be the same daily channel or a separate admin/private channel.
|
||||||
MM_NOTIFY_ENABLED=false
|
#MM_NOTIFY_ENABLED=true
|
||||||
MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here
|
#MM_NOTIFY_CHANNEL_ID=your-notify-channel-id-here
|
||||||
|
|||||||
+3
-1
@@ -17,9 +17,11 @@ source "$SCRIPT_DIR/sky-cam.conf"
|
|||||||
|
|
||||||
ASTRO_YEAR="${1:-}"
|
ASTRO_YEAR="${1:-}"
|
||||||
if [ -z "$ASTRO_YEAR" ]; then
|
if [ -z "$ASTRO_YEAR" ]; then
|
||||||
echo "Usage: $0 <ASTRO_YEAR> (e.g. $0 2025)"
|
echo "Usage: $0 <ASTRO_YEAR> [CAM_NAME] (e.g. $0 2025 north)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
# Camera name: second argument overrides conf (passed through from montage-mvt.sh).
|
||||||
|
CAM_NAME="${2:-$CAM_NAME}"
|
||||||
|
|
||||||
year_dir="$BASE_DIR/movies/$CAM_NAME/$ASTRO_YEAR"
|
year_dir="$BASE_DIR/movies/$CAM_NAME/$ASTRO_YEAR"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user