Project

General

Profile

Powersave, auto shutdown and auto startup

Added by Dutchy Nl over 4 years ago

To auto-shutdown and auto-startup a computer which only serves as a TvHeadend-server and/or Samba-server, the next script might be of some help. It's been tested on Ubuntu-12.04-server.

What the script does for you, is checking (default every 60 seconds) if your system can be shut off unless:
  • it is less than a given minimum period of time the system is running (default 30 minutes)
  • you are watching Tv or a recording (with delay, default 30 minutes)
  • a recording is taking place
  • within a short time a new recording will start (default 10 minutes)
  • you are up- or downloading files (with delay, default 30 minutes)
  • you are logged in on the system
  • a post recording or any other process you specified is active

What the script also does for you, is switching your system on short before a new recording should start (default 3 minutes).
Example: program will start at 10:00, start ahead TvHeadend 5 mins, so wakeup is at 9:52 and recording can start at 9:55.

Some hints:
  • Be sure the RTC is set (and stays set) to UTC-time.
  • Also be sure that the user who calls the script has rights to execute (see the wiki about “HowTo wakeup XBMC/TVHeadend for scheduled recording”).
  • Be sure Curl and Netstat are installed.
  • Run the script with "sudo"-rights on boot. It will remain active until shutdown.
  • Install and use Webmin to manage your system and to program the script to run on boot the easy way.
    (Start webmin session > system > bootup and shutdown > create a new upstart service.)
    Add “10000” to the “port_numbers” parameter to prevent the system from shutting down when logged in on Webmin.
  • Eject/disconnect the network drive in your filemanager after up- or downloading files. Otherwise the system won't shutdown.

USE FOR TVHEADEND 3.4

#!/bin/bash

# BASIC SETTINGS change at wish

# Settings you have to look at
# TvHeadend login and password
tvh_login=YOUR_LOGIN_NAME
tvh_password=YOUR_PASSWORD
# (post recording) process activity to be checked, leave blank to deactivate
process_check=(PROCESS_A PROCESS_B)

# Settings you might look at
# portnumbers to be checked for user activity (tvheadend 9981 + 9982 and samba 445)
port_numbers=(9981 9982 445)
# minimum time in seconds needed for consecutive shutdown AND startup
safe_margin_shutdown=600
# minimum time in seconds needed to start up the computer properly
safe_margin_startup=180
# minimum time in minutes not to shutdown after last user activity (watching tv/recording, up-/downloading files, booting the system)
idle_time_shutdown=30
# maximum time in hours not to wake up for updating EPG
epg_hours=48
# interval in seconds the script will check if the system should be shutdown
script_int=60

# END OF BASIC SETTINGS keep out from here ;-)

# retrieve IP_address tvheadend server
tvh_ip=$(hostname -I | awk '{print $1}')

# set language
export LANG=C

# set session start
uptime_boot_sec=$(cat /proc/uptime | awk -F ' ' '{print$1}' | awk -F '.' '{print$1}')
boot_time=$(($(date +%s)-uptime_boot_sec))

# initial value do not change
recording=1

# check for shutdown
until [ $recording -eq 0 ];do

# initial values do not change
    recording=0
    shutdown_timer=$idle_time_shutdown
    ping_array=()

# countdown to shutdown
    until [ $shutdown_timer -eq 0 ];do
        shutdown_timer=$((shutdown_timer-1))

