Exemple #1
0
class Matemat:
    log = getLogger('MatematSim')

    def __init__(self):
        pass

    @flogger(log)
    def writeLCD(self, msg):
        self.log.info('writeLCD(): msg=%s' % msg)

    @flogger(log)
    def getPriceline(self):
        while True:
            try:
                print 'Priceline?'
                p = int(sys.stdin.readline().strip())
                self.log.debug('priceline=%s' % p)
                return p
            except ValueError:
                pass

    @flogger(log)
    def serve(self, priceline):
        self.log.info('priceline=%s' % priceline)
        # always serve
        return True

    @flogger(log)
    def completeserve(self):
        return True
Exemple #2
0
class SerialInterface:
    log = getLogger('SerialInterface')
    
    @flogger(log)
    def  __init__ ( self, path2device, baudrate, timeout=0):
        self.ser = serial.Serial(path2device, baudrate)
        self.ser.flushInput()
        self.ser.flushOutput()
        if timeout:
            self.ser.setTimeout(timeout)
        self.seriallog = open("/tmp/seriallog","w");

    def writeMessage(self,message):
        enc = "\\0" + message.replace('\\','\\\\') + "\\1";
        self.log.debug('writing %s' % enc)
        self.ser.write(enc)

    def readMessage(self):
        data = ""
        escaped = False
        stop = False
        start = False

        while True:
            c = self.ser.read(1)
            if len(c) == 0:             #A timout occured
                self.log.warning('TIMEOUT')
                return False
        #    print "c=", c
        #    continue
            if escaped:
                if c == '0':
                    start = True
                elif c == '1':
                    stop = True
                elif c == '\\':
                    d = '\\'
                escaped = False
            elif c == '\\':
                escaped = 1
            else:
                d = c
                
            if start:
                start = False
            elif stop:
                if data[0] == 'D':
                    message = '%f %s'%(time.time(), data[2:])
                    self.log.info('serial debug message: %d %s'%(len(data), data))
                    self.seriallog.write(message+"\n")
                    self.seriallog.flush()
                    #print message
                    data = ""
                    stop = False
                else:
                    self.log.debug('received message: len=%d data=%s'%(len(data),data))
                    return data
            elif escaped == False:
                data += str(d)
Exemple #3
0
class Checkout(threading.Thread):
    log = getLogger('Checkout')

    @flogger(log)
    def __init__(self):
        threading.Thread.__init__(self)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        #self.sock.setblocking(0)
        self.sock.bind((config.get('checkout', 'listen_ip'),
                        config.getint('checkout', 'listen_port')))
        self.matemat = matemat.Matemat()

    @flogger(log)
    def go(self):
        self.matemat.writeLCD('OBEY AND CONSUME')
        while not self.gotPurse:
            self.waitForSocket()
            if not self.processCommand():
                return

        credit = self.token.eot()
        self.log.debug('credit=%s' % credit)
        self.report('Credit: %s' % credit)

        priceline = None
        while 1:
            if self.checkAbort():
                return

            priceline = self.matemat.getPriceline()
            if priceline == -1:
                self.report('TIMEOUT', 3)
                return
            elif priceline != 0:
                self.log.info('priceline=%s' % priceline)
                break
            time.sleep(0.01)

        assets = self.token.assets(priceline)
        if assets < 0:
            self.report('Not enough credits!', 3)
            return

        self.token.finish(priceline)
        if self.matemat.serve(priceline):
            self.log.info('Serving %s' % priceline)
            self.report('%i left! kthxbye' % assets, 3)
        else:
            self.log.info('Failed to serve %s' % priceline)
            self.report('Failed to serve!', 3)
            self.token.rollback(priceline)
            return

        if False:  #not self.matemat.completeserve():
            self.log.info('Failed to complete serve %s' % priceline)
            self.report('Failed to cserve!', 3)
            self.token.rollback(priceline)

    @flogger(log)
    def report(self, msg, wait=0):
        self.matemat.writeLCD(msg)
        if wait != 0:
            time.sleep(wait)

    @flogger(log)
    def waitForSocket(self, timeout=None):
        r = select([self.sock], [], [], timeout)
        return len(r[0]) == 1

    @flogger(log)
    def checkAbort(self):
        if self.waitForSocket(timeout=0):
            return self.processCommand(checkAbort=True)
        return False

    @flogger(log)
    def processCommand(self, checkAbort=False):
        data, self.raddr = self.sock.recvfrom(128)
        data.strip()
        if len(data) == 0:
            return

        cmd = data[:2]
        self.log.info('cmd=%s' % cmd)
        data = data[2:].strip()
        self.log.info('data=%s' % data)

        if checkAbort:
            return cmd == 'Ab'

        ret = False
        if cmd == 'Rd':
            if self.idle:
                self.send('READY')
                ret = True
        elif cmd == 'Ab':
            pass
        elif cmd == 'Bp':
            if len(data) == 0:
                self.report('ERR: Bad Purse!', 3)
            else:
                self.report('ERR: %s' % data[:15], 3)
        elif cmd == 'Td':
            self.gotPurse = True
            ret = True
        elif cmd == 'Tc':
            #self.report('Reading tokens...')
            self.token.check(data)
            self.report('Credit: %s' % self.token.tokencount)
            self.send('OK')
            ret = True
        elif cmd == 'Dm':
            self.report(data[:20], 3)

        return ret

    @flogger(log)
    def send(self, msg):
        self.log.info('msg=%s' % msg)
        return self.sock.sendto(msg, self.raddr) == 0

    @flogger(log)
    def run(self):
        self.token = tokens.Token()
        while 1:
            self.idle = True
            self.gotPurse = False
            self.go()
            self.token.clear()
