Stuff done
[uccvend-vendserver.git] / sql-edition / servers / VendServer.py
index 2adc4e1..c93fda0 100755 (executable)
@@ -8,7 +8,7 @@ import sys, os, string, re, pwd, signal, math
 import logging, logging.handlers
 from traceback import format_tb
 if USE_DB: import pg
 import logging, logging.handlers
 from traceback import format_tb
 if USE_DB: import pg
-from time import time, sleep
+from time import time, sleep, mktime, localtime
 from popen2 import popen2
 from LATClient import LATClient, LATClientException
 from SerialClient import SerialClient, SerialClientException
 from popen2 import popen2
 from LATClient import LATClient, LATClientException
 from SerialClient import SerialClient, SerialClientException
@@ -16,7 +16,7 @@ from VendingMachine import VendingMachine, VendingException
 from MessageKeeper import MessageKeeper
 from HorizScroll import HorizScroll
 from random import random, seed
 from MessageKeeper import MessageKeeper
 from HorizScroll import HorizScroll
 from random import random, seed
-from Idler import TrainIdler,GrayIdler,StringIdler,ClockIdler,FortuneIdler,FileIdler,PipeIdler
+from Idler import GreetingIdler,TrainIdler,GrayIdler,StringIdler,ClockIdler,FortuneIdler,FileIdler,PipeIdler
 import socket
 from posix import geteuid
 
 import socket
 from posix import geteuid
 
@@ -36,7 +36,6 @@ For a good time call +61 8 6488 3901
 
 """
 
 
 """
 
-GREETING = 'UCC SNACKS'
 PIN_LENGTH = 4
 
 DOOR = 1
 PIN_LENGTH = 4
 
 DOOR = 1
@@ -51,6 +50,10 @@ STATE_DOOR_CLOSING = 3
 STATE_GETTING_UID = 4
 STATE_GETTING_PIN = 5
 STATE_GET_SELECTION = 6
 STATE_GETTING_UID = 4
 STATE_GETTING_PIN = 5
 STATE_GET_SELECTION = 6
+STATE_GRANDFATHER_CLOCK = 7
+
+TEXT_SPEED = 0.8
+IDLE_SPEED = 0.05
 
 class DispenseDatabaseException(Exception): pass
 
 
 class DispenseDatabaseException(Exception): pass
 
@@ -85,8 +88,8 @@ class DispenseDatabase:
 
 def scroll_options(username, mk, welcome = False):
        if welcome:
 
 def scroll_options(username, mk, welcome = False):
        if welcome:
-               msg = [(center('WELCOME'), False, 0.8),
-                          (center(username), False, 0.8)]
+               msg = [(center('WELCOME'), False, TEXT_SPEED),
+                          (center(username), False, TEXT_SPEED)]
        else:
                msg = []
        choices = ' '*10+'CHOICES: '
        else:
                msg = []
        choices = ' '*10+'CHOICES: '
@@ -123,8 +126,8 @@ def get_pin(uid):
                logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
                return None
        if s.st_mode & 077:
                logging.info('getting pin for uid %d: .pin not found in home directory'%uid)
                return None
        if s.st_mode & 077:
-               logging.info('getting pin for uid %d: .pin has wrong permissions'%uid)
-               return None
+               logging.info('getting pin for uid %d: .pin has wrong permissions. Fixing.'%uid)
+               os.chmod(pinfile, 0600)
        try:
                f = file(pinfile)
        except IOError:
        try:
                f = file(pinfile)
        except IOError:
@@ -193,7 +196,7 @@ def setup_idlers(v):
                 GrayIdler(v,one="/",zero="\\"),
                ClockIdler(v),
                 GrayIdler(v,one="X",zero="O"),
                 GrayIdler(v,one="/",zero="\\"),
                ClockIdler(v),
                 GrayIdler(v,one="X",zero="O"),