# check for server connection tvheadend samba or any other server according to settings above
        status_netstat=1
        until [ $status_netstat -eq 0 ];do
            status_netstat=0
            sleep $script_int
            for i in $( echo "${port_numbers[*]}"); do
                port_no=$i
                for i in $(echo $(netstat -n | grep -i "ESTABLISHED" | grep "$tvh_ip:$port_no" |  awk -F ':' '{print ":"$2}' | sed 's/:'$port_no'\|[ ]//g')); do
                    shutdown_timer=$idle_time_shutdown
                    status_netstat=1
                    ping_array[$(echo "${#ping_array[*]}")]=$i
                done
            done
            ping_array=($(echo "${ping_array[*]}" | sed 's/[ ]/\n/g' | awk '!a[$0]++' ))
        done
        for i in $(echo "${ping_array[*]}"); do
            if [ $( ping -c1 $i | grep "received" | awk -F ',' '{print $2}' | awk '{print $1}' ) -eq 0 ]; then
                ping_array=($(echo "${ping_array[*]/$i/}"))
            fi
        done
        if [ $(echo "${#ping_array[*]}") -eq 0 -a $boot_time -lt $(($(date +%s)-idle_time_shutdown*60)) ]; then
            shutdown_timer=0
        fi
        if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -ne 0 -a $shutdown_timer -eq 0 ]; then
            shutdown_timer=1
        fi

    done

# check for active post recording processes
    total_processes=0
    for i in $( echo "${process_check[*]}"); do
        counter=$( ps -A | grep "$i" | wc -l )
        total_processes=$((total_processes+counter))
    done
    if [ $total_processes -ne 0 ]; then
        recording=$((recording+1))
    fi

# check for active users
    if [ $(who | wc -l) -ne 0 ]; then
        recording=$((recording+1))
    fi

# retrieve and calculate wake up data
    if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -eq 0 ]; then
        wake_after_min=$((epg_hours*60))
        if [ $(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $3}' | awk -F '<' '{print $1}' | wc -l) -gt 0 ]; then
            wake_after_min_temp=$(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $3}' | awk -F '<' '{print $1}')
            if [ $wake_after_min -gt $wake_after_min_temp ]; then
                wake_after_min=$wake_after_min_temp
            fi
        fi
    else
        wake_after_min=0
    fi
    wake_after_secs=$((wake_after_min*60))

# check safe margin shutdown
    if [ $safe_margin_shutdown -gt $wake_after_secs ]; then
        recording=$((recording+1))
    fi

done

# set RTC wake up time
stop_date=$(date +%s)
wake_date=$((stop_date+wake_after_secs-safe_margin_startup))
echo 0 > /sys/class/rtc/rtc0/wakealarm
echo $wake_date > /sys/class/rtc/rtc0/wakealarm

# shutdown computer
sudo shutdown -h now

USE FOR TVHEADEND 3.5 and up due to modified status.xml.

#!/bin/bash

# BASIC SETTINGS change at wish

# Settings you have to look at
# TvHeadend login and password
tvh_login=YOUR_LOGIN_NAME
tvh_password=YOUR_PASSWORD
# (post recording) process activity to be checked, leave blank to deactivate
process_check=(PROCESS_A PROCESS_B)

# Settings you might look at
# portnumbers to be checked for user activity (tvheadend 9981 + 9982 and samba 445)
port_numbers=(9981 9982 445)
# minimum time in seconds needed for consecutive shutdown AND startup
safe_margin_shutdown=600
# minimum time in seconds needed to start up the computer properly
safe_margin_startup=180
# minimum time in minutes not to shutdown after last user activity (watching tv/recording, up-/downloading files, booting the system)
idle_time_shutdown=30
# maximum time in hours not to wake up for updating EPG
epg_hours=48
# interval in seconds the script will check if the system should be shutdown
script_int=60

# END OF BASIC SETTINGS keep out from here ;-)

# retrieve IP_address tvheadend server
tvh_ip=$(hostname -I | awk '{print $1}')

# set language
export LANG=C

# set session start
uptime_boot_sec=$(cat /proc/uptime | awk -F ' ' '{print$1}' | awk -F '.' '{print$1}')
boot_time=$(($(date +%s)-uptime_boot_sec))

# initial value do not change
recording=1

# check for shutdown
until [ $recording -eq 0 ];do

# initial values do not change
    recording=0
    shutdown_timer=$idle_time_shutdown
    ping_array=()

# countdown to shutdown
    until [ $shutdown_timer -eq 0 ];do
        shutdown_timer=$((shutdown_timer-1))

# check for server connection tvheadend samba or any other server according to settings above
        status_netstat=1
        until [ $status_netstat -eq 0 ];do
            status_netstat=0
            sleep $script_int
            for i in $( echo "${port_numbers[*]}"); do
                port_no=$i
                for i in $(echo $(netstat -n | grep -i "ESTABLISHED" | grep "$tvh_ip:$port_no" |  awk -F ':' '{print ":"$2}' | sed 's/:'$port_no'\|[ ]//g')); do
                    shutdown_timer=$idle_time_shutdown
                    status_netstat=1
                    ping_array[$(echo "${#ping_array[*]}")]=$i
                done
            done
            ping_array=($(echo "${ping_array[*]}" | sed 's/[ ]/\n/g' | awk '!a[$0]++' ))
        done
        for i in $(echo "${ping_array[*]}"); do
            if [ $( ping -c1 $i | grep "received" | awk -F ',' '{print $2}' | awk '{print $1}' ) -eq 0 ]; then
                ping_array=($(echo "${ping_array[*]/$i/}"))
            fi
        done
        if [ $(echo "${#ping_array[*]}") -eq 0 -a $boot_time -lt $(($(date +%s)-idle_time_shutdown*60)) ]; then
            shutdown_timer=0
        fi
        if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -ne 0 -a $shutdown_timer -eq 0 ]; then
            shutdown_timer=1
        fi

    done