Exemple #4
0
class CheckoutOld(threading.Thread):
    IDLE, COUNTING, CHECKING, WAITING, SERVING, CHECKINGSERVE, ABORTING,\
            WAITSTATE, REPORTING = range(9)
    log = getLogger('Checkout')

    @flogger(log)
    def __init__(self, test=False):
        threading.Thread.__init__(self)
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.setblocking(0)
        self.socket.bind((config.get('checkout', 'listen_ip'),
                          config.getint('checkout', 'listen_port')))
        self.matemat = matemat.Matemat()

        self.state = self.IDLE
        self.newstate = True
        self.served = False
        self.waiting = 0

    @flogger(log)
    def send(self, msg):
        self.log.info('msg=%s' % msg)
        # print "sending",msg
        sent = self.socket.sendto(msg, self.raddr)
        if sent == 0:
            return False
        else:
            return True

    @flogger(log)
    def checkState(self):
        if self.waiting:
            if time.time() >= self.waiting:
                self.log.debug('setting state ' + str(self.nextstate))
                self.state = self.nextstate
                self.newstate = True
                self.waiting = False

    @flogger(log)
    def setState(self, nextstate, wait=0):
        self.log.debug('nextstate=%d wait%d' % (nextstate, wait))
        self.waiting = time.time() + wait
        self.nextstate = nextstate
        self.state = self.WAITSTATE

    @flogger(log)
    def fetchCommand(self):
        try:
            data, self.raddr = self.socket.recvfrom(64)
            data.strip()
            if len(data) > 0:
                self.cmd = "%s%s" % (data[0], data[1])
                self.log.info('cmd=%s' % self.cmd)
                self.data = data[2:].strip()
                self.log.info('data=%s' % self.data)
                return True
        except:
            pass
        return False

    @flogger(log)
    def reset(self):
        if self.served:
            self.token.finish(0)
        self.token.tokenreset = True
        self.matemat.writeLCD("OBEY AND CONSUME")
        self.served = False

    @flogger(log)
    def pay(self):
        self.token.pay()

    @flogger(log)
    def run(self):
        self.token = tokens.Token()  #has to be in this thread
        while 1:
            self.checkState()
            if (self.state == self.IDLE or self.state == self.COUNTING) and \
                    select([self.socket],[],[]) and self.fetchCommand():
                if not self.command():
                    self.log.info('command failed')
                    self.send("FAIL")
            self.process()

    def process(self):
        self.log.debug('processing state %d' % self.state)
        if self.state == self.IDLE:
            self.idle()
        elif self.state == self.COUNTING:
            if self.newstate:
                self.newstate = False
                self.socket.setblocking(1)
                self.matemat.writeLCD("Reading tokens")
            if self.tokendata:
                self.token.check(self.tokendata)
                self.send("OK")
                #print time.time()
                self.tokendata = ""
        elif self.state == self.ABORTING:
            self.abort()
        elif self.state == self.WAITING:
            self.wait()
        elif self.state == self.CHECKING:
            self.check()
        elif self.state == self.SERVING:
            self.serve()
        elif self.state == self.CHECKINGSERVE:
            self.checkserve()
        elif self.state == self.REPORTING:
            if self.newstate:
                self.newstate = False
                self.matemat.writeLCD(self.report)
            self.setState(self.IDLE, 3)

    def idle(self):
        if self.newstate:
            self.newstate = False
            self.reset()
        #time.sleep(0.1)

    def abort(self):
        if self.newstate:
            self.newstate = False
            self.matemat.writeLCD("aborting")
            self.setState(self.IDLE, 3)

    def wait(self):
        #sys.exit(0)
        if self.newstate:
            self.newstate = False
            self.credit = self.token.eot()
            self.log.debug('credit=%s' % self.credit)
            self.matemat.writeLCD("Credit: %s" % self.credit)
        self.priceline = self.matemat.getPriceline()
        if self.priceline == -1:
            self.matemat.writeLCD("TIMEOUT")
            self.setState(self.ABORTING, 3)
        elif self.priceline != 0:
            self.log.info('priceline=%s' % self.priceline)
            self.setState(self.CHECKING)
        time.sleep(0.01)

    def check(self):
        liquidity = self.token.assets(self.priceline)
        if liquidity == False:
            self.matemat.writeLCD("Not enough credits")
            self.setState(self.IDLE, 3)
        else:
            self.setState(self.SERVING)

    def serve(self):
        if self.matemat.serve(self.priceline):
            self.log.info('Serving %s' % self.priceline)
            self.matemat.writeLCD("Enjoy it")
            self.served = True
            self.setState(self.CHECKINGSERVE)
        else:
            self.log.info('Failed to serve %s' % self.priceline)
            self.matemat.writeLCD("Failed to serve")
            served = False
            self.setState(self.ABORTING, 3)

    def checkserve(self):
        if not self.matemat.completeserve():
            self.log.info('Failed to serve %s' % self.priceline)
            self.matemat.writeLCD("Failed to serve")
            served = False
            self.setState(self.ABORTING, 3)
        else:
            self.setState(self.IDLE, 3)

    @flogger(log)
    def command(self):
        if self.cmd == "Ta":
            if self.token.add(tokendata):
                self.send("OK")
                return True
            return False
        elif self.cmd == "Rd":
            if self.state == self.IDLE:
                self.send("READY")
                return True
            return False
        elif self.cmd == "Ab":
            if self.state != self.IDLE and self.nextstate != self.IDLE:
                self.setState(self.ABORTING)
            return False
        elif self.cmd == "Tc":
            if self.state == self.IDLE or self.state == self.COUNTING:
                self.tokendata = self.data
                if self.state == self.IDLE:
                    self.setState(self.COUNTING)
                return True
            else:
                return False
            return True
        elif self.cmd == "Td":
            if self.state == self.COUNTING:
                self.setState(self.WAITING)
                self.socket.setblocking(0)
                return True
            return False
        elif self.cmd == "Bp":
            self.setState(self.REPORTING)
            self.report = "Bad Purse!"
            self.socket.setblocking(0)
