Here is the file. It should go to freevo/src/helpers and run the same
way you run the recordserver (probably ./freevo nukkumaatti start).
Note that it also deals with Lirc, but not using pyLirc, since pyLirc
doesn't seem to support several clients at the same time (nextcode()
returns *always* an empty list when I use nukkumaatti at the same time
than freevo).

Once running, a SIGHUP will provoke an early shutdown sequence (earlier
than what was calculated), unless Freevo is recording something.

No guaranty on the code, the file, and so on. It might burn your house
and give you cancer, the usual stuff. Don't be mad at me if it doesn't
work as you think it should.

Matthieu
-- 
 (~._.~)        Matthieu Weber - Université de Jyväskylä         (~._.~)
  ( ? )                email : [EMAIL PROTECTED]                  ( ? ) 
 ()- -()               public key id : 452AE0AD                  ()- -()
 (_)-(_)  "Humor ist, wenn man trotzdem lacht (Germain Muller)"  (_)-(_)
import signal, time, socket, config, os.path
from twisted.persisted import marmalade

# Signal HUP:
#     When the user wants to shutdown the machine.
#     Calculates soonest shutdown time and sets the external timer to this time

class NukkuMaatti:

    def __init__(self):
        self.end = 0
        self.lircd_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.lircd_sock.connect('/dev/lircd')
        self.lircd_sock.setblocking(0)
        signal.signal(signal.SIGHUP, self.handle_sighup)
        self.user_input_occured = 0 # no automatic shutdown if '1'
        self.tv_video_state = 1
        self.set_tv_video(1)

        self.default_running_time = 900 # Run 15 min if we don't know when to shutdown
        self.shutdown_delay = 10 # wait 10 sec before shutdown
        self.wakeup_advance = 600 # wakeup 10 min before the time
        self.min_off_time = 3600 # shutdown for at least 1 hour
        self.max_off_time = 137436 # shutdown for at most 1 days, 14 hours (timer max)

    def handle_sighup(self, number, frame):
        self.set_times(1)
        self.user_input_occured = 0
        self.send('SET_TIMER %d' % (self.calc_delay(self.wakeup_time)))

    def calc_delay(self, wakeup_time):
        return int((wakeup_time - time.time())/2.097152)

    def set_times(self, sighup=0):
        t = []
        time_type = {}
        if os.path.isfile(config.TV_RECORD_SCHEDULE):
            pl = marmalade.unjellyFromXML(open(config.TV_RECORD_SCHEDULE, 
'r')).getProgramList().values()
            time_type = {}
            for p in pl:
                time_type[p.stop] = 'stop'
                time_type[p.start] = 'start'
            t = time_type.keys()    
            t.sort()
        
        i = 0
        set = 0
        earliest_wakeup = 0
        while i < len(t) - 1:
            if time_type[t[i]] == 'start' and earliest_wakeup == 0:
                earliest_wakeup = t[i] - config.TV_RECORD_PADDING - self.wakeup_advance
            if time_type[t[i]] == 'stop' and time_type[t[i+1]] == 'start' and \
               t[i+1] - t[i] - 2 * config.TV_RECORD_PADDING - self.shutdown_delay - 
self.wakeup_advance > self.min_off_time:
                self.shutdown_time = t[i] + config.TV_RECORD_PADDING + 
self.shutdown_delay
                self.wakeup_time = t[i+1] - config.TV_RECORD_PADDING - 
self.wakeup_advance
                set = 1
                break
            i += 1
        now = time.time()
        if not set: # No suitable times found (i.e. all schedules are overlaping or no 
schedule)
            if len(t) > 0: # At least one element
                # Shuntdown when the last scheduled program ends
                self.shutdown_time = t[len(t) - 1] + conf.TV_RECORD_PADDING + 
self.shutdown_delay
            else:
                # No clue on when to shutdown, use default running time
                self.shutdown_time = now + self.default_running_time
            # Wakeup time is then as far in the future as possible
            self.wakeup_time = self.shutdown_time + self.max_off_time
            
        # if no wakeup time is found from the schedule, or if the earliest is
        # far enough in the future (meaning that we can sleep in-between)
        if earliest_wakeup == 0 or earliest_wakeup - now > self.min_off_time:
            if sighup == 1:
                # the user wants to shutdown the machine
                self.shutdown_time = now + self.shutdown_delay
            else:
                # otherwise
                self.shutdown_time = now + self.default_running_time
            # if no wakeup time was found from the schedule
            if earliest_wakeup == 0:
                # we sleep as long as possible
                self.wakeup_time = self.shutdown_time + self.max_off_time
            else:
                self.wakeup_time = earliest_wakeup
        print "shutdown at %s" % time.strftime("%d.%m.%y %H:%M:%S", 
time.localtime(self.shutdown_time))
        print "wakeup   at %s" % time.strftime("%d.%m.%y %H:%M:%S", 
time.localtime(self.wakeup_time))

    def send(self, cmd):
        print "send " + cmd
        #self.sock.send(cmd)

    def set_tv_video(self, flag):
        #self.send('TV_VIDEO %s' % (self.tv_video_state))
        os.system('/usr/local/bin/tv_video %s' % (flag))        

    def toggle_tv_video(self):
        if self.tv_video_state == 1:
            self.tv_video_state = 0
        else:
            self.tv_video_state = 1
        self.set_tv_video(self.tv_video_state)
        
    def clear_for_shutdown(self):
        return not (os.path.isfile(config.FREEVO_CACHEDIR + '/record') or \
               os.path.isfile(config.FREEVO_CACHEDIR + '/get_xmltv'))

    def run(self):
        self.set_times()
        buf = ""
        while not self.end:
            try:
                r = self.lircd_sock.recv(64)
                buf += r
                self.user_input_occured = 1
                cont = 1
                while cont:
                    i = buf.find('\n')
                    line = ""
                    if i > -1:
                        line = buf[:i]
                        buf = buf[i+1:]
                    if len(line) > 0:
                        s = line.split(None,3)
                        if s[1] == '00':
                            code = s[2]
                            if code == 'A.F/P':
                                self.toggle_tv_video()
                    else:
                        cont = 0
            except:
                pass
            if not self.user_input_occured and time.time() > self.shutdown_time:
                if self.clear_for_shutdown():
                    self.end = 1
                else:
                    print "not clear for shutdown"
                    self.set_times()
                
            time.sleep(.1)

    def close(self):
        self.lircd_sock.close()
        self.set_tv_video(0)
        print "System shutdown"

if __name__ == '__main__':
    nm = NukkuMaatti()
    nm.run()
    nm.close()

Reply via email to