-               FileIdler(v, '/usr/share/common-licenses/GPL-2'),
+               FileIdler(v, '/usr/share/common-licenses/GPL-2',affinity=2),
                 GrayIdler(v,one="*",zero="-",reorder=1),
                StringIdler(v, text=str(math.pi) + "            "),
                ClockIdler(v),
                 GrayIdler(v,one="*",zero="-",reorder=1),
                StringIdler(v, text=str(math.pi) + "            "),
                ClockIdler(v),
@@ -201,7 +204,7 @@ def setup_idlers(v):
                StringIdler(v, text=str(math.e) + "            "),
                 GrayIdler(v,one="X",zero="O",reorder=1),
                StringIdler(v, text="    I want some pizza - please call Pizza Hut Shenton Park on +61 8 9381 9979 - and order as Quinn - I am getting really hungry", repeat=False),
                StringIdler(v, text=str(math.e) + "            "),
                 GrayIdler(v,one="X",zero="O",reorder=1),
                StringIdler(v, text="    I want some pizza - please call Pizza Hut Shenton Park on +61 8 9381 9979 - and order as Quinn - I am getting really hungry", repeat=False),
-               PipeIdler(v, "/usr/bin/ypcat", "passwd"),
+               PipeIdler(v, "/usr/bin/getent", "passwd"),
                FortuneIdler(v),
                ClockIdler(v),
                StringIdler(v),
                FortuneIdler(v),
                ClockIdler(v),
                StringIdler(v),
@@ -209,30 +212,43 @@ def setup_idlers(v):
                ]
        disabled = [
                ]
                ]
        disabled = [
                ]
-       idler = choose_idler()
+
+def reset_idler(v, vstatus, t = None):
+       global idlers, idler
+       idler = GreetingIdler(v, t)
+       vstatus.time_of_next_idlestep = time()+idler.next()
+       vstatus.time_of_next_idler = None
+       vstatus.change_state(STATE_IDLE, 1)
 
 def choose_idler():
        global idlers, idler
        iiindex = 0
 
 def choose_idler():
        global idlers, idler
        iiindex = 0
+       average_affinity = 10 # guessing here...
 
 
-       if idler:
+       if idler and idler.__class__ != GreetingIdler:
                iiindex = idlers.index(idler)
 
        iilen = len(idlers)
 
                iiindex = idlers.index(idler)
 
        iilen = len(idlers)
 
-       move = int(random()*len(idlers)) + 1
+       move = int(random()*len(idlers)*average_affinity) + 1
 
        while move >= 0:
 
        while move >= 0:
-               idler = idlers[( (iiindex + 1) % iilen)]
-               move = move - idler.affinity()
+               iiindex += 1
+               iiindex %= iilen
+               idler = idlers[iiindex]
+               move -= idler.affinity()
 
        idler.reset()
 
 
        idler.reset()
 
-def idle_step():
+def idle_step(vstatus):
        global idler
        if idler.finished():
                choose_idler()
        global idler
        if idler.finished():
                choose_idler()
-       idler.next()
+               vstatus.time_of_next_idler = time() + 30
+       nextidle = idler.next()
+       if nextidle is None:
+               nextidle = IDLE_SPEED
+       vstatus.time_of_next_idlestep = time()+nextidle
 
 class VendState:
        def __init__(self,v):
 
 class VendState:
        def __init__(self,v):
@@ -247,10 +263,23 @@ class VendState:
                self.cur_selection = ''
                self.time_to_autologout = None
 
                self.cur_selection = ''
                self.time_to_autologout = None
 
-               self.time_to_idle = None
-
                self.last_timeout_refresh = None
 
                self.last_timeout_refresh = None
 
