Files
sunset-alarm-cli/sunset-alarm
T
2026-10-17 14:28:24 -07:00

78 lines
3.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# sunset-alarm — persistent alert at a calculated offset before sunset
# Usage: sunset-alarm (-l LAT:LONG | -t HH24:MI) (-m MINUTES) [-h]
set -uo pipefail
SUNSET_EPOCH="" # epoch of today's sunset
ALERT_EPOCH="" # epoch when the window opens (sunset - offset)
OFFSET_MIN=0 # signed minute offset from sunset
LAT="" # latitude (-l/--location)
LON="" # longitude
HARDCODED_TIME="" # HH:MM string (-t/--hardcoded)
usage() {
cat <<'EOF'
Usage: sunset-alarm (-l LAT:LONG | -t HH24:MI) (-m MINUTES) [-h]
Options:
-l LAT:LONG Latitude and longitude, e.g. 32.123:-111.111
(queried from Open-Meteo for today's sunset time)
-t HH24:MI Hardcoded sunset time to use instead.
When combined with -l the offset is applied against
this time and the network call is skipped.
-m MINUTES Minutes before (-), at (= 0), or after (+) sunset
to trigger the alert. May be negative.
-h Show this help message and exit.
Examples:
sunset-alarm -l 32.123:-111.111 -m 90 # 90 min before actual sunset
sunset-alarm -t 18:00 -m -5 # 5 min after the hardcoded time
EOF
}
die() { echo "Error: $*" >&2; exit 1; }
# ── resolve a fallback command at startup ──────────────────────────
NOTIFY_CMD=""
for _cmd in fyi notify-send wall; do
if command -v "$_cmd" >/dev/null 2>&1; then
NOTIFY_CMD="$_cmd"; break
fi
done
fire_alert() {
local body="$1"
case "$NOTIFY_CMD" in
fyi) fyi "Sunset Alarm: ${body}" ;;
notify-send) notify-send -u normal "Sunset Alarm" "${body}" 2>/dev/null || true ;;
wall) echo "Sunset Alarm: ${body}" | wall 2>/dev/null || printf 'Sunset Alarm: %s\n' "$body" ;;
esac
}
# ── open-meteo helper ─────────────────────────────────────────────
fetch_sunset_epoch() {
local lat="$1" lon="$2"
# curl –silent + HTTP code tail so we can detect failures.
local resp; resp=$(curl -sfw "\n%{http_code}" \
"https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}&current=sunset&timezone=auto" \
--connect-timeout 10 --max-time 30) || return 1
local code="${resp##*$'\n'}"
resp="${resp%$'\n'*}" # strip the trailing HTTP code
[[ "${code:-599}" == "200" ]] || return 2
local iso; iso=$(printf '%s\n' "$resp" | jq -r '.current.sunset // empty')
[[ -n "$iso" ]] || return 3 # null / missing field
SUNSET_EPOCH=$(date -d "$iso" +%s) # local-time epoch
}
# Build today's sunset epoch from a hardcoded HH:MM when -t is used.
set_sunset_from_time() {
local hhmm="$1"
local Y M D h m
read -r Y M D h m <<< "$(date +%Y-%m-%d) $(echo "$hhmm" | tr ':' ' ')"
SUNSET_EPOCH=$(date -d "${Y}-${M}-${D} ${h}:${m}:00" 2>/dev/null +%s \
|| die "Invalid time format '${hhmm}')")