Skip to content
Tags

, ,

My setup for vdr automatic wake up and shutdown

April 14, 2012

Hello

Like all kids, my kids really enjoy watching cartoons. Unfortunately, most of them are broadcast during the morning, sometimes very early in the morning. Since I don’t want my kids to wake up (or wake me up…) too early in the morning to watch cartoon, I record the most interesting programs with vdr (I also edit out commercials before my kids watch them)

To limit my carbon (or equivalent radio-active waste) footprint, I do not want to leave the computer on 24/24, so the machine has to power up by itself before a recording time.

So I’ve setup vdr to automatically setup the wake up time of the computer and shutdown the machine once the recording is finished. Note that this machine is also my main home machine, so it must not shutdown while I’m working on it (typing this blog, for instance).

This should have been easy and fairly documented. Well, it was not that easy. A lot of doc mentions nvram-wakeup which is more or less obsolete. Other docs were in German. So, here’s a summary of the setup so other can benefit from my experience.

First, this was done on a Debian/sid machine, this post should be usable on other distros, provided some adaptations. These adaptations are left as an exercise to the reader (which is marketing lingo for “I don’t have a clue”)

First add this line in /etc/default/vdr:

 ENABLE_SHUTDOWN=1

When vdr has nothing to do, it will run some shutdown scripts, including /usr/share/vdr/shutdown-hooks/S90.custom, which is a link to /etc/vdr/shutdown-hooks/S90.custom.

The output of this script will be eval’ed by vdr, so vdr knows what to do next (e.g. abort shutdown, display a message to user, retry later…).

Here are the possible output of a vdr shutdown script (list taken from vdr-wiki):

  • To abort the shutdown, exit with an errorlevel != 0.
  • If you want a message to be displayed on the OSD when aborting a shutdown,
    then write to stdout:
    ABORT_MESSAGE=
  • If you want to defer the shutdown, write to stdout:
    TRY_AGAIN=
  • To overwrite the command that will be executed to shutdown the machine
    after all shutdown hooks have been processed, write to stdout:
    SHUTDOWNCMD=
    i.e.:
    echo "ABORT_MESSAGE=\"I do not want to shutdown now!\"" ; exit 1

This script will mess with /sys/class/rtc/rtc0/wakealarm so it must be run as root. But vdr will launch this script and does not run as root. Instead of setting a suid bit, let’s setup sudo to enable this script to gain root privilege from vdr. Add this line in /etc/sudoers (with visudo):

vdr ALL= NOPASSWD: /etc/vdr/shutdown-hooks/S90.custom *

And here’s a commented Perl script that handle the shutdown test:

#!/usr/bin/perl
use IO::File ;
use 5.10.0 ;
use English;
use Path::Class; 

use Sys::Syslog qw(:standard :macros);  # standard functions & macros
openlog('vdr-shutdown', "", "user");

Here’s the call to sudo to gain root privilege (if not already run as root):

if ($EUID) {
    system('sudo','/etc/vdr/shutdown-hooks/S90.custom', @ARGV) ;
    syslog(info => "vdr-shutdown: sudo myself returned $@") ;
    exit;
}

Get the next timer info from the command arguments provided by vdr:

my ($next_timer,$interval) = @ARGV ;

Setup the next alarm in the mother board:

if ( $next_timer) {
  my $dev_fh = IO::File->new("> /sys/class/rtc/rtc0/wakealarm");
  die "cannot open $dev_fh: $!" unless $dev_fh ;
  my $newtime = $next_timer - 300  ;  # Start 5 minutes earlier
  $dev_fh->print( "$newtime\n" ) ;
  $dev_fh->close ;

  syslog(info => "vdr-shutdown: set wakeup to $newtime") ;
}

Now, let’s check if someone is logged on the system. Weirdly enough, forking a command from this Perl script does not work when it’s run by vdr. Calling the ‘who’ command always return empty. The trick to find if anyone is logged is to check the content of /dev/pts directory. No files in there means that nobody is logged:

my @pts  = dir('/dev/pts')->children;
syslog(info => "vdr-shutdown:  found pts @pts") ;

if (@pts > 1) {
    syslog(info => "vdr-shutdown: retry later: someone is logged") ;
    say 'ABORT_MESSAGE="someone is logged, shutting down deferred"';
    say 'TRY_AGAIN=30'
}
else {
    syslog(info => "vdr-shutdown: nobody is logged, halting") ;
}

Now some cleanup then exit:

closelog() ;

exit 0;

Last but not least, make sure this script executable (e.g with “chmod a+x”).

This script has been working for one month, and not a single programs was missed. My kids are happy.

I’m not so happy because I now have a lot of commercials to edit out 😉

All the best

From → computer

5 Comments
  1. Thomas Rehberg permalink

    wanted to use your script as it would exactly tackle a concern I have: no shutdown when Iḿ working on the system please..
    But I have no clue on any Perl scripts.. just that yours is not working in my case as in syslog it just says

    eb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 29: /usr/share/vdr/shutdown-hooks/S90.custom: use: not found
    Feb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 30: /usr/share/vdr/shutdown-hooks/S90.custom: use: not found
    Feb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 31: /usr/share/vdr/shutdown-hooks/S90.custom: use: not found
    Feb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 32: /usr/share/vdr/shutdown-hooks/S90.custom: use: not found
    Feb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 34: /usr/share/vdr/shutdown-hooks/S90.custom: Syntax error: “(” unexpected

    Any idea of what could be wrong here ?

    Thomas

    • Feb 11 15:58:21 Computerle vdr[13632]: /usr/share/vdr/shutdown-hooks/S90.custom: 34: /usr/share/vdr/shutdown-hooks/S90.custom: Syntax error: “(” unexpected

      Any idea of what could be wrong here ?

      Yes. Your script is executed by a shell (probably bash) and not by Perl.

      The scripts from shutdown-hooks directory are executed by /usr/lib/vdr/vdr-shutdown. vdr-shutdown contains the following lines:

          if [ -x $shutdownhook ]; then
              $log "executing $shutdownhook"
              result_data=`$shutdownhook "$@"`
          else
              $log "executing $shutdownhook as shell script"
              result_data=`/bin/sh $shutdownhook "$@"`
          fi
      

      Looks like your script does not have the executable bit set. To fix
      the issue you mention, you should run:

      sudo chmod 755 /usr/share/vdr/shutdown-hooks/S90.custom
      

      All the best

      • Thomas Rehberg permalink

        many thanks for this rapid reply, made S90.custom executable but it doesn t work either …
        not sure what Iḿ doing wrong here.

  2. I’ve updated the blog to mention that the shutdown-hook script must be made executable.

Trackbacks & Pingbacks

  1. Dominique Dumont: My setup for vdr automatic wake up and shutdown | Linux-Support.com

Leave a comment