+       def change_state(self,newstate,newcounter=None):
+               if self.state != newstate:
+                       #print "Changing state from: ", 
+                       #print self.state,
+                       #print " to ", 
+                       #print newstate 
+                       self.state = newstate
+
+               if newcounter is not None and self.counter != newcounter:
+                       #print "Changing counter from: ", 
+                       #print self.counter,
+                       #print " to ", 
+                       #print newcounter 
+                       self.counter = newcounter
+
 
 
 def handle_tick_event(event, params, v, vstatus):
 
 
 def handle_tick_event(event, params, v, vstatus):
@@ -291,10 +320,7 @@ def handle_get_selection_idle(state, event, params, v, vstatus):
                vstatus.cur_pin = ''
                vstatus.cur_selection = ''
                        
                vstatus.cur_pin = ''
                vstatus.cur_selection = ''
                        
-               idle_in(vstatus,2)
-               vstatus.state = STATE_IDLE
-
-               vstatus.mk.set_message(GREETING)
+               reset_idler(v, vstatus)
 
        ### State fully logged out ... reset variables
        if vstatus.time_to_autologout and not vstatus.mk.done(): 
 
        ### State fully logged out ... reset variables
        if vstatus.time_to_autologout and not vstatus.mk.done(): 
@@ -308,12 +334,6 @@ def handle_get_selection_idle(state, event, params, v, vstatus):
                vstatus.time_to_autologout = time() + 15
                vstatus.last_timeout_refresh = None
 
                vstatus.time_to_autologout = time() + 15
                vstatus.last_timeout_refresh = None
 
-       ### State logged out ... after normal logout??
-       # perhaps when logged in?
-       if vstatus.time_to_idle is not None and vstatus.cur_user != '': 
-               vstatus.time_to_idle = None
-
-
        ## FIXME - this may need to be elsewhere.....
        # need to check
        vstatus.mk.update_display()
        ## FIXME - this may need to be elsewhere.....
        # need to check
        vstatus.mk.update_display()
@@ -328,12 +348,8 @@ def handle_get_selection_key(state, event, params, v, vstatus):
                        vstatus.cur_user = ''
                        vstatus.cur_selection = ''
                        
                        vstatus.cur_user = ''
                        vstatus.cur_selection = ''
                        
-                       idle_in(vstatus,2)
-                       vstatus.state = STATE_IDLE
-
-                       vstatus.mk.set_messages(
-                               [(center('BYE!'), False, 1.5),
-                                (GREETING, False, None)])
+                       vstatus.mk.set_messages([(center('BYE!'), False, 1.5)])
+                       reset_idler(v, vstatus, 2)
                        return
                vstatus.cur_selection += chr(key + ord('0'))
                vstatus.mk.set_message('SELECT: '+vstatus.cur_selection)
                        return
                vstatus.cur_selection += chr(key + ord('0'))
                vstatus.mk.set_message('SELECT: '+vstatus.cur_selection)
@@ -396,10 +412,7 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
                if key == 11:
                        if vstatus.cur_pin == '':
                                vstatus.cur_user = ''
                if key == 11:
                        if vstatus.cur_pin == '':
                                vstatus.cur_user = ''
-                               vstatus.mk.set_message(GREETING)
-                       
-                               idle_in(vstatus,5)
-                               vstatus.state = STATE_IDLE
+                               reset_idler(v, vstatus)
 
                                return
                        vstatus.cur_pin = ''
 
                                return
                        vstatus.cur_pin = ''
@@ -412,20 +425,18 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
                        if vstatus.username:
                                v.beep(0, False)
                                vstatus.cur_selection = ''
                        if vstatus.username:
                                v.beep(0, False)
                                vstatus.cur_selection = ''
