Project

General

Profile

Auto shutdown and wakeup for scheduled recordings

Added by Mr Rooster over 7 years ago

Hi All,

As a recent TVHeadend convert (from Myth) I've been really impressed with it. The configuration and speed of setup compared to Myth have been an eye opener. (It was actually due to a PVR box upgrade that I decided to give it a go, and after spending a week re-setting up Myth, being able to install TVH in a weekend was amazing, especially as I've used my for over 10 years so aren't exactly green when it comes to setting it up).

Anyway, the one thing I really do miss from Myth was the auto shutdown before recordings facility it offers. My PVR box is single use (backend/frontend) and only used for that, however it's also a creaky old PC so I don't really want it on all the time as it's not the most efficient thing.

I poked around and found these instructions on the wiki, which I used as a starting point to develop the below script.

I'm sharing it here hoping it'll be some use to others. It's basically similar to the provided instructions except:

  • Doesn't shutdown if a recording is in progress
  • Doesn't shutdown if a client frontend is connected. (Unless it's connecting on 127.0.0.1).
  • Doesn't shutdown if a recording is due... soon.

However, it does also use the web APIs, so I don't guarantee it'll work on any version of TVH other than the 4.2.1 I've currently got installed.

To use:

  • It uses a 'script' user, with the password 'script'. I did have this setup for localhost access, however I now run with the --disable-acl option so this isn't an issue. If it is you'll need to create a 'script' user with the password 'script'. (Or amend the script, and replace script:script with <user>:<pass>
  • You'll need curl installed.
  • Follow the instructions on the Wiki regarding drivers if that's an issue to you. (Basically, your machine needs to startup/shutdown cleanly).
  • If you're on an old debian/ubuntu and it doesn't wake up you'll need to disable the saving of the clock on shutdown. (Step 4 from https://ubuntuforums.org/showthread.php?t=1370585 if you need it).
  • You will need to ensure the TVHeadend user (in my case tvh) can shutdown/reboot the machine, I'm on Debian and have the following in /etc/sudoers.d/tvh:
# tvh can shutdown without asking
tvh  ALL= NOPASSWD: /sbin/shutdown, /usr/sbin/rtcwake

You can run the script using the post recording hook, however, as I like my PVR to stay on in the evenings and shutdown automagically all other times I have the following in my cron tab for the tvheadend user:

# m h  dom mon dow   command
*/10 2-16 * * * /home/tvh/bin/shutdown_after_rec.sh

this seems to work well.

The script itself. NB: It assumes TVH is running on the default ports on localhost:

#!/bin/sh

export PATH=/home/tvh/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

##
## Check for active connections, except those from the local machine.
##
if [ "`curl -s http://script:script@localhost:9981/api/status/connections | tr } '\n' | grep peer | grep -v 127.0.0.1`" != "" ]; then
        echo "Not shutting down due to active connections" | logger
        exit 0
fi

##
## Check for active recordings
##
curl -s "http://script:script@localhost:9981/api/dvr/entry/grid_upcoming?limit=99999" | grep -q '"sched_status":"recording",'
match=$?
if [ "$match" != "0" ]; then
        ##
        ## Not recording, can we shutdown?
        ##
        next_recording=`curl -s "http://script:script@localhost:9981/api/dvr/entry/grid_upcoming?limit=99999" | tr , '\n' | grep start_real | sed "s/.*start_real.:\([0-9]*\).*/\1/" | sort -n | head -1`

        ## 
        ## If there are no recordings we should wake up tomorrow
        ##
        if [ "$next_recording" = "" ]; then
          echo "No recordings... wake up tomorrow...." | logger
          next_recording=`date --date "tomorrow" +%s`
        fi

        gap=$(($next_recording-`date +%s`))

        echo Next recording: `date -d "1970-01-01 $next_recording sec" "+%F %H:%M:%S" -u` | logger

        if [ $gap -gt 900 ]; then
                ##
                ## The gap to the next recording is more than 15 minutes, so lets shutdown
                ##

                ##
                ## Set the wakeup for 10 minutes before the next recording
                ##
                wakeup=$((next_recording-600))
                wakeup_date=`date -d "1970-01-01 $wakeup sec" "+%F %H:%M:%S"`
                echo "Waking up at: $wakeup_date" | logger
                /usr/bin/sudo /usr/sbin/rtcwake -m no -t $wakeup
                ##
                ## Now shutdown
                ##
                /usr/bin/sudo /sbin/shutdown -P now
        fi
else
        ##
        ## Still recording, log the attempt and do nothing.
        ##
        echo "Still recording. Not shutting down." | logger
fi

Edit: Added limit=99999 to show all recordings, as pointed out by Janne Säilynkangas. :)


