class RouterDriver(object): '''This object interacts with the bartendro router controller.''' def __init__(self, device, software_only): self.device = device self.ser = None self.msg = "" self.ret = 0 self.software_only = software_only self.dispenser_select = None self.dispenser_version = DISPENSER_DEFAULT_VERSION self.startup_log = "" self.debug_levels = [200, 180, 120] # dispenser_ids are the ids the dispensers have been assigned. These are logical ids # used for dispenser communication. self.dispenser_ids = [255 for i in xrange(MAX_DISPENSERS)] # dispenser_ports are the ports the dispensers have been plugged into. self.dispenser_ports = [255 for i in xrange(MAX_DISPENSERS)] if software_only: self.num_dispensers = MAX_DISPENSERS else: self.num_dispensers = 0 def get_startup_log(self): return self.startup_log def get_dispenser_version(self): return self.dispenser_version def reset(self): """Reset the hardware. Do this if there is shit going wrong. All motors will be stopped and reset.""" if self.software_only: return self.close() self.open() def count(self): return self.num_dispensers def set_timeout(self, timeout): self.ser.timeout = timeout def open(self): '''Open the serial connection to the router''' if self.software_only: return self._clear_startup_log() try: log.info("Opening %s" % self.device) self.ser = serial.Serial(self.device, BAUD_RATE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=.01) except serial.serialutil.SerialException, e: raise SerialIOError(e) log.info("Done.\n") import status_led self.status = status_led.StatusLED(self.software_only) self.status.set_color(0, 0, 1) self.dispenser_select = dispenser_select.DispenserSelect( MAX_DISPENSERS, self.software_only) self.dispenser_select.open() self.dispenser_select.reset() # This primes the communication line. self.ser.write(chr(170) + chr(170) + chr(170)) sleep(.001) log.info("Discovering dispensers") self.num_dispensers = 0 for port in xrange(MAX_DISPENSERS): self._log_startup("port %d:" % port) self.dispenser_select.select(port) sleep(.01) while True: self.ser.flushInput() self.ser.write("???") data = self.ser.read(3) ll = "" for ch in data: ll += "%02X " % ord(ch) if len(data) == 3: if data[0] != data[1] or data[0] != data[2]: self._log_startup(" %s -- inconsistent" % ll) continue id = ord(data[0]) self.dispenser_ids[self.num_dispensers] = id self.dispenser_ports[self.num_dispensers] = port self.num_dispensers += 1 self._log_startup( " %s -- Found dispenser with pump id %02X, index %d" % (ll, id, self.num_dispensers)) break elif len(data) > 1: self._log_startup( " %s -- Did not receive 3 characters back. Trying again." % ll) sleep(.5) else: break self._select(0) self.set_timeout(DEFAULT_TIMEOUT) self.ser.write(chr(255)) duplicate_ids = [ x for x, y in collections.Counter(self.dispenser_ids).items() if y > 1 ] if len(duplicate_ids): for dup in duplicate_ids: if dup == 255: continue self._log_startup("ERROR: Dispenser id conflict!\n") sent = False for i, d in enumerate(self.dispenser_ids): if d == dup: if not sent: self._send_packet8(i, PACKET_ID_CONFLICT, 0) sent = True self._log_startup(" dispenser %d has id %d\n" % (i, d)) self.dispenser_ids[i] = 255 self.num_dispensers -= 1 self.dispenser_version = self.get_dispenser_version(0) if self.dispenser_version < 0: self.dispenser_version = DISPENSER_DEFAULT_VERSION else: self.status.swap_blue_green() log.info( "Detected dispensers version %d. (Only checked first dispenser)" % self.dispenser_version) self.led_idle()
def open(self): '''Open the serial connection to the router''' if self.software_only: return self._clear_startup_log() try: log.info("Opening %s" % self.device) self.ser = serial.Serial(self.device, BAUD_RATE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=.01) except serial.serialutil.SerialException: raise SerialIOError log.info("Done.\n") import status_led self.status = status_led.StatusLED(self.software_only) self.status.set_color(0, 0, 1) self.dispenser_select = dispenser_select.DispenserSelect( MAX_DISPENSERS, self.software_only) self.dispenser_select.open() self.dispenser_select.reset() # This primes the communication line. self.ser.write(chr(170) + chr(170) + chr(170)) sleep(.001) log.info("Discovering dispensers") self.num_dispensers = 0 for port in xrange(MAX_DISPENSERS): self._log_startup("port %d:" % port) self.dispenser_select.select(port) sleep(.01) while True: self.ser.flushInput() self.ser.write("???") data = self.ser.read(3) ll = "" for ch in data: ll += "%02X " % ord(ch) if len(data) == 3: if data[0] != data[1] or data[0] != data[2]: self._log_startup(" %s -- inconsistent" % ll) continue id = ord(data[0]) self.dispenser_ids[self.num_dispensers] = id self.dispenser_ports[self.num_dispensers] = port self.num_dispensers += 1 self._log_startup( " %s -- Found dispenser with pump id %02X, index %d" % (ll, id, self.num_dispensers)) break elif len(data) > 1: self._log_startup( " %s -- Did not receive 3 characters back. Trying again." % ll) sleep(.5) else: break self._select(0) self.set_timeout(DEFAULT_TIMEOUT) self.ser.write(chr(255)) duplicate_ids = [ x for x, y in collections.Counter(self.dispenser_ids).items() if y > 1 ] if len(duplicate_ids): for dup in duplicate_ids: if dup == 255: continue self._log_startup("ERROR: Dispenser id conflict!\n") sent = False for i, d in enumerate(self.dispenser_ids): if d == dup: if not sent: self._send_packet8(i, PACKET_ID_CONFLICT, 0) sent = True self._log_startup(" dispenser %d has id %d\n" % (i, d)) self.dispenser_ids[i] = 255 self.num_dispensers -= 1 self.led_idle()
class RouterDriver(object): ''' plug in replacement for Bartendro RouterDriver to control the naive peristlatic pumps from Hello Drinkbot project. Provides a layer above the AdaFruit motor library which understands pumps''' def __init__(self, device, software_only=False): ''' device is ignored, it is required for bartendro hardware''' self.device = device self.__doc__ = 'foo' self.dispenser_cnt = 8 self.software_only = software_only self.dispenser_version = DISPENSER_DEFAULT_VERSION self.startup_log = "" # I need a hellodrinkbot switch #if not software_only: if 1: try: self.mh1 = Adafruit_MotorHAT(addr=0x60) #self.ports = [self.mh1.getMotor(foo+1) for foo in range(4)] #for motor in range(4): #self.ports[motor].setSpeed(255) except: # no motor hat, but that might be fine self.mh1 = Fake_MotorHAT() log.info("No Motor Hat?") self.ports = [self.mh1.getMotor(foo + 1) for foo in range(4)] for motor in range(4): self.ports[motor].setSpeed(255) pass # Add a second motor hat, with a second address. Comment the # above lines, replace with something like this: # self.mh1 = Adafruit_MotorHAT(addr=0x60) # self.mh2 = Adafruit_MotorHAT(addr=0xXX) # self.ports = [self.mh1.getMotor(range(1,9))] # for motor in range(8): # self.ports[motor].setSpeed(255) else: #self.ports = [i for i in range(1, 5)] pass self.num_dispensers = MAX_DISPENSERS self.dispensers = [ #{'port': None, 'direction': MOTOR_DIRECTION_FORWARD}, { 'port': 0, 'direction': MOTOR_DIRECTION_FORWARD }, { 'port': 0, 'direction': MOTOR_DIRECTION_BACKWARD }, { 'port': 1, 'direction': MOTOR_DIRECTION_FORWARD }, { 'port': 1, 'direction': MOTOR_DIRECTION_BACKWARD }, { 'port': 2, 'direction': MOTOR_DIRECTION_FORWARD }, { 'port': 2, 'direction': MOTOR_DIRECTION_BACKWARD }, { 'port': 3, 'direction': MOTOR_DIRECTION_FORWARD }, { 'port': 3, 'direction': MOTOR_DIRECTION_BACKWARD }, ] def get_startup_log(self): return self.startup_log def get_dispenser_version(self): return self.dispenser_version def reset(self): """Reset the hardware. Do this if there is shit going wrong. All motors will be stopped and reset.""" if self.software_only: return self.close() self.open() def count(self): return self.num_dispensers def set_timeout(self, timeout): self.ser.timeout = timeout def open(self): '''Open the serial connection to the router''' if self.software_only: return self._clear_startup_log() try: log.info("Opening %s" % self.device) self.ser = serial.Serial(self.device, BAUD_RATE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=.01) except serial.serialutil.SerialException, e: #raise SerialIOError(e) pass log.info("Done.\n") import status_led self.status = status_led.StatusLED(self.software_only) self.status.set_color(0, 0, 1) #self.dispenser_select = dispenser_select.DispenserSelect( # MAX_DISPENSERS, self.software_only) #self.dispenser_select.open() #self.dispenser_select.reset() # This primes the communication line. self.ser.write(chr(170) + chr(170) + chr(170)) sleep(.001) log.info("Discovering dispensers") self.num_dispensers = 0 for port in xrange(MAX_DISPENSERS): self._log_startup("port %d:" % port) #self.dispenser_select.select(port) sleep(.01) while True: self.ser.flushInput() self.ser.write("???") data = self.ser.read(3) ll = "" for ch in data: ll += "%02X " % ord(ch) if len(data) == 3: if data[0] != data[1] or data[0] != data[2]: self._log_startup(" %s -- inconsistent" % ll) continue id = ord(data[0]) self.dispenser_ids[self.num_dispensers] = id self.dispenser_ports[self.num_dispensers] = port self.num_dispensers += 1 self._log_startup( " %s -- Found dispenser with pump id %02X, index %d" % (ll, id, self.num_dispensers)) break elif len(data) > 1: self._log_startup( " %s -- Did not receive 3 characters back. Trying again." % ll) sleep(.5) else: break self._select(0) self.set_timeout(DEFAULT_TIMEOUT) self.ser.write(chr(255)) duplicate_ids = [ x for x, y in collections.Counter(self.dispenser_ids).items() if y > 1 ] if len(duplicate_ids): for dup in duplicate_ids: if dup == 255: continue self._log_startup("ERROR: Dispenser id conflict!\n") sent = False for i, d in enumerate(self.dispenser_ids): if d == dup: if not sent: self._send_packet8(i, PACKET_ID_CONFLICT, 0) sent = True self._log_startup(" dispenser %d has id %d\n" % (i, d)) self.dispenser_ids[i] = 255 self.num_dispensers -= 1 self.dispenser_version = self.get_dispenser_version(0) if self.dispenser_version < 0: self.dispenser_version = DISPENSER_DEFAULT_VERSION else: self.status.swap_blue_green() log.info( "Detected dispensers version %d. (Only checked first dispenser)" % self.dispenser_version) self.led_idle()
def open(self): '''Open the serial connection to the router''' if self.software_only: return try: print "Opening %s" % self.device self.ser = serial.Serial(self.device, BAUD_RATE, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=.01) except serial.serialutil.SerialException: raise SerialIOError print "Done." print import status_led self.status = status_led.StatusLED(self.software_only) self.status.set_color(0, 0, 1) self.dispenser_select = dispenser_select.DispenserSelect( MAX_DISPENSERS, self.software_only) self.dispenser_select.open() self.dispenser_select.reset() # This primes the communication line. self.ser.write(chr(170) + chr(170) + chr(170)) sleep(.001) self.num_dispensers = 0 for port in xrange(MAX_DISPENSERS): print "port %d" % port self.dispenser_select.select(port) sleep(.01) while True: self.ser.flushInput() self.ser.write("???") data = self.ser.read(3) for ch in data: print "%02X " % ord(ch), if len(data) == 3: if data[0] != data[1] or data[0] != data[2]: print "inconsistent" continue id = ord(data[0]) self.dispenser_ids[self.num_dispensers] = id self.dispenser_ports[self.num_dispensers] = port self.num_dispensers += 1 print "Found dispenser %d with pump id %d -- assigned dispenser %d" % ( port, id, self.num_dispensers) break elif len(data) > 1: print "Did not receive 3 characters back. Trying again." sleep(.5) else: break self.select(0) self.ser.timeout = 2 self.ser.write(chr(255)) duplicate_ids = [ x for x, y in collections.Counter(self.dispenser_ids).items() if y > 1 ] if len(duplicate_ids): for dup in duplicate_ids: if dup == 255: continue print "ERROR: Dispenser id conflict!" sent = False for i, d in enumerate(self.dispenser_ids): if d == dup: if not sent: self.send_packet8(i, PACKET_ID_CONFLICT, 0) sent = True print " dispenser %d has id %d" % (i, d) self.dispenser_ids[i] = 255 self.num_dispensers -= 1 #self.num_dispensers = 1 self.led_idle()