-                               vstatus.state = STATE_GET_SELECTION
+                               vstatus.change_state(STATE_GET_SELECTION)
                                scroll_options(vstatus.username, vstatus.mk, True)
                                return
                        else:
                                v.beep(40, False)
                                vstatus.mk.set_messages(
                                        [(center('BAD PIN'), False, 1.0),
                                scroll_options(vstatus.username, vstatus.mk, True)
                                return
                        else:
                                v.beep(40, False)
                                vstatus.mk.set_messages(
                                        [(center('BAD PIN'), False, 1.0),
-                                        (center('SORRY'), False, 0.5),
-                                        (GREETING, False, None)])
+                                        (center('SORRY'), False, 0.5)])
                                vstatus.cur_user = ''
                                vstatus.cur_pin = ''
                        
                                vstatus.cur_user = ''
                                vstatus.cur_pin = ''
                        
-                               idle_in(vstatus,5)
-                               vstatus.state = STATE_IDLE
+                               reset_idler(v, vstatus, 2)
 
                                return
 
 
                                return
 
@@ -437,10 +448,8 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
        if len(vstatus.cur_user) < 5:
                if key == 11:
                        vstatus.cur_user = ''
        if len(vstatus.cur_user) < 5:
                if key == 11:
                        vstatus.cur_user = ''
-                       vstatus.mk.set_message(GREETING)
 
 
-                       idle_in(vstatus,5)
-                       vstatus.state = STATE_IDLE
+                       reset_idler(v, vstatus)
                        return
 
                vstatus.cur_user += chr(key + ord('0'))
                        return
 
                vstatus.cur_user += chr(key + ord('0'))
@@ -448,16 +457,54 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
 
        if len(vstatus.cur_user) == 5:
                uid = int(vstatus.cur_user)
 
        if len(vstatus.cur_user) == 5:
                uid = int(vstatus.cur_user)
+               if uid == 0:
+                       logging.info('user '+vstatus.cur_user+' has a bad PIN')
+                       pfalken="""
+CARRIER DETECTED
+
+CONNECT 128000
+
+Welcome to Picklevision Sytems, Sunnyvale, CA
+
+Greetings Professor Falken.
+
+
+
+
+Shall we play a game?
+
+
+Please choose from the following menu:
+
+1. Tic-Tac-Toe
+2. Chess
+3. Checkers
+4. Backgammon
+5. Poker
+6. Toxic and Biochemical Warfare
+7. Global Thermonuclear War
+
+7 [ENTER]
+
+Wouldn't you prefer a nice game of chess?
+
+""".replace('\n','    ')
+                       vstatus.mk.set_messages([(pfalken, False, 10)])
+                       vstatus.cur_user = ''
+                       vstatus.cur_pin = ''
+                       
+                       reset_idler(v, vstatus, 10)
+
+                       return
+
                if not has_good_pin(uid):
                        logging.info('user '+vstatus.cur_user+' has a bad PIN')
                        vstatus.mk.set_messages(
                if not has_good_pin(uid):
                        logging.info('user '+vstatus.cur_user+' has a bad PIN')
                        vstatus.mk.set_messages(
-                               [(' '*10+'INVALID PIN SETUP'+' '*10, False, 3),
-                                (GREETING, False, None)])
+                               [(' '*10+'INVALID PIN SETUP'+' '*11, False, 3)])
                        vstatus.cur_user = ''
                        vstatus.cur_pin = ''
                        
                        vstatus.cur_user = ''
                        vstatus.cur_pin = ''
                        
-                       idle_in(vstatus,5)
-                       vstatus.state = STATE_IDLE
+                       reset_idler(v, vstatus, 3)
 
                        return
 
 
                        return
 
@@ -465,7 +512,7 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
                vstatus.cur_pin = ''
                vstatus.mk.set_message('PIN: ')
                logging.info('need pin for user %s'%vstatus.cur_user)
                vstatus.cur_pin = ''
                vstatus.mk.set_message('PIN: ')
                logging.info('need pin for user %s'%vstatus.cur_user)
-               vstatus.state = STATE_GETTING_PIN
+               vstatus.change_state(STATE_GETTING_PIN)
                return
 
 
                return
 
 
