#!/usr/bin/python
# vim:ts=4
+USE_DB = 0
+
import sys, os, string, re, pwd
-import pg
+if USE_DB: import pg
from time import time, sleep
from popen2 import popen2
from LATClient import LATClient
from VendingMachine import VendingMachine
from ConfigParser import ConfigParser
+from HorizScroll import HorizScroll
+from random import random, seed
GREETING = 'UCC SNACKS'
PIN_LENGTH = 4
self.process_requests()
notify = self.db.getnotify()
+def scroll_options(username, mk, welcome = False):
+ if welcome:
+ msg = [(center('WELCOME'), False, 0.8),
+ (center(username), False, 0.8)]
+ else:
+ msg = []
+ choices = ' '*10+'CHOICES: '
+ try:
+ coke_machine = file('/home/other/coke/coke_contents')
+ cokes = coke_machine.readlines()
+ coke_machine.close()
+ except:
+ cokes = []
+ pass
+ for c in cokes:
+ c = c.strip()
+ (slot_num, price, slot_name) = c.split(' ', 2)
+ if slot_name == 'dead': continue
+ choices += '%s8-%s (%sc) '%(slot_num, slot_name, price)
+ choices += '55-DOOR '
+ choices += 'OR A SNACK. '
+ choices += '99 TO READ AGAIN. '
+ choices += 'CHOICE? '
+ msg.append((choices, False, None))
+ mk.set_messages(msg)
+
def get_pin(uid):
try:
info = pwd.getpwuid(uid)
def door_open_mode(vending_machine):
print "Entering open door mode"
- v.display("DOOR OPEN")
+ v.display("-FEED ME-")
while True:
e = v.next_event()
if e == None: break
(event, params) = e
if event == DOOR:
if params == 1: # door closed
- v.display("BYE BYE!")
+ v.display("-YUM YUM!-")
sleep(1)
return
+class Idler:
+ def __init__(self, v):
+ self.idle_state = 0
+ self.v = v
+
+ def put_shark(self, s, l):
+ if self.s[l] == ' ':
+ self.s[l] = s
+ elif self.s[l] == 'X':
+ self.s[l] = '*'
+ else:
+ self.s[l] = 'X'
+
+ def next(self):
+ # does the next stage of a dance
+ self.s = [' ']*10
+ shark1 = self.idle_state % 18
+ if shark1 < 9:
+ self.put_shark('^', shark1)
+ else:
+ self.put_shark('^', 18-shark1)
+
+ shark2 = ((self.idle_state+4) % 36)/2
+ if shark2 < 9:
+ self.put_shark('<', shark2)
+ else:
+ self.put_shark('<', 18-shark2)
+
+ shark3 = ((self.idle_state+7) % 54)/3
+ if shark3 < 9:
+ self.put_shark('>', 9-shark3)
+ else:
+ self.put_shark('>', 9-(18-shark3))
+
+ train1 = ((self.idle_state%(18*36)))
+ train1_start = 122
+ if train1 > train1_start and train1 < train1_start+(10*2):
+ for i in range(5):
+ ptr = i+train1-train1_start-5
+ if ptr >= 0 and ptr < 10: self.s[ptr] = '#'
+
+ train2 = ((self.idle_state%(18*36)))
+ train2_start = 400
+ if train2 > train2_start and train2 < train2_start+(10*2):
+ for i in range(5):
+ ptr = i+train2-train2_start-5
+ if ptr >= 0 and ptr < 10: self.s[9-ptr] = '#'
+
+ train3 = ((self.idle_state%(18*36)))
+ train3_start = 230
+ if train3 > train3_start and train3 < train3_start+(10*2):
+ for i in range(10):
+ ptr = i+train3-train3_start-10
+ if ptr >= 0 and ptr < 10: self.s[ptr] = '-'
+
+ self.v.display(string.join(self.s, ''))
+ self.idle_state += 1
+ self.idle_state %= 18*36*54
+
+def cookie(v):
+ seed(time())
+ messages = [' WASSUP! ', 'PINK FISH ', ' SECRETS ', ' ESKIMO ', ' FORTUNES ', 'MORE MONEY']
+ choice = int(random()*len(messages))
+ msg = messages[choice]
+ left = range(len(msg))
+ for i in range(len(msg)):
+ if msg[i] == ' ': left.remove(i)
+ reveal = 1
+ while left:
+ s = ''
+ for i in range(0, len(msg)):
+ if i in left:
+ if reveal == 0:
+ left.remove(i)
+ s += msg[i]
+ else:
+ s += chr(int(random()*26)+ord('A'))
+ reveal += 1
+ reveal %= 17
+ else:
+ s += msg[i]
+ v.display(s)
+
def center(str):
LEN = 10
return ' '*((LEN-len(str))/2)+str
class MessageKeeper:
def __init__(self, vendie):
+ # Each element of scrolling_message should be a 3-tuple of
+ # ('message', True/False if it is to be repeated, time to display)
self.scrolling_message = []
self.v = vendie
self.next_update = None
if not forced and self.next_update != None and time() < self.next_update:
return
if len(self.scrolling_message) > 0:
+ if len(self.scrolling_message[0][0]) > 10:
+ (m, r, t) = self.scrolling_message[0]
+ a = []
+ exp = HorizScroll(m).expand(padding = 0, wraparound = True)
+ if t == None:
+ t = 0.1
+ else:
+ t = t / len(exp)
+ for x in exp:
+ a.append((x, r, t))
+ del self.scrolling_message[0]
+ self.scrolling_message = a + self.scrolling_message
newmsg = self.scrolling_message[0]
if newmsg[2] != None:
self.next_update = time() + newmsg[2]
self.scrolling_message.append(self.scrolling_message[0])
del self.scrolling_message[0]
+ def done(self):
+ return len(self.scrolling_message) == 0
+
if __name__ == '__main__':
cp = ConfigParser()
cp.read('/etc/dispense/servers.conf')
v = VendingMachine(rfh, wfh)
print 'PING is', v.ping()
- db = DispenseDatabase(v, DBServer, DBName, DBUser, DBPassword)
+ if USE_DB: db = DispenseDatabase(v, DBServer, DBName, DBUser, DBPassword)
cur_user = ''
cur_pin = ''
cur_selection = ''
mk = MessageKeeper(v)
mk.set_message(GREETING)
- logout_timeout = None
+ time_to_autologout = None
+ idler = Idler(v)
+ time_to_idle = None
last_timeout_refresh = None
while True:
- db.handle_events()
+ if USE_DB: db.handle_events()
- if logout_timeout != None:
- time_left = logout_timeout - time()
- if time_left < 10 and last_timeout_refresh > time_left:
+ if time_to_autologout != None:
+ time_left = time_to_autologout - time()
+ if time_left < 5 and (last_timeout_refresh is None or last_timeout_refresh > time_left):
mk.set_message('LOGOUT: '+str(int(time_left)))
last_timeout_refresh = int(time_left)
+ cur_selection = ''
- if logout_timeout != None and logout_timeout - time() <= 0:
- logout_timeout = None
+ if time_to_autologout != None and time_to_autologout - time() <= 0:
+ time_to_autologout = None
cur_user = ''
cur_pin = ''
cur_selection = ''
mk.set_message(GREETING)
+ if time_to_autologout and not mk.done(): time_to_autologout = None
+ if cur_user == '' and time_to_autologout: time_to_autologout = None
+ if len(cur_pin) == PIN_LENGTH and mk.done() and time_to_autologout == None:
+ # start autologout
+ time_to_autologout = time() + 15
+
+ if time_to_idle == None and cur_user == '': time_to_idle = time() + 60
+ if time_to_idle != None and cur_user != '': time_to_idle = None
+ if time_to_idle is not None and time() > time_to_idle: idler.next()
+
mk.update_display()
e = v.next_event(0)
if username:
v.beep(0, False)
cur_selection = ''
-
- msg = [(center('WELCOME'), False, 0.8),
- (center(username), False, 0.9)]
- msg.append(('CHOICES :', True, 1))
- msg.append(('55 - DOOR', True, 1))
- msg.append(('OR A SNACK', True, 1))
- mk.set_messages(msg)
+ scroll_options(username, mk, True)
continue
else:
v.beep(40, False)
continue
cur_selection += chr(key + ord('0'))
mk.set_message('SELECT: '+cur_selection)
+ time_to_autologout = None
elif len(cur_selection) == 1:
if key == 11:
cur_selection = ''
- mk.set_message('SELECT: ')
+ time_to_autologout = None
+ scroll_options(username, mk)
continue
else:
cur_selection += chr(key + ord('0'))
if cur_selection == '55':
v.display('GOT DOOR?')
os.system('su - "%s" -c "dispense door"'%username)
+ elif cur_selection == '91':
+ cookie(v)
+ elif cur_selection == '99':
+ scroll_options(username, mk)
+ cur_selection = ''
+ continue
elif cur_selection[1] == '8':
v.display('GOT COKE?')
os.system('su - "%s" -c "dispense %s"'%(username, cur_selection[0]))
v.display('THANK YOU')
sleep(0.5)
cur_selection = ''
- logout_timeout = time() + 10
+ time_to_autologout = time() + 10