Einführung

Damit ich am Morgen von passender Musik geweckt werde, habe ich mir ein Skript geschrieben, welches mein Notebook in einen Wecker verwandelt. So stelle ich normalerweise den Notebook vor dem Schlafen gehen in den Sleep-Modus, welcher 30 Minuten Musik abspielt und danach in den Stanbdy fährt. Am Morgen schaltet mein Notebook automatisch zur eingestellten Weckzeit ein und spielt die Musik weiter. So starte ich meist gut in den Tag. Hier beschreibe ich, wie ich das gemacht habe.

Konzept

Ich habe mir überlegt, welche Anforderungen ein Skript haben muss, damit ich einen Wecker implementieren kann. Folgendes ist dabei entstanden:

  • Computer automatisch zu einer einstellbaren Zeit starten
  • Nach dem Starten ein Programm ausführen
  • Eine Sleep-Funktion, welche den Computer nach einer gewissen Zeit in den Standby stellt
  • Den Wecker deaktivieren
  • Die Wecker-Einstellungen abfragen
  • Eingaben auf Gültigkeit überprüfen (Nur mögliche Parameter und Uhrzeiten)

Daraus ist das Script wecker entstanden. Das Skript ist auf GitHub in meinem Scripts Repository zu finden: wecker.

Die wichtigsten Befehle daraus werde ich in diesem Blogpost erklären.

Computer in den Standby schicken

Um den Computer in den Standby zu schicken, kann man pm-suspend verwenden, welches man unter Arch Linux im Paket pm-utils findet:

sudo pacman -S pm-utils

Will man den Computer nach 23 Minuten in den Standby fahren, kann man das so realisieren:

sleep 23m && sudo pm-suspend

Jetzt wartet sleep genau 23 Minuten. Nach erfolgreichem Warten (ohne dass man z. B. mit ^C abbricht), wird sudo pm-suspend ausgeführt, welches den Computer in den Standby fährt.

Will man nach dem Aufwecken ein weiteren Befehl ausführen, kann man den auch wieder mit && starten:

sleep 23m && sudo pm-suspend && amixer set Master 90% && mpc play

Nach dem Aufwecken wird die Lautstärke auf 90% gestellt und die Musik mittels mpc abgespielt.

Hat man ein systemd System, kann man den Computer ohne Rootrechte in den Standby schicken:

systemctl suspend

Diese Variante ist natürlich zu bevorzugen.

Computer aufwecken mit rtcwake

Mit rtcwake kann man den Computer automatisch aufstarten. Dies geschieht, wenn er sich im ausgeschalteten Zustand oder im Standby befindet.

Eventuell muss man zuerst noch rtcwake installieren. Unter Arch Linux ist rtcwake im Paket util-linux enthalten.

sudo rtcwake -m no -t `date -d "tomorrow 6:55" +%s`

Die Option -m no macht, dass nach dem Absetzen des Befehls der Computer nicht in den Standby fährt. Mit -t kann man die Zeit angeben. Diese Option erwartet einen Unix-Timestamp. Mit date -d +%s kann man so die Anzahl Sekunden seit dem 1. Januar 1997 berechnen.

Hier gibt es jedoch ein Problem: Wenn ich nur 06:00 eingebe, dann wird die Uhrzeit vom aktuellen Tag verwendet. Möchte ich jedoch am nächsten Tag um 06:00 Uhr geweckt werden, muss ich tomorrow 06:00 eingeben. Da es nicht immer klar ist, ob man den Wecker vor oder nach Mitternacht stellt, kann man mit date berechnen, ob die Uhrzeit in der Vergangenheit liegt oder nicht. Liegt das Datum in der Vergangenheit, muss man 24 h addieren. Die Uhrzeit darf sich auch nicht in der Vergangenheit befinden (falls man sie absolut mit einem Datum eingibt) oder eine ungültige Eingabe für date sein. Diese Fälle kann man so abfangen:

NOW="`date +%s`"

if ! date -d $2 >/dev/null 2>&1
then
  echo "Alarm time is invalid."
  exit 1
fi

if [ "`date -d $2 +%s`" -gt "$NOW" ]
then
  echo "Set alarm for today"
  ALARMTIME="`date -d $2 +%s`"
elif [ "$((`date -d $2 +%s` - $NOW))" -ge 86400 ]
then
  echo "Alarm time not possible."
  exit 1
else
  echo "Set alarm for tomorrow"
  ALARMTIME="$((`date -d $2 +%s` + 86400))"
fi

Der Alarm kann anschliessend so mit der korrekten Uhrzeit gesetzt werden:

sudo rtcwake -m no -t "$ALARMTIME"

Status des Weckers abfragen

Der aktuelle Status von rtcwake kann man auf verschiedene Weisen abfragen. In für Menschen lesbarer Form findet man den Alarm im File /proc/driver/rtc:

$ grep al /proc/driver/rtc
alrm_time       : 21:00:00
alrm_date       : 2013-03-28
alarm_IRQ       : yes
alrm_pending    : no

Die Variablen alrm_time und alrm_date geben den Weckzeitpunkt an. Ist alarm_IRQ auf YES gesetzt, ist der Alarm eingeschaltet.

Will man die Weckzeit mit date auswerten, kann man auf die Datei /sys/class/rtc/rtc0/wakealarm zugreifen. Dort ist der Unix-Timestamp der Weckzeit hinterlegt. Eine schöne Ausgabe erhält man mit:

ALARM=`cat /sys/class/rtc/rtc0/wakealarm`
date -d @"$ALARM" "+Alarm is set: %A %Y-%m-%d %H:%M:%S"
DIFF=`expr $ALARM - $NOW`
HRS=`expr $DIFF / 60 / 60`
MINS=`expr \( $DIFF - $HRS \* 60 \* 60 \) / 60`
echo "Alarm will start in $HRS h $MINS m"

Mit diesem Code wird zudem die restliche Zeit in Stunden und Minuten berechnet.

Das wecker Script

Das wecker lässt sich wie folgt bedienen:

$ wecker  -h
Usage:
  wecker option <params>

  Options:
    set <time>
      Set the alarm at <time>
    sleep <minutes>
      Suspend the computer after <minutes>
    disable
      Disable the alarm
    status
      Shows the current alarm time

  Examples:
    wecker set 23:00
      The computer will start at 23:00h
    wecker sleep 42m
      The computer will suspend in 42 minutes
    wecker disable
      The computer will not start automatically

Weckzeit setzen:

$ sudo wecker set 06:55
Set alarm for tomorrow
Current status: Alarm is set: Sonntag 2013-03-31 07:55:00
Alarm will start in 14 h 47 m

Wecker abfragen:

$ wecker status
Current status: Alarm is set: Sonntag 2013-03-31 07:55:00
Alarm will start in 14 h 46 m

Nach 23 Minuten in den Standby fahren und Lautstärke erhöhen:

$ sudo wecker sleep 23 && amixer set Master 90%

Zudem ist der Wecker auch deaktivierbar:

$ sudo wecker disable
Disable alarm.
Current status: Alarm is not set.