@@ -476,68 +523,155 @@ def handle_idle_key(state, event, params, v, vstatus):
 
        if key == 11:
                vstatus.cur_user = ''
 
        if key == 11:
                vstatus.cur_user = ''
-               vstatus.mk.set_message(GREETING)
-               idle_in(vstatus,5)
-               choose_idler()
+               reset_idler(v, vstatus)
                return
        
                return
        
-       vstatus.state = STATE_GETTING_UID
+       vstatus.change_state(STATE_GETTING_UID)
        run_handler(event, key, v, vstatus)
 
 
 def handle_idle_tick(state, event, params, v, vstatus):
        run_handler(event, key, v, vstatus)
 
 
 def handle_idle_tick(state, event, params, v, vstatus):
-       ### State logged out ... initiate idler in 5  (first start?)
-       if vstatus.time_to_idle == None and vstatus.cur_user == '':
-               vstatus.time_to_idle = time() + 5
-               choose_idler()
-
        ### State idling
        ### State idling
+       if vstatus.mk.done():
+               idle_step(vstatus)
 
 
-       if vstatus.time_to_idle is not None and time() > vstatus.time_to_idle: 
-               idle_step()
-
-       if vstatus.time_to_idle is not None and time() > vstatus.time_to_idle + 30:
-               vstatus.time_to_idle = time()
+       if vstatus.time_of_next_idler and time() > vstatus.time_of_next_idler:
+               vstatus.time_of_next_idler = time() + 30
                choose_idler()
        
        ###
 
        vstatus.mk.update_display()
 
                choose_idler()
        
        ###
 
        vstatus.mk.update_display()
 
