Set ACPI Wakeup Time

The /usr/bin/setwakeup.sh Script

This script is used by both MythBackend and MythWelcome in order to schedule an ACPI wakeup alarm. Each of these applications must be configured separately to use this script.

This script improves upon and solves problems with stock MythTV installations. Most importantly, it corrects a conflict between MythBackend program scheduling and MythWelcome daily wakeup alarms. You can read about this on the MythWelcome page.

A log is kept of all scheduling activities, so that wakeup problems can be easily diagnosed. This log is stored in the file /var/log/mythtv/wakeup.log. Here is an example of the log file format:

Oct 19 19:35:24 setwakeup - 20:55 2008-10-19 wakeup requested
Oct 19 19:35:24 setwakeup - 2008-10-19 20:55:00 to /proc/acpi/alarm
Oct 19 19:35:25 setwakeup - 2008-10-20 05:00:00 wakeup requested
Oct 19 19:35:25 setwakeup - keeping previous wakeup 2008-10-19 20:55:00

In this log file there are two requests to set the wakeup time. The first one is for 8:55pm, and it requests a wakeup five minutes before the start of a recording. The second request if for a wakeup at 5:00am the next morning. Since the second request conflicts with the first, it is ignored.

The /usr/bin/setwakeup.sh program needs root privileges to operate properly. Therefore it needs to be added to the sudoers list. Edit the file /etc/sudoers and add /usr/bin/setwakeup.sh to the list of files that are assigned to Cmnd_Alias MYTHDORA. It should look similar to the following:

Cmnd_Alias MYTHDORA= /usr/bin/setwakeup.sh, ...

The fully commented source code explains how and why the script works:

#!/bin/sh
#
# . Sets ACPI wakeup time
#
# . Input parameters $* are the date/time in any valid format
#
# . Assumes that RTC is localtime and not UTC
#
# . Works whether system sets ACPI wakeup time with either:
#	/proc/acpi/alarm
#	/sys/class/rtc/rtc0/wakealarm
#
# . Corrects schedulting conflicts between recording time and daily
#	wakeup time caused by Mythwelcome (at least in MythDora 5.0)
#
# . Appends status messages to log file: /var/log/mythtv/wakeup.log
#
# . Keeps record of wakeup time in file: /var/log/mythtv/wakeupspec
#	File format is "%s %s"
#		- where first item is epoch seconds of when requested
#		- where second iten is epoch seconds of wakeup time

# Current time and date
NOW=`date "+%b %d %H:%M:%S"`

# Helper prints messages to wakeup log
function logtowakeup()
	{
	echo "$NOW setwakeup - $1" >> /var/log/mythtv/wakeup.log
	}

# Rewrite time/date parameter into standardized format. If failure,
# then try again assuming input is in epoch seconds. A second failure
# produces error for invalid date and exits.
DATE=`date -d "$*" "+%F %H:%M:%S" -u`
if [ $? -ne 0 ]; then
	DATE=`date -d "@$*" "+%F %H:%M:%S" -u`
	if [ $? -ne 0 ]; then
	logtowakeup "$* invalid date specification"
		exit 1
	fi
fi

# Log the wakeup request
logtowakeup "$* wakeup requested"

# Current time in seconds
NOWSECS=`date -d "$NOW" "+%s"`

# Requested wakeup time in seconds
SECS=`date -d "$DATE" "+%s" -u`

# If this wakeup setting has been issued within a second of the previous
# one, then mythwelcome is schizophrenic. Actually, this happens because
# there is both a daily wakeup and a scheduled recording. Mythwelcome
# will fire off both requests without predjudice. The earlier of the two
# wakeup times is retained.
if [ -e /var/log/mythtv/wakeupspec ]; then
	set -- `cat /var/log/mythtv/wakeupspec`
	if [ $(($NOWSECS-$1)) -lt 2 ] && [ $SECS -gt $2 ]; then
		LASTDATE=`date -d "@$2" "+%F %H:%M:%S" -u`
		logtowakeup "keeping previous wakeup $LASTDATE"
		exit 0
	fi
fi

# Save wakeup specification
echo "$NOWSECS $SECS" > /var/log/mythtv/wakeupspec

# There are two methods for setting the ACPI wakeup time. Newer Linux
# kernels write epoch time to /sys/class/rtc/rtc0/wakealarm. wakealarm
# must be set zero prior to setting the desired value.
if [ -e /sys/class/rtc/rtc0/wakealarm ]; then
	echo 0 > /sys/class/rtc/rtc0/wakealarm
	echo $SECS > /sys/class/rtc/rtc0/wakealarm
	logtowakeup "$DATE to /sys/class/rtc/rtc0/wakealarm"
fi

# Supposedly the /proc/acpi/alarm method is deprecated, however this
# is supported by MythDora 5.0
if [ -e /proc/acpi/alarm ]; then
	echo $DATE > /proc/acpi/alarm
	logtowakeup "$DATE to /proc/acpi/alarm"
fi