Exemple #5
0
class Cashier:
    log = getLogger('Cashier')

    @flogger(log)
    def __init__(self):
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.socket.connect((config.get('cashier', 'checkout_ip'),
                             config.getint('cashier', 'checkout_port')))
        self.socket.settimeout(1)

    @flogger(log)
    def send(self, msg):
        sent = self.socket.send(msg)
        if sent != 0:
            self.log.debug('"%s": Send OK' % msg)
            return True
        else:
            self.log.debug('"%s": Send failed' % msg)
            return False

    @flogger(log)
    def recv(self, expect):
        try:
            data = self.socket.recv(64)
        except:
            return False

        data = data.strip()
        if data == expect:
            self.log.debug('"%s": Receive OK' % expect)
            return True
        else:
            self.log.debug('"%s": Receive failed' % expect)
            return False

    @flogger(log)
    def isReady(self):
        sent = self.send("Rd")
        if sent:
            rcvd = self.recv("READY")
        else:
            return False

        if rcvd:
            return True
        else:
            return False

    @flogger(log)
    def reportBadPurse(self, message=None):
        if message:
            sent = self.send("Bp%s" % message)
        else:
            sent = self.send("Bp")

    @flogger(log)
    def abort(self):
        sent = self.send("Ab")
        if sent: rcvd = self.recv("OK")
        else: return False

        if rcvd: return True
        else: return False

    @flogger(log)
    def checkToken(self, token):
        sent = self.send("Tc%s" % token)

        if sent:
            rcvd = self.recv("OK")
        else:
            return False

        if rcvd:
            self.log.debug('"%s": True' % token)
            return True
        else:
            self.log.debug('"%s": False' % token)
            return False

    @flogger(log)
    def checkCredit(self):
        sent = self.send("Td")

    @flogger(log)
    def display(self, message):
        sent = self.send("Dm%s" % message)
Exemple #6
0
class Matemat(threading.Thread):
    log = getLogger('Matemat')
    messages = Queue.Queue()

    def __init__(self):
        threading.Thread.__init__(self)
        self.interface = upay.serialinterface.SerialInterface(
            '/dev/ttyS0', 115200, 5)

    def run(self):
        while 1:
            message = self.interface.readMessage()

            self.messages.put(message)

    def getMessage(self):
        return self.messages.get(block=True)

    @flogger(log)
    def _waitForReply(self, reply):
        self.log.debug('reply=%s' % reply)
        while True:
            msg = self.getMessage()
            if msg == False:
                return False
            if msg in reply:
                self.log.debug('msg=%s' % msg)
                return msg

    @flogger(log)
    def writeLCD(self, msg):
        self.log.info('writeLCD(): msg=%s' % msg)
        msg = "d" + msg
        self.interface.writeMessage(msg)
        return self._waitForReply(["dD"])

    @flogger(log)
    def getPriceline(self):
        self.interface.writeMessage("p")
        while True:
            msg = self.getMessage()
            if msg == False:
                return -1
            if msg[0] == 'p':
                self.log.debug('priceline=%s' % msg[2])
                return int(msg[2])

    @flogger(log)
    def serve(self, priceline):
        self.log.info('priceline=%s' % priceline)
        self.interface.writeMessage("s" + str(priceline))
        ret = self._waitForReply(["sO", "sN"])
        if ret == False:
            return False
        if ret == "sN":
            return False
        return True

    @flogger(log)
    def completeserve(self):
        return self._waitForReply(["sD"])