chmod pin automatically. remove boot up message now it doesnt take so long to boot.
[zanchey/dispense2.git] / sql-edition / servers / VendServer.py
index 2adc4e1..22958bd 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
-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
@@ -51,6 +51,10 @@ STATE_DOOR_CLOSING = 3
 STATE_GETTING_UID = 4
 STATE_GETTING_PIN = 5
 STATE_GET_SELECTION = 6
+STATE_GRANDFATHER_CLOCK = 7
+
+TEXT_SPEED = 0.8
+IDLE_SPEED = 0.02
 
 class DispenseDatabaseException(Exception): pass
 
@@ -85,8 +89,8 @@ class DispenseDatabase:
 
 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: '
@@ -123,8 +127,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 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:
@@ -232,6 +236,7 @@ def idle_step():
        global idler
        if idler.finished():
                choose_idler()
+       sleep(IDLE_SPEED)
        idler.next()
 
 class VendState:
@@ -251,6 +256,21 @@ class VendState:
 
                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):
@@ -292,7 +312,7 @@ def handle_get_selection_idle(state, event, params, v, vstatus):
                vstatus.cur_selection = ''
                        
                idle_in(vstatus,2)
-               vstatus.state = STATE_IDLE
+               vstatus.change_state(STATE_IDLE)
 
                vstatus.mk.set_message(GREETING)
 
@@ -329,7 +349,7 @@ def handle_get_selection_key(state, event, params, v, vstatus):
                        vstatus.cur_selection = ''
                        
                        idle_in(vstatus,2)
-                       vstatus.state = STATE_IDLE
+                       vstatus.change_state(STATE_IDLE)
 
                        vstatus.mk.set_messages(
                                [(center('BYE!'), False, 1.5),
@@ -399,7 +419,7 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
                                vstatus.mk.set_message(GREETING)
                        
                                idle_in(vstatus,5)
-                               vstatus.state = STATE_IDLE
+                               vstatus.change_state(STATE_IDLE)
 
                                return
                        vstatus.cur_pin = ''
@@ -412,7 +432,7 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
                        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:
@@ -425,7 +445,7 @@ def handle_getting_pin_key(state, event, params, v, vstatus):
                                vstatus.cur_pin = ''
                        
                                idle_in(vstatus,5)
-                               vstatus.state = STATE_IDLE
+                               vstatus.change_state(STATE_IDLE)
 
                                return
 
@@ -440,7 +460,7 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
                        vstatus.mk.set_message(GREETING)
 
                        idle_in(vstatus,5)
-                       vstatus.state = STATE_IDLE
+                       vstatus.change_state(STATE_IDLE)
                        return
 
                vstatus.cur_user += chr(key + ord('0'))
@@ -457,7 +477,7 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
                        vstatus.cur_pin = ''
                        
                        idle_in(vstatus,5)
-                       vstatus.state = STATE_IDLE
+                       vstatus.change_state(STATE_IDLE)
 
                        return
 
@@ -465,7 +485,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.state = STATE_GETTING_PIN
+               vstatus.change_state(STATE_GETTING_PIN)
                return
 
 
@@ -481,7 +501,7 @@ def handle_idle_key(state, event, params, v, vstatus):
                choose_idler()
                return
        
-       vstatus.state = STATE_GETTING_UID
+       vstatus.change_state(STATE_GETTING_UID)
        run_handler(event, key, v, vstatus)
 
 
@@ -504,6 +524,113 @@ def handle_idle_tick(state, event, params, v, vstatus):
 
        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.
@@ -513,14 +640,14 @@ def handle_door_event(state, event, params, v, vstatus):
        vstatus.time_to_idle = None
 
        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
-               vstatus.state = STATE_DOOR_CLOSING
+               vstatus.change_state(STATE_DOOR_CLOSING)
                idle_in(vstatus, 5)
 
                logging.warning('Leaving open door mode')
@@ -532,11 +659,11 @@ def idle_in(vstatus,seconds):
 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
+               vstatus.change_state(STATE_IDLE)
                return
        if not vstatus.time_to_idle:
                vstatus.mk.set_message(GREETING)
-               vstatus.state = STATE_IDLE
+               vstatus.change_state(STATE_IDLE)
                return
 
 def create_state_table(vstatus):
@@ -564,6 +691,13 @@ 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_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)]
 
@@ -576,11 +710,9 @@ def run_forever(rfh, wfh, options, cf):
 
        if USE_DB: db = DispenseDatabase(v, cf.DBServer, cf.DBName, cf.DBUser, cf.DBPassword)
 
-       vstatus.mk.set_message(GREETING)
        setup_idlers(v)
        choose_idler()
-       vstatus.mk.set_message("Booted")
-
+       vstatus.mk.set_message(GREETING)
 
        # This main loop was hideous and the work of the devil.
        # This has now been fixed (mostly) - mtearle
@@ -593,6 +725,8 @@ def run_forever(rfh, wfh, options, cf):
        #
        # ( return state - not currently implemented )
 
+       vstatus.change_state(STATE_IDLE,1)
+
        while True:
                if USE_DB:
                        try:
@@ -604,7 +738,6 @@ def run_forever(rfh, wfh, options, cf):
                e = v.next_event(0)
                (event, params) = e
 
-               vstatus.counter=1
                run_handler(event, params, v, vstatus)
 
 #              logging.debug('Got event: ' + repr(e))

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