Crank up your speakers and get up on time!
The alarm can be stopped by pausing the track through MPC
.
Example usage: $ alarm -s 05:55 -m "Death Grips/Death Grips [2013] Government Plates/01 - You Might Think He Loves You for Your Money but I Know What He Really Loves You for It’s Your Brand New Leopard Skin Pillbox Hat.mp3"
Arguments
-s --set
– Set a time for the alarm to go off (24h, e.g., 05:55).-f --for
– Set an alarm to go off after a period of time (e.g., 08:30 means in 8 hours 30 minutes).-m --music
– Path to music file, directory, or playlist (relative to your MPD music_directory)
Source code
alarm
#!/bin/bash
# A simple alarm clock script
# Uses MPD (Music Player Daemon)
DEFAULT_TRACK="alarm.mp3" # Change this to a track in your library.
usage() {
echo "Usage:"
echo " -s --set Set a time for the alarm to go off (24h, e.g., 05:55)"
echo " -f --for Set an alarm to go off after a period of time (e.g., 08:30 means in 8 hours 30 minutes)"
echo " -m --music Path to music file, playlist, or directory (relative to your MPD music_directory!) [Optional]"
echo " If not provided, will use default: '$DEFAULT_TRACK'"
exit 1
}
play_alarm() {
local AUDIO_PATH="$1"
if ! pgrep mpd > /dev/null; then
echo "MPD is not running. Starting MPD..."
mpd
sleep 2
fi
mpc stop
mpc clear
mpc add "$AUDIO_PATH"
mpc volume 100
mpc repeat on
mpc play
}
if [[ $# -lt 2 ]]; then
usage
fi
MODE=""
TIME=""
AUDIO_PATH=""
while [[ $# -gt 0 ]]; do
case "$1" in
-s|--set)
MODE="set"
TIME="$2"
shift 2
;;
-f|--for)
MODE="for"
TIME="$2"
shift 2
;;
-m|--music)
AUDIO_PATH="$2"
shift 2
;;
*)
usage
;;
esac
done
if [[ -z "$MODE" || -z "$TIME" || -z "$AUDIO_PATH" ]]; then
usage
fi
if [[ -z "$AUDIO_PATH" ]]; then
AUDIO_PATH="$DEFAULT_TRACK"
echo "No music specified. Using default: $AUDIO_PATH"
fi
# Verify music path (must be a path relative to your music directory)
if [[ "$AUDIO_PATH" = /* ]]; then
echo "Error: Music path must be relative to your MPD music_directory."
exit 1
fi
case "$MODE" in
set)
if ! [[ "$TIME" =~ ^([01]?[0-9]|2[0-3]):[0-5][0-9]$ ]]; then
echo "Invalid time format: $TIME"
usage
fi
NOW_SEC=$(date +%s)
ALARM_SEC=$(date -d "today $TIME" +%s 2>/dev/null)
if [ $? -ne 0 ]; then
echo "Invalid date/time."
exit 1
fi
if [ "$ALARM_SEC" -le "$NOW_SEC" ]; then
ALARM_SEC=$(date -d "tomorrow $TIME" +%s)
fi
SLEEP_SEC=$((ALARM_SEC - NOW_SEC))
echo "Alarm set for $TIME ($(date -d @$ALARM_SEC)), will go off in $((SLEEP_SEC/60)) minutes."
;;
for)
if ! [[ "$TIME" =~ ^([0-9]+):([0-5][0-9])$ ]]; then
echo "Invalid period format: $TIME"
usage
fi
HOURS="${BASH_REMATCH[1]}"
MINUTES="${BASH_REMATCH[2]}"
SLEEP_SEC=$((10#$HOURS * 3600 + 10#$MINUTES * 60))
TARGET_TIME=$(date -d "+$HOURS hour +$MINUTES min" "+%Y-%m-%d %H:%M")
echo "Alarm set to go off in $HOURS hours and $MINUTES minutes (at $TARGET_TIME)."
;;
*)
usage
;;
esac
sleep "$SLEEP_SEC"
play_alarm "$AUDIO_PATH"