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/d/4956-auto-shutdown-and-wakeup-for-scheduled-recordings
# 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(e)/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(suspend to ram) 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(RealtimeClock) 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(e) 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(e) 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