Replies (11)

RE: Auto shutdown and wakeup for scheduled recordings - Added by Nic Butcher about 7 years ago

Thanks for this - very useful.

Do you know how to use the api/dvr/entry/filemoved command?

I just get a '400 Bad request' when I try this:

curl -v "http://admin:admin@localhost:9981/api/dvr/entry/filemoved" --data-urlencode "src=/storage/tvshows/xxxxx.ts" --data-urlencode "dst=/nas/tv/xxxxx.ts" 

(not my real username / password obviously!)

Thanks

RE: Auto shutdown and wakeup for scheduled recordings - Added by Nic Butcher about 7 years ago

Update - apologies - it looks like this was correct:

curl -s "http://admin:admin@localhost:9981/api/dvr/entry/filemoved" --data-urlencode "src=/storage/tvshows/xxxxx.ts" --data-urlencode "dst=/nas/tv/xxxxx.ts" 

The reason I was getting a Bad request was a mistake in my parsing of the source and destination paths into the above command - Doh!

Anyway - in case anybody else is trying this, I can confirm the above works.

RE: Auto shutdown and wakeup for scheduled recordings - Added by Patrick Aldag about 7 years ago

So far the Script works fine.
But if there is no scheduled recording the pc doesnot suspend After the last recording.
I think IT would be great if you could implement something that Sets something like a daily wakeup for epg update aß long as there is no real timer?

RE: Auto shutdown and wakeup for scheduled recordings - Added by Mr Rooster about 7 years ago

I've updated the script to wake the machine up in 24 hours if there are no upcoming recordings.

If you use the script from the post recording hook this means the machine will stay awake until the next recording, so you should probably schedule it via cron once in a while too.

If you schedule the script via cron and often have no recordings make sure there is enough time for tvh to start and perform an EPG scan. You probably don't want it running more than once every 10 minutes.

To make the change, add:

        if [ "$next_recording" = "" ]; then
          echo "No recordings... wake up tomorrow...." | logger
          next_recording=`date --date "tomorrow" +%s`
        fi

Before the following line:

        gap=$(($next_recording-`date +%s`))

RE: Auto shutdown and wakeup for scheduled recordings - Added by Patrick Aldag about 7 years ago

Thanks for this.

I am still playing around and setting up the server ( i am not familiar with this).

Meanwhile I have some autorecodings set. this results in enough timers ;-).
But at the moment most timers are at weekends which means that the server often would not wake up for several days.
It would be nice if there is an option to wake up every second day.

Do i have to set the variable "TOMORROW" ?
I am also not experienced in sripting......

For the script used on a server i think i also have to implement some checks for connctions and other stuff.

RE: Auto shutdown and wakeup for scheduled recordings - Added by Mr Rooster about 7 years ago

Patrick Aldag wrote:

Meanwhile I have some autorecodings set. this results in enough timers ;-).
But at the moment most timers are at weekends which means that the server often would not wake up for several days.
It would be nice if there is an option to wake up every second day.

The $gap variable get set to the number of seconds before the next recording.

The script uses this to check that the next recording is more than 15 minutes away. You could also use this to check for recordings several days away.

So if you want to ensure the machine wakes up for the next record or in 2 days, whichever is sooner you could change:

        gap=$(($next_recording-`date +%s`))

To:

        gap=$(($next_recording-`date +%s`))
        if [ $gap -gt 172800 ]; then
                ##
                ## The gap to the next recording is more than 2 days, wakup in 2 days
                ##
                next_recording=`date --date "2 days" +%s`
                gap=$(($next_recording-`date +%s`))
        fi

172800 is the number of seconds in 2 days.

The value "2 days" after the --date argument can be changed. You can try these from the command line:

ian@pvr:~$ date
Mon 13 Nov 19:45:51 GMT 2017
ian@pvr:~$ date --date "3 days 5 hours" 
Fri 17 Nov 00:46:07 GMT 2017
ian@pvr:~$ date --date "3 days 12 hours" 
Fri 17 Nov 07:46:11 GMT 2017