+       vstatus.change_state(STATE_GRANDFATHER_CLOCK)
+       run_handler(event, params, v, vstatus)
+       sleep(0.05)
+
+def beep_on(when, before=0):
+       start = int(when - before)
+       end = int(when)
+       now = int(time())
+
+       if now >= start and now <= end:
+               return 1
+       return 0
+
+def handle_idle_grandfather_tick(state, event, params, v, vstatus):
+       ### check for interesting times
+       now = localtime()
+
+       quarterhour = mktime([now[0],now[1],now[2],now[3],15,0,now[6],now[7],now[8]])
+       halfhour = mktime([now[0],now[1],now[2],now[3],30,0,now[6],now[7],now[8]])
+       threequarterhour = mktime([now[0],now[1],now[2],now[3],45,0,now[6],now[7],now[8]])
+       fivetothehour = mktime([now[0],now[1],now[2],now[3],55,0,now[6],now[7],now[8]])
+
+       hourfromnow = localtime(time() + 3600)
+       
+       #onthehour = mktime([now[0],now[1],now[2],now[3],03,0,now[6],now[7],now[8]])
+       onthehour = mktime([hourfromnow[0],hourfromnow[1],hourfromnow[2],hourfromnow[3], \
+               0,0,hourfromnow[6],hourfromnow[7],hourfromnow[8]])
+
+       ## check for X seconds to the hour
+       ## if case, update counter to 2
+       if beep_on(onthehour,15) \
+               or beep_on(halfhour,0) \
+               or beep_on(quarterhour,0) \
+               or beep_on(threequarterhour,0) \
+               or beep_on(fivetothehour,0):
+               vstatus.change_state(STATE_GRANDFATHER_CLOCK,2)
+               run_handler(event, params, v, vstatus)
+       else:
+               vstatus.change_state(STATE_IDLE)
+
+def handle_grandfather_tick(state, event, params, v, vstatus):
+       go_idle = 1
+
+       msg = []
+       ### we live in interesting times
+       now = localtime()
+
+       quarterhour = mktime([now[0],now[1],now[2],now[3],15,0,now[6],now[7],now[8]])
+       halfhour = mktime([now[0],now[1],now[2],now[3],30,0,now[6],now[7],now[8]])
+       threequarterhour = mktime([now[0],now[1],now[2],now[3],45,0,now[6],now[7],now[8]])
+       fivetothehour = mktime([now[0],now[1],now[2],now[3],55,0,now[6],now[7],now[8]])
+
+       hourfromnow = localtime(time() + 3600)
+       
+#      onthehour = mktime([now[0],now[1],now[2],now[3],03,0,now[6],now[7],now[8]])
+       onthehour = mktime([hourfromnow[0],hourfromnow[1],hourfromnow[2],hourfromnow[3], \
+               0,0,hourfromnow[6],hourfromnow[7],hourfromnow[8]])
+
+
+       #print "when it fashionable to wear a onion on your hip"
+
+       if beep_on(onthehour,15):
+               go_idle = 0
+               next_hour=((hourfromnow[3] + 11) % 12) + 1
+               if onthehour - time() < next_hour and onthehour - time() > 0:
+                       v.beep(0, False)
+
+                       t = int(time())
+                       if (t % 2) == 0:
+                               msg.append(("DING!", False, None))
+                       else:
+                               msg.append(("     DING!", False, None))
+               elif int(onthehour - time()) == 0:
+                       v.beep(255, False)
+                       msg.append(("   BONG!", False, None))
+                       msg.append(("     IT'S "+ str(next_hour) + "O'CLOCK AND ALL IS WELL .....", False, TEXT_SPEED*4))
+       elif beep_on(halfhour,0):
+               go_idle = 0
+               v.beep(0, False)
+               msg.append((" HALFHOUR ", False, 50))
+       elif beep_on(quarterhour,0):
+               go_idle = 0
+               v.beep(0, False)
+               msg.append((" QTR HOUR ", False, 50))
+       elif beep_on(threequarterhour,0):
+               go_idle = 0
+               v.beep(0, False)
+               msg.append((" 3 QTR HR ", False, 50))
+       elif beep_on(fivetothehour,0):
+               go_idle = 0
+               v.beep(0, False)
+               msg.append(("Quick run to your lectures!  Hurry! Hurry!", False, TEXT_SPEED*4))
+       else:
+               go_idle = 1
+       
+       ## check for X seconds to the hour
+
+       if len(msg):
+               vstatus.mk.set_messages(msg)
+               sleep(1)
+
+       vstatus.mk.update_display()
+       ## if no longer case, return to idle
+
+       ## change idler to be clock
+       if go_idle and vstatus.mk.done():
+               vstatus.change_state(STATE_IDLE,1)
 
 def handle_door_idle(state, event, params, v, vstatus):
        # don't care right now.
        pass
 
 def handle_door_event(state, event, params, v, vstatus):
 
 def handle_door_idle(state, event, params, v, vstatus):
        # don't care right now.
        pass
 
 def handle_door_event(state, event, params, v, vstatus):
-       vstatus.time_to_idle = None
-
        if params == 1:  #door open
        if params == 1:  #door open
-               vstatus.state = STATE_DOOR_OPENING
+               vstatus.change_state(STATE_DOOR_OPENING)
                logging.warning("Entering open door mode")
                v.display("-FEED  ME-")
                #door_open_mode(v);
                vstatus.cur_user = ''
                vstatus.cur_pin = ''
        elif params == 0:  #door closed
                logging.warning("Entering open door mode")
                v.display("-FEED  ME-")
                #door_open_mode(v);
                vstatus.cur_user = ''
                vstatus.cur_pin = ''
        elif params == 0:  #door closed
-               vstatus.state = STATE_DOOR_CLOSING
-               idle_in(vstatus, 5)
+               vstatus.change_state(STATE_DOOR_CLOSING)
+               reset_idler(v, vstatus, 3)
 
                logging.warning('Leaving open door mode')
                v.display("-YUM YUM!-")
 
 
                logging.warning('Leaving open door mode')
                v.display("-YUM YUM!-")
 
