#!/usr/bin/tclsh # global debug, set to 1 ... set debug 1 # default increment for sleep timer (must be > 5 for sleep notifications to # make sense) set INC 10 # maximum sleep amount set max_sleep_time [expr 30*60] proc WhenToCallMythDialog {} { global INC debug end_time set now [clock seconds] set mins_left [expr ($end_time-$now+30)/60] set secs_left [expr $end_time-$now] if { $mins_left > $INC } { after [expr $INC*60*1000] { set now [clock seconds] set mins_left [expr ($end_time-$now+30)/60] MythDialog "Sleep: $mins_left minutes" } if { $debug } { puts "should wait $INC mins..." } } elseif { $mins_left > 5 } { # if we have less than INC (10) left, then lets just say "5 minutes to go" after [expr ($INC-5)*60*1000] { MythDialog "Sleep: 5 minutes" } if { $debug } { puts "should wait [expr $INC-5] mins..." } } elseif { $mins_left > 1 } { # if we have more than 1, but less than 5 sleep for 4 minutes (leaving 1 more minute) after [expr 4*60*1000] { MythDialog "Sleep: 1 minute" } if { $debug } { puts "should wait 1 min..." } } elseif { $secs_left > 30} { after [expr 30*1000] { MythDialog "Sleep: 30 seconds" } if { $debug } { puts "should wait 30 sec..." } } else { # 27 seconds + 3 timeone and the box shutsdown after [expr 27*1000] { MythDialog "Sleep: Shutting Down" } if { $debug } { puts "Shutting down..." } } } proc MythDialog {str} { puts "MythDialog $str" catch {exec /usr/bin/mythutil --message --message_text "$str" --timeout 3 --bcastaddr=127.0.0.1} WhenToCallMythDialog } # when a client calls the server, we are either going to show the current # remaining time (if the call is within 4 seconds of the last call), or add to # the timer... (modulo max_sleep_time) proc HandleNewRequest {channel clientaddr clientport} { global debug end_time last_request_time set now [clock seconds] # this must be the first time this server has been called if { ! [info exists last_request_time] } { if { $debug } { puts "1st call of this server, just tell them the timer is off at the moment" } puts $channel "Sleep Timer: Off" } else { if { $debug } { puts "Connection from $clientaddr registered (lr=$last_request_time, n=$now)" } # if this press is 4+ seconds from last press, then just show the current timer if { [expr $now > $last_request_time + 4] } { if { $debug } { puts "last client calls was > 4 seconds ago, lets tell them the remaining time" } # if there is no end time, then we still haven't started our timer, so # just say its off if { ! [info exists end_time] } { if { $debug } { puts "timer still at 0" } puts $channel "Sleep Timer: Off" } else { if { $debug } { puts "just tell them we have some minutes left" } # we add 30 seconds here to allow for 1/2 minute rounding... # so if we have 9:59 seconds, left, its better to just turn it # into 10:29 / 10 and make it 10 puts $channel "[expr ($end_time - $now + 30)/60] minutes left" } } else { if { $debug } { puts "last client call was < 4 seconds ago, lets add some time" } # okay, it < 4 seconds ago, the client hit us, so add some time IncreaseSleepInterval $channel $now } } set last_request_time $now close $channel } proc IncreaseSleepInterval { channel now } { global debug INC max_sleep_time end_time # if there are any after's get rid of them, we will set the 2 new ones (the timer itself, and the dialog) foreach aid [after info] { after cancel $aid } # okay, there is no end_time yet, so first call, just set it to +INC minutes # and tell client if { ! [info exists end_time] } { set sleep_for [expr $INC*60] if { $debug } { puts "there is no end_time yet, so this is the 1st call... sleep_for=$sleep_for" } } else { # okay, this is the current gap / amount we are sleeping for set curr_gap [expr $end_time - $now] if { $debug } { puts "curr_gap=$curr_gap" } # add $INC, but round it to the nearest $INC # add 1/2 of 60 seconds, then div then mult by integer amount *60 seconds should do this set sleep_for [expr ($curr_gap +30 +$INC*60) / ($INC*60) * ($INC*60)] if { $debug } { puts "sleep for = $sleep_for" } if { $sleep_for >= $max_sleep_time} { if { $debug } { puts "okay, went past $max_sleep_time, turn sleep off" } puts $channel "Sleep: Off" unset end_time return } } set end_time [expr $now + $sleep_for] after [expr $sleep_for*1000] { set timer 1 } puts $channel "Sleep Timer: [expr $sleep_for/60] minutes" if { $debug } { puts "new timer: [expr $sleep_for/60]" } WhenToCallMythDialog } set halt 0 set sock [socket -server HandleNewRequest 41971] if { $debug } { puts "now lets wait on the timer" } while { ! $halt } { vwait timer if { $debug } { puts "kludge: timer fired, so just halt" } exec sudo /sbin/poweroff & }