Patrick Aldag wrote:

For the script used on a server i think i also have to implement some checks for connctions and other stuff.

I check for logged on users like this:

if [ "`who -q | grep users | cut -f2 -d=`" -gt 0 ];then
        echo "Logged on users..." >> /home/tvh/wake.log
        echo "Not shutting down due to logged on users:" | logger
        who -a | logger
        exit 0
fi

RE: Auto shutdown and wakeup for scheduled recordings - Added by Busybody Busybody almost 7 years ago

Hello,

I used this as basis for whipping up my own script.

Couple of things, I think the curl line should be curl -s http://script:script@localhost:9981/api/dvr/entry/grid_upcoming --data-urlencode "limit=99999"
Otherwise the page retrieved has only 50 upcoming recordings -> at least in my case (with many autorecs) this can resulted in omitted wakeup/shutdown times.

My setup differs in many places:
- I have a computer that runs 24/7, which then remotely shuts down/wakes up the TVHeadend-machine if no recordings are to be done in next "time" (I used 2 hours). You'll need shutdown rights via ssh and without a password, see following link for instructions.
[[https://askubuntu.com/questions/191257/how-could-i-shutdown-a-remote-host-in-my-network-thru-ssh-with-a-local-host]]

- TVH is only used as a DVR, so I removed all references to users being logged in.
- Wake-on-LAN needs to be configured and working
- Next shutdown is timed upon wakeup, so if you add recordings between wakeup and next shutdown, they are not taken into account. I tend to keep my scheduling at least few days into the future, so this is not a problem for me.
- I did this with perl, tried bash script which was very slow (probably due the million-time for-loops, which perl is better suited)

And yes, even though I'm a rookie with perl, I know there are ugly backtick-system calls and Perl-gurus are probably screaming bloody murder, but feel free to modify...

#!/usr/bin/perl -w
use strict;
use warnings;
use constant GRACE_TIME => 7200;    #time in seconds, 7200 = 2 hours.

#grep all start/stop times, remember limit=99999, by default it shows only >50 upcoming recordings
my @reclist = `curl -s http://script:script\@[IP.OF.TVH.BOX]:9981/api/dvr/entry/grid_upcoming --data-urlencode "limit=99999" | tr , "\n" | egrep "start_real|stop_real"`;
my $current_time = `date +%s`;
my @tuner_reserved = ();
my $time_to_start, my $time_to_stop;

foreach my $line (@reclist)
{
    #Start time of recording
    if($line =~ m/start_real/)
    {
        (my $start_time = $line) =~ s/"start_real"://;

        #Start time in the past - recording ongoing
        if($current_time >= $start_time)
        {
            $start_time = $current_time;
        }

        $time_to_start = $start_time - $current_time;
#        print "Recording starts at $time_to_start seconds \n";
        next;
    }

    if($line =~ m/stop_real/)
    {
                (my $stop_time = $line) =~ s/"stop_real"://;

        $time_to_stop = $stop_time - $current_time;
#        print "Recording stops at $time_to_stop seconds \n";
    }

    my $i=0;

#Arrays' elements denotes seconds from now as in timeline. We loop thru all recordings
#If recording ongoing on that second, insert "1" in array, otherwise undef.
    for( $i=$time_to_start; $i<$time_to_stop; $i++)
    {
        $tuner_reserved[$i] = 1;
    }
}

my $tuner_free_start=0;
my $tuner_free_stop=0;
my $a;
my $start_hr;
my $stop_hr;
my $shutdown_initiated=0;

#Loop thru all the seconds from now, 1M seconds is little over 1,5 weeks
for( $a=0 ; $a<1000000 ; $a++ )
{
    #No recording - tuners are free
    if(!$tuner_reserved[$a])
    {
        #First time to encounter state of "no recordings". Apply stop flag.
        if($tuner_free_start == 0)
        {
            $tuner_free_start = $a + $current_time;
            $tuner_free_stop = 0;
        }
    }
    #Tuners in use
    else
    {

        #Start of recording. If a=0, recording is ongoing right now.
        if($tuner_free_stop == 0 && $a != 0)
        {
            $tuner_free_stop = $a + $current_time;

            #Recording started now, we were in state of "no recordings" 
            if($tuner_free_start != 0)
            {

                #If state of "no recordings" lasts more than GRACE_TIME and this is the first
                #time that's happened -> apply shutdown/wakeup/rerun-this scripts

                my $free_duration = ($tuner_free_stop - $tuner_free_start);
                if (($free_duration >= GRACE_TIME) && ($shutdown_initiated == 0))
                {
                    #mangle dates, apply shutdown 60 seconds after recording is stopped, and wakeup 3 minutes
                    #before next recording. 3 minutes later rerun this script.
                    my $shutdown_time = $tuner_free_start+60;
                    $start_hr = `date -d \@$shutdown_time "+%R %d.%m.%Y"`;
                    my $wakeup_time = $tuner_free_stop-180;
                    $stop_hr = `date -d \@$wakeup_time "+%R %d.%m.%Y"`;
#                    print "Shutdown time $start_hr, wakeup time $stop_hr \n";
                    $shutdown_initiated = 1;
                                        my $rerun_time = `date -d \@$tuner_free_stop "+%R %d.%m.%Y"`;

                    `echo "ssh tvh_user\@IP.OF.TVH.BOX sudo shutdown -h now" | at $start_hr`;
                    `echo "etherwake -i enp[my_network_card] [MAC address of TVH box]" | at $stop_hr`;
                    `echo "/path/to/this_script.pl" | at $rerun_time`;
                }

#                Uncomment following lines for printing all times tuners are free
#                $start_hr = `date -d \@$tuner_free_start`;
#                chomp ($start_hr);
#                $stop_hr = `date -d \@$tuner_free_stop`;
#                chomp ($stop_hr);
#                $free_duration = $free_duration/60;
#                print "Tuners free between $start_hr and $stop_hr, duration of $free_duration minutes \n";
            }

            $tuner_free_start = 0;
        }
    }
}

RE: Auto shutdown and wakeup for scheduled recordings - Added by Mr Rooster almost 7 years ago

Janne Säilynkangas wrote:

Hello,

I used this as basis for whipping up my own script.

Couple of things, I think the curl line should be curl -s http://script:script@localhost:9981/api/dvr/entry/grid_upcoming --data-urlencode "limit=99999"
Otherwise the page retrieved has only 50 upcoming recordings -> at least in my case (with many autorecs) this can resulted in omitted wakeup/shutdown times.

Good catch! I'd missed that (and it might explain the odd missed recording I've had). Script updated.

Cheers. :D

RE: Auto shutdown and wakeup for scheduled recordings - Added by joey ramone over 6 years ago

hi

Thank you for the script, it works perfect with Build: 4.2.6 !

I have no idea about scripts, programming ..., so two questions :

It is possible to combine your script with other auto shutdow scripts like [[https://wiki.ubuntuusers.de/Skripte/Auto_OFF/]]
And second, I have a vbox xti 3442 and want to shutdown after recording .... . With this http command [[http://&lt;VBox IP>/cgi-bin/ManageApp/ManageApp?OPTION=48&shutdown_action=Shutdown+System+]] it is possible, but how I can use it with your script ?

By e nepo

RE: Auto shutdown and wakeup for scheduled recordings - Added by Walter av about 6 years ago

Thanks "Mr Rooster", I modified the script for Debian 9 and Ubuntu 16.04 with TvHeadend 4.2.6 with suspend in mind(instead of shutdown).

However I added a re-sleep fix, for example if the system suspends every 10nth minutes by cronjob, but if it wakes at every 9nth minute /19/29/39/49/59 it mostly enters sleep again just after it woke up without having enough time to let kodi frontend connect to tvheadend server to generate active sessions to stop sleep and keep system awake. With re-sleep fix it will stay another 10 minute cycle alive. I also modified some folder/binary paths that were needed for debian/ubuntu and my personal needs. I guess this is also a problem currently with your shutdown script, but maybe with a "uptime" check this can be fixed?

Newcomers keep in mind that additional suspend/sleep/wake system adjustments may be necessary to unload/stop certain unstable kernel modules/processes before sleep and reload them after sleep. See comments in script and end of post for example. If you just use shutdown instead of sleep(suspend) its easier.

#!/bin/bash
# https://tvheadend.org/boards/4/topics/27066
# shutdown vs suspend doesn't create wakeup data for correct re-sleep check

TVHINSTU=hts
TVHWUSER=sleepuser
TVHWPASS=sleeppass
TVHIPADD=127.0.0.1
TVHHPORT=9981

#/etc/sudoers.d/hts
# hts user can shutdown with sudo permission
#hts  ALL= NOPASSWD: /bin/systemctl poweroff,/bin/systemctl halt,/bin/systemctl reboot,/bin/systemctl suspend,/usr/sbin/rtcwake,/bin/journalctl

#sudo crontab -u hts -e 
#*/10 * * * * /home/hts/shutdown_after_rec.sh

#verify suspend compatibility and adjust remove/reload some kernel modules before after suspend
#https://askubuntu.com/questions/226278/run-script-on-wakeup
#/lib/systemd/system-sleep/yoursleepscript

#test system rtcwake abilities
#sudo apt-get install utils-linux
#sudo rtcwake -s 240 -m no #will set a wakeup time 4 minutes from now
#timedatectl #shows local/rtc time
#sudo rtcwake -m show #shows the bios time for waking up -u -l utc local -a auto=default
#sudo systemctl suspend;exit #test and see if the system wakes in 4 minutes
#sudo rtcwake -m no -t $(date +%s -d 'today 19:45')
#sudo rtcwake -m show #check time what has been set if it correlates rtc to utc

#test system wakeonlan abilities
#cat /proc/acpi/wakeup
#sudo ethtool eth0 #pumb if the 'g' is missing it won't wake on magic packet!!! 
#sudo ethtool -set eth0 wol g #sets the 'g' as a condition to wake from lan

#tvheadend sleep user allow / set checkboxes video recording "manage all" to detect recordings
#ok recording realtime takes intro/ending padding in account
#ok rtcwake event takes padding&warmup in account

export PATH=/home/$TVHINSTU:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

WAKEDATE=$(sudo journalctl -b 0 -o short-iso MESSAGE="PM: Finishing wakeup." | tail -1 | cut -d" " -f1 | sed -e 's/+.*//')
DATEWAKE=$(date -d"$WAKEDATE" +%s )
DATENOW=$(date +%s)

A=$(($DATENOW-$DATEWAKE))
B=540 #seconds 9 minutes
if (( A < B));
    then
        echo "$TVHINSTU user last suspend request was $A < 540 seconds ago skip suspend" | logger
        exit 0
    else
        echo "$TVHINSTU user last suspend request was $A > 540 seconds ago continue suspend" | logger
##
## Check for active connections, except those from the local machine.
##
if [ "`curl -s http://$TVHWUSER:$TVHWPASS@$TVHIPADD:$TVHHPORT/api/status/connections | tr } '\n' | grep peer | grep -v 127.0.0.1`" != "" ]; then
        echo "$TVHINSTU user detects active TvHeadend connections skip suspend" | logger
        exit 0
fi

##
## Check for active recordings
##
curl -s "http://$TVHWUSER:$TVHWPASS@$TVHIPADD:$TVHHPORT/api/dvr/entry/grid_upcoming?limit=99999" | grep -q '"sched_status":"recording",'
match=$?
if [ "$match" != "0" ]; then
        ##
        ## Not recording, can we shutdown?
        ##
        next_recording=`curl -s "http://$TVHWUSER:$TVHWPASS@$TVHIPADD:$TVHHPORT/api/dvr/entry/grid_upcoming?limit=99999" | tr , '\n' | grep start_real | sed "s/.*start_real.:\([0-9]*\).*/\1/" | sort -n | head -1`

        ## 
        ## If there are no recordings we should wake up tomorrow 
        ## everyday wakeup for epg index?
        if [ "$next_recording" = "" ]; then
          echo "$TVHINSTU user detects no TvHeadend scheduled recordings, set EPG update wake" | logger
          next_recording=`date --date "tomorrow" +%s`
        fi

        gap=$(($next_recording-`date +%s`))

        echo Next recording: `date -d "1970-01-01 $next_recording sec" "+%F %H:%M:%S" -u` | logger

        if [ $gap -gt 2400 ]; then
                ##
                ## The gap to the next recording is more than 40 minutes, so lets shutdown
                ##

                ##
                ## Set the wakeup for 2 minutes before the next recording
                ##
                wakeup=$((next_recording-120))
                wakeup_date=`date -d "1970-01-01 $wakeup sec" "+%F %H:%M:%S"`
                echo "$TVHINSTU user sets wake up for next TvHeadend event at: $wakeup_date" | logger
                /usr/bin/sudo /usr/sbin/rtcwake -m no -t $wakeup
                ##
                ## Now shutdown
                ##
                /usr/bin/sudo /bin/systemctl suspend #poweroff
        fi
else
        ##
        ## Still recording, log the attempt and do nothing.
        ##
        echo "$TVHINSTU user detects active TvHeadend recording(s) skip suspend" | logger
fi
        #exit 0
fi

Before this nice suspend script may work for you, its important to know if your Debian/Ubuntu TvHeadend server suspends/wakes without issues in the first place! A good start is a minimal Debian/Ubuntu CLI install (without GUI/desktop) and without internal/external connected PCI/USB DVB-tuner hardware, even without TvHeadend package! First try to bring the system asleep:

sudo systemctl suspend;exit

If it sleeps for a couple of minutes (check if all fans are silent?), than wake it up with power button (keyboard / mouse may work). When its awake again check kernel driver diagnosticmessage "dmesg" to see if any errors popup after sleep. If the system won't sleep or wake, check BIOS/UEFI settings and make sure SLEEP/SUSPEND related settings are set to anything with S3/STR instead of S1 or other.
sudo dmesg

Add DVB-tuner(s) one at the time (don't install TvHeadend yet) check with "lsmod" to see what modules they load and install Tvheadend and notice that some tuners load even more kernel modules. Sleep the system again if there are some devices that may not wakeup correctly unload their kernel modules before sleep with the following script in "/lib/systemd/system-sleep/examplescript". For example I need to unload the modules for a elgato DVB-C USB Tuner and a Technotrend DVB-S2/CAM PCI Tuner and notice that I also stop tvheadend service!

sudo nano /lib/systemd/system-sleep/examplescript #copy past script below
sudo chmod a+x /lib/systemd/system-sleep/examplescript
#!/bin/sh
#https://askubuntu.com/questions/226278/run-script-on-wakeup #SpmP

case $1/$2 in
  pre/*)
    echo "Going to $2..." 
    # Place your pre suspend commands here, or `exit 0` if no pre suspend action required
systemctl stop tvheadend
    sleep 3
modprobe -r em28xx_alsa
modprobe -r em28xx_dvb
modprobe -r em28xx_rc
modprobe -r em28xx
modprobe -r drxk

modprobe -r budget_ci
modprobe -r budget_core
modprobe -r tda18271
modprobe -r stb0899
modprobe -r stb6100
modprobe -r lnbp21
modprobe -r rc_tt_1500
modprobe -r rc_nec_terratec_cinergy_xs
    ;;
  post/*)
    echo "Waking up from $2..." 
    # Place your post suspend (resume) commands here, or `exit 0` if no post suspend action required
modprobe budget_ci
modprobe em28xx_dvb
sleep 5
systemctl restart tvheadend
    ;;
esac

If system sleeps and wakes correctly its time to check if RTC is affective on letting the system poweron/wake from off/suspend. On Debian/Ubuntu "rtcwake" must be installed by the package "util-linux".

sudo apt-get install util-linux

To test if the system wakes 10 minutes from now (after suspending it again ;-) do:

sudo rtcwake -s 600 -m no #will set a wakeup event 600 seconds from now
sudo rtcwake -m show #shows wake time in UTC don't worry if its not local time!
timedatectl #shows your current local time and BIOS UTC time
sudo systemctl suspend;exit #sleeps system now wait for ~10 minutes and see if it powers up

If the system won't powerup, check if your local system time( = +- ~x hours from UTC) / BIOS=UTC time are correctly matching. Also check BIOS that its using UTC time instead of local and that some power related settings in BIOS allow poweron by rtc/clock event/alarm PCI device etc.

If these conditions are met its time to install "Mr Rooster" modified TvHeadend Auto shutdown/suspend and wakeup script. Notice that it need to setup with correct permissions for correct user and a corresponding cronjob for that user! First create script, fix ownership/execution and than give tvheadend user sudo permissions to allow suspending and at a cronjob timer.

sudo nano /home/hts/sleep_after_rec.sh #use script from begining of this topic
sudo chmod +x /home/hts/sleep_after_rec.sh #makes it executable
sudo chown hts:hts /home/hts/sleep_after_rec.sh #makes hts user own it

sudo nano /etc/sudoers.d/hts #add following lines without comments!
hts  ALL= NOPASSWD: /bin/systemctl poweroff,/bin/systemctl halt,/bin/systemctl reboot,/bin/systemctl suspend,/usr/sbin/rtcwake,/bin/journalctl

sudo crontab -u hts -e #add a cronjob timer every 10 minutes
#*/10 * * * * /home/hts/sleep_after_rec.sh

Almost every thing is ready, but you'll notice the #comment before the cronjob timer, if it was not there your system automatically fall asleep every 10 minutes! Just need to create a TvHeadend user from the webinterface which is capable of listing connection and user status, create a admin username/password "sleepuser"/"sleeppass" with all defaults but also checkbox video recording "manage all" to detect recordings.

The test the interaction of the sleep script, we'll manually trigger it with active sessions (nearby-upcoming)recording and or kodi htsp users active viewing connections (also VLC from tvheadend webinterface is correct. Start to watch a TV-channel from the server and manually trigger sleep.

sudo -u hts /home/hts/sleep_after_rec.sh #will test sleep as user hts

If everything works correct the system won't sleep since it detects a active viewing connection, see the log files to see that the sleep script did run but did not finish.

sudo cat /var/log/syslog | grep hts
#... hts: hts user last suspend request was 4202 > 540 seconds ago continue suspend...
#... hts: hts user detects active TvHeadend recording(s) skip suspend...

Stop active viewing/recording sessions schedule a recording an hour from here and force sleep again:

sudo -u hts /home/hts/sleep_after_rec.sh

If the system sleeps and wakes for recording and sleeps again you may activate the cronjob(remove #comment) and your done.

sudo crontab -u hts -e #add a cronjob timer every 10 minutes
*/10 * * * * /home/hts/sleep_after_rec.sh

WAKE ON LAN "WOL"
This can be used to let a kodi client trigger a event to remotely wake the tvheadend server for watching. The enable wakeonlan on TvHeadend server, check BIOS setting for waking on LAN/Ethernet PCI/PCI activity and check in Debian/Ubuntu following settings:

sudo apt-get install ethtool
sudo ethtool eth0 #check current WOL settings
#       ....
#    Supports Wake-on: pg
#    Wake-on: pbum
#    Current message level: 0x0000003f (63)
#       ...

sudo ethtool -set eth0 wol g #set WOL magic packet
#       ....
#    Supports Wake-on: pg
#    Wake-on: g
#    Current message level: 0x0000003f (63)
#       .

#Some systems need acpi trigger for specific pci slot/device in my example LAN0 device says "disabled" 
cat /proc/acpi/wakeup #look for something that looks like LAN/Ethernet/SLOT lspci -tn

#after following command /proc/acpi/wakeup shows "enabled" 
echo "LAN0" | sudo tee /proc/acpi/wakeup

#if necessary add ethtool/ echo proc/acpi/wake to /etc/rc.local if wakeonlan settings are not saved!

sudo ifconfig #lookup macaddress of eth0

sudo systemctl suspend#or wait for script to suspend it

On the Client side install and do the following the wake the remote TvHeadend server. Or use my roraspbiankodi cient image.

sudo apt-get install wakeonlan
wakeonlan macaddress #wakes the tvheadend server

This raspbian based kodi image is readonly/power outage/cut proof and triggers wakeonlan as soon as television goes on with raspberry pi.
https://github.com/walterav1984/roraspbiankodi

RE: Auto shutdown and wakeup for scheduled recordings - Added by Stefan Pappalardo over 3 years ago

Hello Everybody,

here is another solution...

  1. cron: /etc/cron.d/autoff
  2. config: /etc/autoff.conf
  3. script: /usr/local/sbin/autoff

/etc/cron.d/autoff

*/5 * * * * root /usr/local/sbin/autoff

The script is started by cron every 5 minutes.

/etc/autoff.conf

USER="admin" 
PASS="<password>" 
HOST="<hostname>" 

User, password and hostname are separated for security reason.
<password> and <hostname> has to be replaced with values fitting of your tvheadends' http api.
Be sure that the file is only readable to the user/group it's started with, i.e. with the following chmod command.

sudo chmod o-rwx /etc/autoff.conf

/usr/local/sbin/autoff

  • logs to syslog
  • checks for
    1. active tvh connections
    2. active tvh subscriptions
    3. active ssh connections
    4. active user sessions (logged in users)
  • gets next planned recording time and sets wakeup time
    1. no planned recording or recording is more than 24 hours ahead: set wakeup time to tomorrow morning at 02:00
    2. next recording seems to be in the past: exit with error code 1
    3. next recording will start during the next 30 minutes: don't shut down and exit with code 0
    4. else: set wakeup time to next recording minus 10 minutes (to give time for boot, check disk, EPG/EIT grab etc.)
  • writes wakeup time to realtime clock
  • shuts down the system
  • cron sends mail on error (if postfix/sendmail is configured correctly)
#!/bin/bash

# USER, PASS and HOST needs to be in config file only readable to root
. /etc/autoff.conf

logit()
{
    # add --stderr to output the message to standard error as well as to the
    # system log
    logger --priority local0.notice --tag autoff -- $*
    return 0
}

IsBusy()
{
    # check for active tvh connections
    TVHCONNS=$(curl --silent --show-error --digest --user "${USER}:${PASS}" \
    "http://${HOST}:9981/api/status/connections" | jq ".totalCount")
    if [ $TVHCONNS -gt 0 ]; then
        logit "${TVHCONNS} tvh connection(s) found" 
        return 1
    fi

    # check for active tvh subscriptions
    TVHSUBS=$(curl --silent --show-error --digest --user "${USER}:${PASS}" \
    "http://${HOST}:9981/api/status/subscriptions" | jq ".totalCount")
    if [ $TVHSUBS -gt 0 ]; then
        logit "${TVHSUBS} tvh substription(s) found" 
        return 1
    fi

    # check for running comskip processes
    CSPROCS=$(ps --no-headers -C comskip | wc --lines)
    if [ $CSPROCS -gt 0 ]; then
        logit "${CSPROCS} comskip processe(s) found" 
        return 1
    fi

    # check for established ssh connections
    IP=$(hostname --ip-address)
    SSHCONNS=$(LANG=C netstat --tcp --numeric | grep "${IP}:22" | wc --lines)
    if [ $SSHCONNS -gt 0 ]; then
        logit "${SSHCONNS} ssh connection(s) found" 
        return 1
    fi

    # check for logged in users
    USERS=$(who | wc --lines)
    if [ $USERS -gt 0 ]; then
        logit "$USERS logged in user(s) found" 
        return 1
    fi

    # idle
    logit "system is idle" 
    return 0
}

IsBusy
BUSY=$?
if [ $BUSY -eq 0 ]; then
    # get start time for next recording
    NEXTREC=$(curl --silent --show-error --digest --user "${USER}:${PASS}" \
    --data-urlencode "limit=999" \
    "http://${HOST}:9981/api/dvr/entry/grid_upcoming" | \
    jq "[ .entries[] | {start_real,status} | \
    select(.status!=\"Invalid\") ] | min_by(.start_real) | .start_real")
    if [ "$NEXTREC" == "null" ]; then
        logit "no planned recording found" 
    else
        logit "next recording time: $(date --date=@${NEXTREC})" 
    fi

    # set wakeup time
    if [ "$NEXTREC" == "null" ] || \
        [ $NEXTREC -gt $(($(date +%s) + 86400)) ]; then
        WAKEUP=$(date --date='02:00 tomorrow' +%s)
        logit "no planned recording in the next 24 hours found" 
        logit "wakelarm set to $(date --date=@$WAKEUP)" 
        echo 0 > /sys/class/rtc/rtc0/wakealarm
        echo $WAKEUP > /sys/class/rtc/rtc0/wakealarm
    elif [ $NEXTREC -lt $(date +%s) ]; then
        logit "error, next planned recording seems to be in the past" 
        exit 1
    elif [ $NEXTREC -lt $(($(date +%s) + 1800)) ]; then
        logit "next planned recording starts in less than 30 minutes" 
        logit "shutdown aborted" 
        exit 0
    else
        WAKEUP=$(($NEXTREC - 600))
        logit "wakelarm set to $(date --date=@$WAKEUP)" 
        echo 0 > /sys/class/rtc/rtc0/wakealarm
        echo $WAKEUP > /sys/class/rtc/rtc0/wakealarm
    fi

    # shutdown
    logit "initiate shutdown" 
    /sbin/halt -p
    exit 0
else
    # aborted
    logit "shutdown aborted" 
    exit 0
fi

logit "error" 
exit 1
    (1-11/11)