68 lines
1.7 KiB
Bash
Executable file
68 lines
1.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# zzz - Sleep timer with notification
|
|
# Usage: zzz -s 5 (5 seconds)
|
|
# zzz -m 2 (2 minutes)
|
|
# zzz 30 (30 seconds, default unit)
|
|
# zzz -q -s 10 (quiet - no voice, just ding)
|
|
|
|
set -euo pipefail
|
|
|
|
QUIET=false
|
|
SECONDS_TOTAL=0
|
|
|
|
usage() {
|
|
echo "Usage: zzz [-s seconds] [-m minutes] [-q] [seconds]"
|
|
echo " -s SEC Sleep for SEC seconds"
|
|
echo " -m MIN Sleep for MIN minutes"
|
|
echo " -q Quiet mode (ding only, no voice)"
|
|
echo " NUM Bare number = seconds"
|
|
exit 1
|
|
}
|
|
|
|
# Parse args
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-s) SECONDS_TOTAL="$2"; shift 2 ;;
|
|
-m) SECONDS_TOTAL=$(( $2 * 60 )); shift 2 ;;
|
|
-q) QUIET=true; shift ;;
|
|
-h|--help) usage ;;
|
|
*)
|
|
if [[ "$1" =~ ^[0-9]+$ ]]; then
|
|
SECONDS_TOTAL="$1"; shift
|
|
else
|
|
echo "Unknown argument: $1" >&2
|
|
usage
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$SECONDS_TOTAL" -le 0 ]]; then
|
|
usage
|
|
fi
|
|
|
|
# Display what we're doing
|
|
if [[ "$SECONDS_TOTAL" -ge 60 ]]; then
|
|
MINS=$(( SECONDS_TOTAL / 60 ))
|
|
SECS=$(( SECONDS_TOTAL % 60 ))
|
|
if [[ "$SECS" -gt 0 ]]; then
|
|
echo "💤 Sleeping ${MINS}m ${SECS}s..."
|
|
else
|
|
echo "💤 Sleeping ${MINS}m..."
|
|
fi
|
|
else
|
|
echo "💤 Sleeping ${SECONDS_TOTAL}s..."
|
|
fi
|
|
|
|
sleep "$SECONDS_TOTAL"
|
|
|
|
# Notification
|
|
paplay /usr/share/sounds/Oxygen-Im-New-Mail.ogg 2>/dev/null &
|
|
|
|
if [[ "$QUIET" == false ]]; then
|
|
echo "Sleep finished" | piper -m ~/.local/share/piper-voices/en_US-lessac-medium.onnx --output-raw 2>/dev/null \
|
|
| aplay -r 22050 -f S16_LE -t raw -q 2>/dev/null \
|
|
|| spd-say -w "Sleep finished" 2>/dev/null || true
|
|
fi
|
|
|
|
echo "⏰ Done!"
|