Work from tonight:
authorBernard Blackham <dagobah@ucc.asn.au>
Fri, 29 Feb 2008 13:25:50 +0000 (13:25 +0000)
committerBernard Blackham <dagobah@ucc.asn.au>
Fri, 29 Feb 2008 13:25:50 +0000 (13:25 +0000)
MIFARE integration.
Old DAA patches for balance showing.
Eat easter eggs.

sql-edition/servers/VendServer.py
sql-edition/servers/VendingMachine.py

index eff58e0..fa5ba5b 100755 (executable)
@@ -43,6 +43,7 @@ DOOR = 1
 SWITCH = 2
 KEY = 3
 TICK = 4
+MIFARE = 5
 
 
 (
@@ -55,7 +56,7 @@ STATE_GET_SELECTION,
 STATE_GRANDFATHER_CLOCK,
 ) = range(1,8)
 
-TEXT_SPEED = 0.8
+TEXT_SPEED = 0.6
 IDLE_SPEED = 0.05
 
 class DispenseDatabaseException(Exception): pass
@@ -91,8 +92,14 @@ class DispenseDatabase:
 
 def scroll_options(username, mk, welcome = False):
        if welcome:
+           # Balance checking: crap code, [DAA]'s fault
+           acct = os.popen('dispense acct %s' % username)
+               balance = acct.read()[15:22]
+               acct.close()
+        
                msg = [(center('WELCOME'), False, TEXT_SPEED),
-                          (center(username), False, TEXT_SPEED)]
+                          (center(username), False, TEXT_SPEED),
+                          (center(balance), False, TEXT_SPEED),]
        else:
                msg = []
        choices = ' '*10+'CHOICES: '
@@ -157,8 +164,8 @@ def get_pin(uid):
 def has_good_pin(uid):
        return get_pin(uid) != None
 
-def verify_user_pin(uid, pin):
-       if get_pin(uid) == pin:
+def verify_user_pin(uid, pin, skip_pin_check=False):
+       if skip_pin_check or get_pin(uid) == pin:
                info = pwd.getpwuid(uid)
                logging.info('accepted pin for uid %d (%s)'%(uid,info.pw_name))
                return info.pw_name
@@ -514,45 +521,9 @@ def handle_getting_uid_key(state, event, params, v, vstatus):
                else:
                        vstatus.mk.set_message('UID: '+vstatus.cur_user)
        
-
-       # Easter egg for nikita's birthday -- DGB
-       if len(vstatus.cur_user) == 8:
-               if vstatus.cur_user != "07051980":
-                       vstatus.mk.set_messages(
-                               [(' '*9+'ONE MORE TRY NiKiTa'+' '*10, False, 3)])
-                       vstatus.cur_user = ''
-                       reset_idler(v, vstatus, 3)
-                       return
-
-               # Do stuff here
-               vstatus.mk.set_messages(
-               [(center('                  GUILD MAILBOX NUMBER 64                  '), False, 20),
-               (center('                  GUILD MAILBOX NUMBER 64                  '), False, 20),
-               (center('                  GUILD MAILBOX NUMBER 64                  '), False, 20),
-               (center('                  GUILD MAILBOX NUMBER 64                  '), False, 20)])
-
-               # Reset
-               vstatus.cur_user = ''
-               vstatus.cur_pin = ''
-               #reset_idler(v, vstatus, 10)
-               reset_idler(v, vstatus, 2)
-               return
-       # End easter egg part 1
        if len(vstatus.cur_user) == 5:
                uid = int(vstatus.cur_user)
 