-def idle_in(vstatus,seconds):
-       vstatus.time_to_idle = time() + seconds
-
 def return_to_idle(state,event,params,v,vstatus):
 def return_to_idle(state,event,params,v,vstatus):
-       if vstatus.time_to_idle is not None and time() > vstatus.time_to_idle: 
-               vstatus.mk.set_message(GREETING)
-               vstatus.state = STATE_IDLE
-               return
-       if not vstatus.time_to_idle:
-               vstatus.mk.set_message(GREETING)
-               vstatus.state = STATE_IDLE
-               return
+       reset_idler(v, vstatus)
 
 def create_state_table(vstatus):
        vstatus.state_table[(STATE_IDLE,TICK,1)] = handle_idle_tick
 
 def create_state_table(vstatus):
        vstatus.state_table[(STATE_IDLE,TICK,1)] = handle_idle_tick
@@ -564,9 +698,24 @@ def create_state_table(vstatus):
        vstatus.state_table[(STATE_GET_SELECTION,DOOR,1)] = do_nothing
        vstatus.state_table[(STATE_GET_SELECTION,KEY,1)] = handle_get_selection_key
 
        vstatus.state_table[(STATE_GET_SELECTION,DOOR,1)] = do_nothing
        vstatus.state_table[(STATE_GET_SELECTION,KEY,1)] = handle_get_selection_key
 
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,1)] = handle_idle_grandfather_tick
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,2)] = handle_grandfather_tick
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,DOOR,1)] = do_nothing
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,DOOR,2)] = do_nothing
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,KEY,1)] = do_nothing
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,KEY,2)] = do_nothing
+
 def get_state_table_handler(vstatus, state, event, counter):
        return vstatus.state_table[(state,event,counter)]
 
 def get_state_table_handler(vstatus, state, event, counter):
        return vstatus.state_table[(state,event,counter)]
 
+def time_to_next_update(vstatus):
+       idle_update = vstatus.time_of_next_idlestep - time()
+       if not vstatus.mk.done() and vstatus.mk.next_update is not None:
+               mk_update = vstatus.mk.next_update - time()
+               if mk_update < idle_update:
+                       idle_update = mk_update
+       return idle_update
+
 def run_forever(rfh, wfh, options, cf):
        v = VendingMachine(rfh, wfh)
        vstatus = VendState(v)
 def run_forever(rfh, wfh, options, cf):
        v = VendingMachine(rfh, wfh)
        vstatus = VendState(v)
@@ -576,11 +725,8 @@ def run_forever(rfh, wfh, options, cf):
 
        if USE_DB: db = DispenseDatabase(v, cf.DBServer, cf.DBName, cf.DBUser, cf.DBPassword)
 
 
        if USE_DB: db = DispenseDatabase(v, cf.DBServer, cf.DBName, cf.DBUser, cf.DBPassword)
 
-       vstatus.mk.set_message(GREETING)
        setup_idlers(v)
        setup_idlers(v)
-       choose_idler()
-       vstatus.mk.set_message("Booted")
-
+       reset_idler(v, vstatus)
 
        # This main loop was hideous and the work of the devil.
        # This has now been fixed (mostly) - mtearle
 
        # This main loop was hideous and the work of the devil.
        # This has now been fixed (mostly) - mtearle
@@ -601,10 +747,10 @@ def run_forever(rfh, wfh, options, cf):
                                logging.error('Database error: '+str(e))
 
 
                                logging.error('Database error: '+str(e))
 
 
-               e = v.next_event(0)
+               timeout = time_to_next_update(vstatus)
+               e = v.next_event(timeout)
                (event, params) = e
 
                (event, params) = e
 
-               vstatus.counter=1
                run_handler(event, params, v, vstatus)
 
 #              logging.debug('Got event: ' + repr(e))
                run_handler(event, params, v, vstatus)
 
 #              logging.debug('Got event: ' + repr(e))

UCC git Repository :: git.ucc.asn.au