This is a quick summary of my alarm clock system, written in bash and highly
unreliable.

<h3>Hardware</h3>

<p>
My preferred hardware platform is a Dell Mini 9.
</p>

<h3>Software</h3>

<p>
My alarm clock is an embarrassing combination of bash scripts and Audacious, my
favorite media player. Any media player will do, as long as it's scriptable.
</p>

<h3>How It Works</h3>

<p>
There are currently two bash scripts in my crappy alarm setup. One script is
called "wakeup" and the other is called "wakeup-at".
</p>
<p>
wakeup is simply a wrapper that adds some error handling around audacious. It
launches audacious if it can't find an instance running already, waits five
seconds for it to get itself together, and then causes it to play. It is also
currently broken, so the 'launching audacious' part doesn't work. I have to
manually start audacious myself. FAILURE.
</p>

<h3>wakeup script:</h3>

<pre>
#!/bin/bash
audacious &amp;

sleep 5s

audacious -p &amp;
</pre>

<p>
You've noticed that the "wakeup" script doesn't actually have any timing
involved; If you want to use it as an alarm, you get to combine it with the bash
"sleep" command. This is not a failure, this is by design! An example alarm:
</p>

<pre>
sleep 8h; wakeup
</pre>

<p>
One problem with this methodology is that it requires math, and is prone to
errors. If I'm going to sleep at 10:46:33 PM and need to wake up at 7:00 AM, I
need to chain sleep commands together for each unit of time:
</p>

<pre>
sleep 7h; sleep 14m; sleep 27s; wakeup
</pre>

<p>
Get some of that math wrong, and you wake up at the wrong time. FAILURE.
</p>
<p>
"wakeup-at" is a wrapper around "wakeup" that uses the "at" utility to schedule
the wakeup script. So, instead of using multiple sleep commands, it accepts any
of the time formats that at accepts:
</p>

<pre>
wakeup-at 7:00 AM
wakeup-at 6:00AM 2018-02-02
wakeup-at teatime
</pre>

<p>
Here is the wakeup-at script:
</p>

<pre>
#!/bin/bash

## Make sure we have enough arguments
if [ $# -lt 1 ]
then
  echo "Usage: `basename $0` &lt;time&gt;"
  exit 1
fi

echo "$@"

## Add custom time keywords
case "$1" in
"eternaldarkness")
	echo wakeup | at 3:33 AM
	;;

## Catch-all; send all arguments to at
*)
	echo wakeup | at $@
	;;
esac
</pre>
<p>
If you make a syntax error, "at" tells you about it immediately. Its only
failings are what it inherits from the original "wakeup" script.
</p>
