/[anoncvs]/projects/dispense2/sql-edition/servers/VendingMachine.py


UCC Code Repository

Diff of /projects/dispense2/sql-edition/servers/VendingMachine.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by dagobah, Fri Jun 25 15:33:12 2004 UTC revision 1.6 by dagobah, Sun Jun 27 11:11:00 2004 UTC
# Line 1  Line 1 
1  import re  # vim:ts=4
2    import re, pg
3  from CRC import do_crc  from CRC import do_crc
4  from binascii import unhexlify  from select import select
5    
6  asynchronous_responses = [      '400', '401', # door open/closed  asynchronous_responses = [      '400', '401', # door open/closed
7                                  '610',        # switches changed                                  '610',        # switches changed
8                                    '200', '201', '202', '203', '204', '205', '206',
9                                    '207', '208', '209', '211', # key presses
10                           ]                           ]
11    DOOR = 1
12    SWITCH = 2
13    KEY = 3
14    
15  class VendingMachine:  class VendingMachine:
16          def __init__(self, rfh, wfh):          def __init__(self, rfh, wfh):
17                    self.events = []
18                  self.secret = 'AAAAAAAAAAAAAAAA'                  self.secret = 'AAAAAAAAAAAAAAAA'
19                  self.rfh = rfh                  self.rfh = rfh
20                  self.wfh = wfh                  self.wfh = wfh
# Line 21  class VendingMachine: Line 28  class VendingMachine:
28                  code = ''                  code = ''
29                  while code != '000':                  while code != '000':
30                          (code, _) = self.get_response()                          (code, _) = self.get_response()
31                    self.get_switches()
32    
33          def await_prompt(self):          def await_prompt(self):
34                  self.wfh.flush()                  self.wfh.flush()
# Line 29  class VendingMachine: Line 37  class VendingMachine:
37                  s = ''                  s = ''
38                  while True:                  while True:
39                          s = self.rfh.read(1)                          s = self.rfh.read(1)
40                          if s == '': raise Exception                          if s == '': raise Exception('nothing read!')
41                          if s == '\n' or s == '\r':                          if s == '\n' or s == '\r':
42                                  state = 1                                  state = 1
43                                  prefix = ''                                  prefix = ''
# Line 39  class VendingMachine: Line 47  class VendingMachine:
47                                          self.challenge = None                                          self.challenge = None
48                                          return                                          return
49                                  if re.search('^[0-9a-fA-F]{4}$', prefix):                                  if re.search('^[0-9a-fA-F]{4}$', prefix):
50                                          self.challenge = unhexlify(prefix)                                          self.challenge = int(prefix, 16)
51                                          return                                          return
52    
53          def get_response(self):          def get_response(self, async = False):
54                  self.wfh.flush()                  self.wfh.flush()
55                  while True:                  while True:
56                          s = ''                          s = ''
# Line 54  class VendingMachine: Line 62  class VendingMachine:
62                          text = s[4:]                          text = s[4:]
63                          if code in asynchronous_responses:                          if code in asynchronous_responses:
64                                  self.handle_event(code, text)                                  self.handle_event(code, text)
65                                    if async: return None
66                          else:                          else:
67                                  self.await_prompt()                                  self.await_prompt()
68                                  return (code, text)                                  return (code, text)
69    
70            def get_switches(self):
71                    self.wfh.write('S\n')
72                    (code, text) = self.get_response()
73                    if code != '600':
74                            return (False, code, text)
75                    self.interpret_switches(text)
76                    return (True, code, text)
77    
78            def interpret_switches(self, text):
79                    self.switches = (int(text[0:2], 16) << 8) | int(text[3:5], 16)
80    
81          def handle_event(self, code, text):          def handle_event(self, code, text):
82                  pass                  if code == '400':
83                            self.events.append((DOOR, 0))
84                    elif code == '401':
85                            self.events.append((DOOR, 1))
86                    elif code == '610':
87                            self.events.append((SWITCH, None))
88                            self.interpret_switches(text)
89                    elif code[0] == '2':
90                            self.events.append((KEY, int(code[1:3])))
91                    else:
92                            sys.stderr.write('WARNING: Unhandled event! (%s %s)\n'%(code,text))
93    
94          def authed_message(self, message):          def authed_message(self, message):
95                  if self.challenge == None:                  if self.challenge == None:
# Line 79  class VendingMachine: Line 109  class VendingMachine:
109                          return (False, 'Invalid item requested (%s)'%item)                          return (False, 'Invalid item requested (%s)'%item)
110                  self.wfh.write(self.authed_message(('V%s\n'%item)+'\n'))                  self.wfh.write(self.authed_message(('V%s\n'%item)+'\n'))
111                  (code, string) = self.get_response()                  (code, string) = self.get_response()
112                  return (code, string)                  return (code == '100', code, string)
113    
114          def beep(self, duration = None, synchronous = True):          def beep(self, duration = None, synchronous = True):
115                  msg = 'B'                  msg = 'B'
# Line 101  class VendingMachine: Line 131  class VendingMachine:
131                          msg += '%02x'%duration                          msg += '%02x'%duration
132                  self.wfh.write(msg+'\n')                  self.wfh.write(msg+'\n')
133                  (code, string) = self.get_response()                  (code, string) = self.get_response()
134                  # FIXME: workaround a bug in rom W. should be just: return (code == '500', code, string)                  return (code == '501', code, string)
                 return (code == '500' or code == '501', code, string)  
135    
136          def display(self, string):          def display(self, string):
137                  if len(string) > 10:                  if len(string) > 10:
# Line 111  class VendingMachine: Line 140  class VendingMachine:
140                  (code, string) = self.get_response()                  (code, string) = self.get_response()
141                  return (code == '300', code, string)                  return (code == '300', code, string)
142    
143            def next_event(self, timeout = None):
144                    # we don't want to buffer in the serial port, so we get all the events
145                    # we can ASAP.
146                    if len(self.events) > 0: timeout = 0
147                    while True:
148                            (r, _, _) = select([self.rfh], [], [], timeout)
149                            if r:
150                                    self.get_response(async = True)
151                                    timeout = 0
152                            else:
153                                    break
154                    if len(self.events) == 0: return None
155                    ret = self.events[0]
156                    del self.events[0]
157                    return ret

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.6

Managed by UCC Webmasters ViewVC Help
Powered by ViewVC 1.1.26