generated from me/template-mit
Compare commits
6
Commits
main
...
3a36ec9651
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a36ec9651 | ||
|
|
eb0555fd77 | ||
|
|
f145f7122e | ||
|
|
0713442b78 | ||
|
|
6ce4a9bbf0 | ||
|
|
15c909d954 |
No files matched your search
@@ -1,3 +1,105 @@
|
|||||||
# template-mit
|
# Sunset Alarm (CLI)
|
||||||
|
|
||||||
Template with MIT license, protected `main` branch, and available `dev` branch.
|
Simple command line shell script which can be run as a user daemon for alerts.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Sunset Alarm allows a user to receive an alert at a specified amount of minutes
|
||||||
|
before sunset. This may be helpful for starting any practices such as preparing
|
||||||
|
for sungazing, or as a reminder to go and find a campsite before it gets dark.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
`()` sections are required.
|
||||||
|
`[]` sections are optional.
|
||||||
|
`|` separates multiple options in a group.
|
||||||
|
|
||||||
|
```console
|
||||||
|
sunset-timer (-l LAT:LONG | -t HH24:MI) (-m MINUTES) [-h]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Set an alarm 90 minutes before for your lat/long experiences sunset:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sunset-alarm -l 32.123:-111.111 -m 90
|
||||||
|
```
|
||||||
|
|
||||||
|
Set an alarm 5 minutes after a manually determined sunset time:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
sunset-alarm -t 18:00 -m -5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
Recommended installation location is under `/usr/local/*`.
|
||||||
|
|
||||||
|
```console
|
||||||
|
# git clone http://git.hyperling.com/me/sunset-alarm-cli /usr/local/src/sunset_alarm_cli
|
||||||
|
# ln -s /usr/local/src/sunset_alarm_cli/sunset-alarm /usr/local/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Daemonize
|
||||||
|
|
||||||
|
**runit**
|
||||||
|
|
||||||
|
Create the run file:
|
||||||
|
|
||||||
|
```console
|
||||||
|
# vi /etc/sv/sunset-alarm/run:
|
||||||
|
```
|
||||||
|
|
||||||
|
```shell
|
||||||
|
#!/bin/sh -e
|
||||||
|
exec 2>&1
|
||||||
|
chpst -u user /usr/local/bin/sunset-alarm -l 33:-112 -m 15
|
||||||
|
```
|
||||||
|
|
||||||
|
Enable the service:
|
||||||
|
|
||||||
|
```console
|
||||||
|
# ln -s /etc/sv/sunset-alarm /var/services/
|
||||||
|
```
|
||||||
|
|
||||||
|
### i3
|
||||||
|
|
||||||
|
Simply add an exec to the end of your config file.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
echo "exec --no-startup-id /usr/local/bin/sunset-alarm -l 33:-112 -m 15" >> ~/.config/i3/config
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
|
||||||
|
### Required
|
||||||
|
|
||||||
|
-m : Accepts a minute value which is used to check if we have approached the
|
||||||
|
alert period before sunset. Can be positive, negative, or 0.
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
-l : Accepts a lat:long value which is used to check Open Meteo for the
|
||||||
|
location's sunset time. This is required if -t is not passed.
|
||||||
|
|
||||||
|
-t : Accepts a time value for sunset time. If this is passed, it bypasses the
|
||||||
|
Open Meteo check and acts as a hardcoded time. The minutes parameter is still
|
||||||
|
required to know when to alert prior to this time.
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
App displays a persistent alert via `fyi` with fallbacks of `notify-send`,
|
||||||
|
`wall`, and others. Appears once when current time is between (sunset - minutes)
|
||||||
|
and midnight. Even if the system is powered on after the alert time has passed,
|
||||||
|
the program continues displaying the alert repeatedly until the day has passed.
|
||||||
|
|
||||||
|
App requires an internet connection. If no connection is found, it sleeps for 5
|
||||||
|
minutes and then tries again to retrieve the sunset time. Once the sunset time
|
||||||
|
has been retrieved for the day, it stops checking Open Meteo until the next day.
|
||||||
|
|
||||||
|
App is short, sweet, concise, and succinct without using any odd syntax or line
|
||||||
|
combining to achieve this. Does not pull in any extraneous libraries, only uses
|
||||||
|
utilities which are already installed on the system. Program is coded to use a
|
||||||
|
range of utilities in case the primary choices are not available. If no choices
|
||||||
|
are installed, displays an ERROR message with a list of software to download.
|
||||||
Executable
+77
@@ -0,0 +1,77 @@
|
|||||||
|
#!/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}¤t=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}')")
|
||||||
Reference in new issue
Block a user