use LATClientException not just Exception
[uccvend-vendserver.git] / virtualvend / vvend.py
index ac9de42..c06970d 100644 (file)
@@ -2,6 +2,7 @@
 
 import sys
 import socket
+import string
 
 try:
   import pygtk
@@ -21,6 +22,20 @@ except:
   print "/usr/local/lib/python2.2/site-packages/"
   sys.exit(1)
 
+import pango
+
+class Switches:
+    def __init__(self):
+       self.misc_input = 0xff
+       self.switch_input = 0x3f
+    def door_open(self):
+       return self.switch_input & 0x20
+    def set_door_open(self, open = True):
+       if open:
+           self.switch_input |= 0x20
+       else:
+           self.switch_input &= ~0x20
+
 #now we have both gtk and gtk.glade imported
 #Also, we know we are running GTK v2
 
@@ -53,13 +68,33 @@ class appgui:
        "on_button9_clicked" : self.keypad_clicked,
        "on_button10_clicked" : self.keypad_clicked,
        "on_button11_clicked" : self.keypad_clicked,
+       "on_button11_clicked" : self.keypad_clicked,
+       "on_door_toggled" : self.door_changed,
         "on_vvend_destroy_event" : self.quit,
         "on_vvend_delete_event" : self.quit }
     self.wTree.signal_autoconnect (dic)
     display = self.wTree.get_widget("label1")
+    label_font = pango.FontDescription('monospace 28')
+    display.modify_font(label_font)
+
+    label_style = display.get_style().copy()
+    fg_color = display.get_colormap().alloc_color('lightgreen')
+    label_style.fg[gtk.STATE_NORMAL] = fg_color
+    display.set_style(label_style)
+
+    w = self.wTree.get_widget("eventbox1")
+    wstyle = w.get_style().copy()
+    bg_color = w.get_colormap().alloc_color('black')
+    wstyle.bg[gtk.STATE_NORMAL] = bg_color
+    w.set_style(wstyle)
+
     display.set_text("*5N4CK0RZ*")
 
+    # vending machine password set here
+    self.vendpw = "AAAAAAAAAAAAAAAA"
+
     self.messageid = None
+    self.switches = Switches()
 
     #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     #s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
@@ -77,13 +112,29 @@ class appgui:
 
 
     return
-  
+
+    def __del__(self):
+       try:
+           self.sock.close()
+           self.sock.shutdown()
+       except:
+           pass
+
 #####CALLBACKS
   def keypad_clicked(self,widget):
-    print "button clicked"
-    print widget.get_label()
-    self.do_send(widget.get_label())
-    sys.stdout.write("\a")
+    key = widget.get_label()
+    if key == 'RESET':
+       key = '11'
+    else:
+       key = '0'+key
+    self.do_send('2'+key+' keypress\n')
+
+  def door_changed(self, widget):
+    self.switches.set_door_open(not widget.get_active())
+    if widget.get_active():
+       self.do_send('401 door closed\n')
+    else:
+       self.do_send('400 door open\n')
 
   def handleNewConnection(self,source,condition):
     #source is a socket in GTK v 1 and a fd in version 2
@@ -112,10 +163,13 @@ class appgui:
   def server(self):
 
      # inicializa o servidor
+     port = 5150
 
      self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-     self.sock.bind(('localhost', 5051))
+     self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+     self.sock.bind(('localhost', port))
      self.sock.listen(0)
+     print "listening on ", port
 
      # 
      #
@@ -137,6 +191,7 @@ class appgui:
      # insere o cliente na lista e registra o m├ętodo self.write como 
      # callback para quando existirem dados esperando para serem lidos
 
+     self.do_prompt()
      self.clients[addr] = (conn, gtk.input_add(conn, gtk.gdk.INPUT_READ, self.write))
 
   def write(self, source, condition):
@@ -163,6 +218,7 @@ class appgui:
             for (addr, port), (conn, tag) in self.clients.iteritems():
                 if source is conn:
                     self.insert('%s:%s >>> %s\n'%(addr, port, data.strip()))
+                   self.handle_command(data.strip())
                     break
      
      return gtk.TRUE
@@ -180,10 +236,108 @@ class appgui:
             gtk.input_remove(tag)
             conn.close()
      self.sock.close()
+     self.sock.shutdown()
 
      gtk.mainquit()
      sys.stdout.write("quit!\n")
 
+  def do_prompt(self):
+    self.do_send("# ")
+
+  def do_help(self):
+    help = """
+
+Valid commands are:
+ ABOUT         ROM information
+ B[S][nn]      beep [synchronously] for a duration nn (optional)
+ C[S][nn]      silence [synchronously] for a duration nn (optional)
+ Dxxxxxxxxxx   show a message on the display
+ ECHO {ON|OFF} turn echo on or off
+ GETROM        download the ROM source code using xmodem
+ H[...]        this help screen
+*JUMPxxxx      jumps to a subroutine at location xxxx
+*PEEKxxxx      returns the value of the byte at location xxxx
+*POKExxxxyy    sets the value of location xxxx to yy
+ PING          pongs
+ S[...]        query all internal switch states
++Vnn           vend an item
++VALL          vend all items
+*Wxxxxxxxxxxxx set a new password for authenticated vends. xxx=16 chars
+               password will be converted to uppercase
+
+Very few functions are available when the machine is in standalone 
+mode (DIP SW 1 is set)
++ denotes that this item requires authentication if DIP SW 2 is set
+* denotes that DIP SW 3 must be set to use these
+Commands starting with # are ignored (comments)
+"""
+    self.do_send(help)
+  
+  def do_about(self):
+    about = """
+
+The Virtual Vending Machine Company
+
+Mark Tearle, June 2004
+"""
+    self.do_send(about)
+
+  def do_vend_all(self):
+     for i in range(11,99):
+       self.do_send("101 Vending "+str(i)+"\n")
+       self.do_send("153 Home sensors failing\n")
+     self.do_send("102 Vend all motors complete\n")
+  
+  def do_vend(self,command):
+     fail = None
+     if fail:
+       self.do_send("153 Home sensors failing\n")
+     else:
+        self.insert("Vending "+command)
+       self.do_send("100 Vend successful\n")
+    
+  def do_display(self,string):
+     display = self.wTree.get_widget("label1")
+     display.set_text("%-10.10s" % (string))
+     self.do_send('300 Written\n')
+
+  def do_beep(self,command):
+     sys.stdout.write("\a")
+     self.do_send('500 Beeped\n')
+
+  def do_silence(self,command):
+     pass
+
+  def do_switches(self):
+     self.do_send("600 3F 3F\n")
+
+  def do_pong(self):
+     self.do_send("000 PONG!\n")
+
+  def handle_command(self, command):
+     command = string.upper(command)
+     print command
+     if string.find(command, "HELP",0) == 0:
+       self.do_help()
+     elif string.find(command, "ABOUT",0) == 0:
+       self.do_about()
+     elif string.find(command, "PING",0) == 0:
+       self.do_pong()
+     elif string.find(command, "VALL",0) == 0:
+       self.do_vend_all()
+     elif string.find(command, "V",0) == 0:
+       self.do_vend(command)
+     elif string.find(command, "B",0) == 0:
+       self.do_beep(command)
+     elif string.find(command, "C",0) == 0:
+       self.do_silence(command)
+     elif string.find(command, "S",0) == 0:
+       self.do_switches()
+     elif string.find(command, "D",0) == 0:
+       self.do_display(command[1:])
+     self.do_prompt()
+       
+
 # we start the app like this...
 app=appgui()
 gtk.mainloop()

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