Mon, 26 Jan 2009
A Linux-based alarm clock
That is, my laptop. Since at night I keep it in the same room where I sleep, I figured that I could as well use it as an highly customizable alarm clock.
My alarm script uses rtcwake(8) from util-linux-ng to set the RTC alarm clock, suspends the computer and then plays some music at a set volume when it wakes up (if it never wakes up, check your BIOS settings). Since it uses the date(2) command it can parse the alarm time in many formats.
#!/bin/sh -e
# for a random tune, list multiple space-separated files
MUSIC='/home/mp3/The_Velvet_Underground/The_Velvet_Underground_&_Nico/07_Heroin.mp3'
# some days I like different music
DOW="$(date +%u)"
if [ $DOW -eq 6 -o $DOW -eq 7 ]; then
MUSIC='/home/mp3/The_Velvet_Underground/The_Velvet_Underground_&_Nico/01_Sunday_Morning.mp3'
fi
# choose your favourite music player
player() { mpg123 --random --quiet --control --title "$@" || true; }
#player() { mplayer -loop 0 "$*"; }
# play the music at this volume
VOLUME='50%'
# ALSA mixer control used to set and restore the master volume
VOLUMECTL='iface=MIXER,name="Master Playback Volume"'
##############################################################################
# this is more elegant, but it needs rtcwake from util-linux-ng >= 2.14.2
rtcwake_set_alarm() {
local when="$1"
local rtc="$2"
if [ "$rtc" ]; then rtc="--device $rtc"; fi
local epochtime=$(date --date "$when" +%s)
[ "$epochtime" ] || return 1
sudo rtcwake $rtc --mode no --time $epochtime
}
# you can use this function instead if your system lacks a working rtcwake
set_alarm() {
local when="$1"
local rtc="$2"
[ "$rtc" ] || rtc='rtc0'
local epochtime=$(date --date "$when" +%s)
[ "$epochtime" ] || return 1
local alarmfile="/sys/class/rtc/$rtc/wakealarm"
sudo sh -c "echo 0 > $alarmfile && echo $epochtime > $alarmfile"
}
##############################################################################
if [ "$1" ]; then
WHEN="$1"
else
echo "Usage: $0 WHEN"
exit 1
fi
set_alarm "$WHEN"
# save the volume
oldvolume="$(amixer cget "$VOLUMECTL" | sed -nre '/ : /s/.*=//p')"
amixer -q cset "$VOLUMECTL" $VOLUME
# actually here I run a script which also deals with network interfaces,
# IM and IRC clients and so on
sudo pm-suspend
player $MUSIC
# restore the volume
amixer -q cset "$VOLUMECTL" "$oldvolume"
exit 0