예제 #1
0
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()
예제 #2
0
    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()
예제 #3
0
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()
예제 #4
0
파일: driver.py 프로젝트: pmich/bartendro
    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()