-               # Easter egg for nikita's birthday -- DGB
-               if vstatus.cur_user == '07051':
-                       if key == 11:
-                               vstatus.cur_user = ''
-                               reset_idler(v, vstatus)
-                               return
-#                      vstatus.cur_user += chr(key + ord('0'))
-                       logging.info(' == 5 dob: '+vstatus.cur_user)
-                       vstatus.mk.set_message('>'+vstatus.cur_user)
-                       return
-               # end easter egg part 2
-
                if uid == 0:
                        logging.info('user '+vstatus.cur_user+' has a bad PIN')
                        pfalken="""
@@ -782,6 +753,28 @@ def handle_door_event(state, event, params, v, vstatus):
                logging.warning('Leaving open door mode')
                v.display("-YUM YUM!-")
 
+def handle_mifare_event(state, event, params, v, vstatus):
+       card_uid = params
+       # Translate card_id into uid.
+       vstatus.cur_user = str(card_uid)
+       vstatus.username = verify_user_pin(int(card_uid), None, True)
+       if vstatus.username:
+               v.beep(0, False)
+               vstatus.cur_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 CARD'), False, 1.0),
+                        (center('SORRY'), False, 0.5)])
+               vstatus.cur_user = ''
+               vstatus.cur_pin = ''
+       
+               reset_idler(v, vstatus, 2)
+               return
+
 def return_to_idle(state,event,params,v,vstatus):
        reset_idler(v, vstatus)
 
@@ -789,26 +782,32 @@ def create_state_table(vstatus):
        vstatus.state_table[(STATE_IDLE,TICK,1)] = handle_idle_tick
        vstatus.state_table[(STATE_IDLE,KEY,1)] = handle_idle_key
        vstatus.state_table[(STATE_IDLE,DOOR,1)] = handle_door_event
+       vstatus.state_table[(STATE_IDLE,MIFARE,1)] = handle_mifare_event
 
        vstatus.state_table[(STATE_DOOR_OPENING,TICK,1)] = handle_door_idle
        vstatus.state_table[(STATE_DOOR_OPENING,DOOR,1)] = handle_door_event
        vstatus.state_table[(STATE_DOOR_OPENING,KEY,1)] = do_nothing
+       vstatus.state_table[(STATE_DOOR_OPENING,MIFARE,1)] = do_nothing
 
        vstatus.state_table[(STATE_DOOR_CLOSING,TICK,1)] = return_to_idle
        vstatus.state_table[(STATE_DOOR_CLOSING,DOOR,1)] = handle_door_event
        vstatus.state_table[(STATE_DOOR_CLOSING,KEY,1)] = do_nothing
+       vstatus.state_table[(STATE_DOOR_CLOSING,MIFARE,1)] = do_nothing
 
        vstatus.state_table[(STATE_GETTING_UID,TICK,1)] = handle_getting_uid_idle
        vstatus.state_table[(STATE_GETTING_UID,DOOR,1)] = do_nothing
        vstatus.state_table[(STATE_GETTING_UID,KEY,1)] = handle_getting_uid_key
+       vstatus.state_table[(STATE_GETTING_UID,MIFARE,1)] = handle_mifare_event
 
        vstatus.state_table[(STATE_GETTING_PIN,TICK,1)] = handle_getting_pin_idle
        vstatus.state_table[(STATE_GETTING_PIN,DOOR,1)] = do_nothing
        vstatus.state_table[(STATE_GETTING_PIN,KEY,1)] = handle_getting_pin_key
+       vstatus.state_table[(STATE_GETTING_PIN,MIFARE,1)] = handle_mifare_event
 
        vstatus.state_table[(STATE_GET_SELECTION,TICK,1)] = handle_get_selection_idle
        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,MIFARE,1)] = do_nothing
 
        vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,1)] = handle_idle_grandfather_tick
        vstatus.state_table[(STATE_GRANDFATHER_CLOCK,TICK,2)] = handle_grandfather_tick
@@ -816,6 +815,7 @@ def create_state_table(vstatus):
        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
+       vstatus.state_table[(STATE_GRANDFATHER_CLOCK,MIFARE,1)] = handle_mifare_event
 
 def get_state_table_handler(vstatus, state, event, counter):
        return vstatus.state_table[(state,event,counter)]
@@ -858,7 +858,6 @@ def run_forever(rfh, wfh, options, cf):
                        except DispenseDatabaseException, e:
                                logging.error('Database error: '+str(e))
 
-
                timeout = time_to_next_update(vstatus)
                e = v.next_event(timeout)
                (event, params) = e
index d73eb4b..aca860e 100644 (file)
@@ -4,6 +4,7 @@ from CRC import do_crc
 from select import select
 import socket, logging
 from time import time, sleep
+from MIFAREClient import MIFAREClient
 
 asynchronous_responses = [     '400', '401', # door open/closed
                                '610',        # switches changed
@@ -14,6 +15,7 @@ DOOR = 1
 SWITCH = 2
 KEY = 3
 TICK = 4
+MIFARE = 5
 
 class VendingException(Exception): pass
 
@@ -35,6 +37,7 @@ class VendingMachine:
                while code != '000':
                        code = self.get_response()[0]
                self.get_switches()
+               self.mifare = MIFAREClient()
 
        def await_prompt(self):
                self.wfh.flush()
@@ -161,15 +164,31 @@ class VendingMachine:
        def next_event(self, timeout = None):
                # we don't want to buffer in the serial port, so we get all the events
                # we can ASAP.
-               if timeout < 0: timeout = 0
-               if len(self.events) > 0: timeout = 0
-               while True:
-                       (r, _, _) = select([self.rfh], [], [], timeout)
+
+               # Never have no timeout...
+               if timeout == None: timeout = 60*60*24*365
+
+               # Make sure we go through the loop at least once.
+               if timeout <= 0: timeout = 0.01
+
+               while timeout > 0:
+                       this_timeout = min(timeout, 0.2)
+                       timeout -= this_timeout
+
+                       (r, _, _) = select([self.rfh], [], [], this_timeout)
                        if r:
                                self.get_response(async = True)
                                timeout = 0
-                       else:
-                               break
+
+                       try:
+                               mifare_uid = self.mifare.get_card_uid()
+                       except ValueError:
+                               mifare_uid = None
+                       if mifare_uid != None:
+                               logging.info('Got MIFARE uid %s'%(str(mifare_uid)))
+                               self.events.append((MIFARE, mifare_uid))
+                               timeout = 0
+
                if len(self.events) == 0: return (TICK, time())
                ret = self.events[0]
                del self.events[0]

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