# check for active post recording processes
    total_processes=0
    for i in $( echo "${process_check[*]}"); do
        counter=$( ps -A | grep "$i" | wc -l )
        total_processes=$((total_processes+counter))
    done
    if [ $total_processes -ne 0 ]; then
        recording=$((recording+1))
    fi

# check for active users
    if [ $(who | wc -l) -ne 0 ]; then
        recording=$((recording+1))
    fi

# retrieve and calculate wake up data
    if [ $(curl -s --user $tvh_login:$tvh_password http://127.0.0.1:9981/status.xml | grep "subscriptions" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') -eq 0 ]; then
        wake_after_min=$((epg_hours*60))
        if [ $(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}' | wc -l) -gt 0 ]; then
            wake_after_min_temp=$(curl -s --user $tvh_login:$tvh_password 127.0.0.1:9981/status.xml | grep "next" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}')
            if [ $wake_after_min -gt $wake_after_min_temp ]; then
                wake_after_min=$wake_after_min_temp
            fi
        fi
    else
        wake_after_min=0
    fi
    wake_after_secs=$((wake_after_min*60))

# check safe margin shutdown
    if [ $safe_margin_shutdown -gt $wake_after_secs ]; then
        recording=$((recording+1))
    fi

done

# set RTC wake up time
stop_date=$(date +%s)
wake_date=$((stop_date+wake_after_secs-safe_margin_startup))
echo 0 > /sys/class/rtc/rtc0/wakealarm
echo $wake_date > /sys/class/rtc/rtc0/wakealarm

# shutdown computer
sudo shutdown -h now

Replies (13)

RE: Powersave, auto shutdown and auto startup - Added by M Rust over 4 years ago

Many thanks for your script! Great!

I've made 2 changes to the script to make it work for my environment:

- Add option "-s" (silent) to all curl instances. Otherwise you will be trashed with progress bar output.
- Add "export LANG=C" at the top. Otherwise the output of "netstat" might be localized and your grep for "ESTABLISHED" will not work.

RE: Powersave, auto shutdown and auto startup - Added by Dutchy Nl over 4 years ago

Thanks!
As you can see, the script is changed as suggested.
Which release of tvheadend do you use?

RE: Powersave, auto shutdown and auto startup - Added by M Rust over 4 years ago

Very good. Thank you!

I use the most current git-release 4.1.

RE: Powersave, auto shutdown and auto startup - Added by Dutchy Nl over 4 years ago

So the script for 3.5 also does the job for version 4.* :)

RE: Powersave, auto shutdown and auto startup - Added by piotr w over 4 years ago

Hi & thanks for the script. I need to add one more check: I need to see if my mediacenter is running (regardless of watching tv or recording), how can this be done ?

Thanks !

RE: Powersave, auto shutdown and auto startup - Added by piotr w over 4 years ago

I'm running Kodi as a frontend. Kodi wakes up the Tvheadend Server (WOL). I'm not always watching a tv or a recording but also movies/tvshows and I don't want the Tvheadend server to shutdown when I'm watching a movie or a tvshow. So a ping-check to the Kodi machine would suffice.

RE: Powersave, auto shutdown and auto startup - Added by piotr w over 4 years ago

I dont use samba, movies and tvshows are on an nfs share on my nas. Not on the tvheadend server.

RE: Powersave, auto shutdown and auto startup - Added by piotr w over 4 years ago

No. I dont want to shutdown my nas. I want to shutdown my tvheadend server. But only if machine with ip 192.168.1.5 is down, i.e. when a ping from the script to 192.168.1.5 times out.

RE: Powersave, auto shutdown and auto startup - Added by Christian . about 3 years ago

I wrote a script to shutdown and wakeup the system based on Tvheadend activity. Is is based on systemd and uses the REST API instead of the local file system to check upcoming recordings. You can find it on GitHub.

RE: Powersave, auto shutdown and auto startup - Added by Daniel Ellis about 3 years ago

In order to add an LCD status display, I've taken Dutchy NL's bash scripts and re-implemented them using python. See https://tvheadend.org/boards/4/topics/23183

RE: Powersave, auto shutdown and auto startup - Added by Paul Hey over 2 years ago

I am attempting to get this script working, but I am not entirely sure of the correct procedure.

I would like somebody, if possible to elaborate upon the following:

Install and use Webmin to manage your system and to program the script to run on boot the easy way.
(Start webmin session > system > bootup and shutdown > create a new upstart service.)

I have webmin up and running, but I am stuck on the "create new upstart service" part. Does the script need to be put somewhere in particular in order that webmin can find it? I have been googling a couple of hours now, and find myself becoming more and more confused! Even the webmin tutorial doesn't seem to make sense.

What do I enter into "Commands to run before starting server" and "Server program and parameters"?

Sorry if these are rookie questions...

RE: Powersave, auto shutdown and auto startup - Added by Robert Cameron over 2 years ago

Paul Hey wrote:

I am attempting to get this script working, but I am not entirely sure of the correct procedure.

I would like somebody, if possible to elaborate upon the following:

Install and use Webmin to manage your system and to program the script to run on boot the easy way.
(Start webmin session > system > bootup and shutdown > create a new upstart service.)

I have webmin up and running, but I am stuck on the "create new upstart service" part. Does the script need to be put somewhere in particular in order that webmin can find it? I have been googling a couple of hours now, and find myself becoming more and more confused! Even the webmin tutorial doesn't seem to make sense.

What do I enter into "Commands to run before starting server" and "Server program and parameters"?

Sorry if these are rookie questions...

"Upstart" was the init system that used to be used by Ubuntu systems. Now most everything is using systemd unit files. To achieve the same basic result, you will create a new service unit in /etc/systemd/service, and then you can have the service run at boot by enabling it with systemctl enable [your_service].service.

For an overview of systemd, check out Arch's wiki entry on it: https://wiki.archlinux.org/index.php/Systemd

Even if you don't run Arch as your distro, their wiki is pretty comprehensive, provides lots of information that is general, and specifics can usually be easily adapted to your individual distro.

RE: Powersave, auto shutdown and auto startup - Added by Paul Hey over 2 years ago

Thank you Robert, that would explain why I can't find any good recent info. I will read and digest the link you have posted.

    (1-13/13)