def test_event_mask_defaults_to_input_and_error():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1)
        ev1.signal()
        
        selector.wait(timeout=0)
        assert selector.ready == ev1
        assert selector.has_input == True
def test_can_use_a_different_value_to_identify_the_event_source():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT, identifier=999)
        
        ev1.signal()
        
        selector.wait()
        assert selector.ready == 999
def test_event_mask_defaults_to_input_and_error():
    with Selector() as selector:
        ev1 = Semaphore(blocking=False)

        selector.add(ev1)
        ev1.signal()

        selector.wait(timeout=0)
        assert selector.ready == ev1
        assert selector.has_input == True
Beispiel #4
0
def test_can_use_a_different_value_to_identify_the_event_source():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT, identifier=999)

        ev1.signal()

        selector.wait()
        assert selector.ready == 999
def test_can_remove_source_from_selector():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT)
        
        ev1.signal()
        
        selector.wait(timeout=0)
        assert selector.ready == ev1
        
        selector.remove(ev1)
        
        selector.wait(timeout=0)
        assert selector.ready == None
def test_selector_is_a_convenient_api_to_epoll():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT)
        
        ev1.signal()
        
        selector.wait()
        assert selector.ready == ev1
        assert selector.has_input == True
        assert selector.has_output == False
        assert selector.has_error == False
        assert selector.has_hangup == False
        assert selector.has_priority_input == False
Beispiel #7
0
def test_can_remove_source_from_selector():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT)

        ev1.signal()

        selector.wait(timeout=0)
        assert selector.ready == ev1

        selector.remove(ev1)

        selector.wait(timeout=0)
        assert selector.ready == None
Beispiel #8
0
def test_selector_is_a_convenient_api_to_epoll():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    with selector, ev1:
        selector.add(ev1, INPUT)

        ev1.signal()

        selector.wait()
        assert selector.ready == ev1
        assert selector.has_input == True
        assert selector.has_output == False
        assert selector.has_error == False
        assert selector.has_hangup == False
        assert selector.has_priority_input == False
def test_can_wait_with_a_timeout():
    with Semaphore(blocking=False) as ev1, \
         Selector() as selector:

        selector.add(ev1, INPUT, identifier=999)

        selector.wait(timeout=0)
        assert selector.ready == None
Beispiel #10
0
def test_selecting_from_multiple_event_sources():
    with Semaphore(blocking=False) as ev1, \
         Semaphore(blocking=False) as ev2, \
         Selector() as selector:

        selector.add(ev1, INPUT)
        selector.add(ev2, INPUT)

        ev1.signal()
        ev2.signal()

        selector.wait()
        first = selector.ready
        first.wait()

        selector.wait()
        second = selector.ready
        second.wait()

        assert first in (ev1, ev2)
        assert second in (ev1, ev2)
        assert first is not second
def test_selecting_from_multiple_event_sources():
    selector = Selector()
    ev1 = Semaphore(blocking=False)
    ev2 = Semaphore(blocking=False)
    with selector, ev1, ev2:
        selector.add(ev1, INPUT)
        selector.add(ev2, INPUT)
        
        ev1.signal()
        ev2.signal()
        
        selector.wait()
        first = selector.ready
        first.wait()
        
        selector.wait()
        second = selector.ready
        second.wait()
        
        assert first in (ev1, ev2)
        assert second in (ev1, ev2)
        assert first is not second
class TemperatureLogger():
    """Starts recording temperatures from two TMP100 chips attached to the I2C bus.
    Resolution determined by BITS.
    Sensors read every LOG_INTERVAL, recording to TEMPERATURE_CSV_FILE.
    """
    semaphore = Semaphore(blocking=False)
    log_timer = Timer(offset=1, interval=LOG_INTERVAL)

    def __init__(self):
        self._terminated = False
        self.timestamp = None
        self.temperatures = [None, None]
        self.log_handler = RotatingFileHandler(TEMPERATURE_CSV_FILE, backupCount=10)
        self.log_handler.setFormatter(TempFormatter())

    def run(self):
        logging.info("Temperature logging starting...")

        with i2c.I2CMaster() as bus,\
             Selector() as selector,\
             self.semaphore,\
             self.log_timer,\
             Timer(offset=0.1, interval=LCD_INTERVAL) as lcd_timer,\
             Adafruit_LCDPlate.get_interrupt_pin() as int_pin:

            # tolerate missing LCD
            lcd = None
            try:
                lcd = Adafruit_LCDPlate.Adafruit_LCDPlate(bus)
                fmt = FMT_ALL
                logging.info("LCD is attached")
            except IOError:
                logging.info("LCD is not attached")

            # resolution (9-12 bit) gets stored as (0-3) in bits 5,6 of config reg
            config = (BITS - 9) << 5
            bus.transaction(
                i2c.writing_bytes(TMP100A_ADDRESS, CONFIG_REGISTER, config),
                i2c.writing_bytes(TMP100B_ADDRESS, CONFIG_REGISTER, config))

            for addr in (TMP100A_ADDRESS, TMP100B_ADDRESS):
                read_results = bus.transaction(
                    i2c.writing_bytes(addr, CONFIG_REGISTER),
                    i2c.reading(addr, 1))
                # should be 0x80 at startup/reset
                logging.info("conf register for 0x{0:02x}: 0x{1:02x}".format(addr, read_results[0][0]))

            right_shift = 16 - BITS
            div = 1 << (BITS - 8)

            selector.add(self.semaphore)
            selector.add(self.log_timer)
            self.log_timer.start()

            if lcd:
                selector.add(lcd_timer)
                selector.add(int_pin)
                lcd_timer.start()

            while not self._terminated:
                try:
                    if lcd:
                        lcd.set_led(Adafruit_LCDPlate.GREEN_PIN, False)

                    selector.wait()
                    if self._terminated:
                        break
                    if not selector.ready is int_pin:
                        selector.ready.wait() # consume event

                    for i, addr in enumerate((TMP100A_ADDRESS, TMP100B_ADDRESS)):
                        read_results = bus.transaction(
                            i2c.writing_bytes(addr, TEMP_REGISTER),
                            i2c.reading(addr, 2))
                        t = read_results[0]
                        self.temperatures[i] = (t[0] if t[0] <= 127 else t[0] - 256) + (t[1] >> right_shift) / div

                    self.timestamp = time()

                    if lcd:
                        lcd.set_led(Adafruit_LCDPlate.GREEN_PIN, True)
                        lcd.set_led(Adafruit_LCDPlate.RED_PIN, False)

                    if selector.ready is self.log_timer:
                        self.log_handler.emit(TempLogRecord(self.timestamp, self.temperatures))
                    elif selector.ready is lcd_timer:
                        lcd.clear()
                        lcd.message(fmt.format(
                            self.temperatures[0], c2f(self.temperatures[0]),
                            self.temperatures[1], c2f(self.temperatures[1])))
                    elif selector.ready is int_pin:
                        # this is hacky...
                        intcap = lcd.chip.registers.read_register(INTCAPA) # required?
                        button_state = lcd.get_button_state()
                        if button_state == 0:
                            pass # button up event: ignore
                        else:
                            if lcd.button_state_pressed(button_state, Adafruit_LCDPlate.SELECT):
                                fmt = FMT_ALL
                            elif lcd.button_state_pressed(button_state, Adafruit_LCDPlate.UP):
                                fmt = FMT_INSIDE
                            elif lcd.button_state_pressed(button_state, Adafruit_LCDPlate.DOWN):
                                fmt = FMT_OUTSIDE
                            elif lcd.button_state_pressed(button_state, Adafruit_LCDPlate.LEFT):
                                fmt = FMT_C
                            elif lcd.button_state_pressed(button_state, Adafruit_LCDPlate.RIGHT):
                                fmt = FMT_F
                            else:
                                fmt = "Unknown\nButton!"
                            lcd_timer.stop()
                            lcd_timer.start()
                except KeyboardInterrupt:
                    logging.info("Keyboard interrupt received")
                    self._terminated = True
                except SystemExit:
                    logging.info("SystemExit received")
                    self._terminated = True
                except:
                    logging.exception("Error reading sensors:")
                    if lcd:
                        lcd.set_led(Adafruit_LCDPlate.RED_PIN, True)
            if lcd:
                lcd.clear()
                lcd.set_backlight(False)
                lcd.set_led(Adafruit_LCDPlate.GREEN_PIN, False)
                lcd.set_led(Adafruit_LCDPlate.RED_PIN, False)

        logging.info("Temperature logging stopped.")
        self.log_handler.close()

    def terminate(self):
        self._terminated = True
        self.semaphore.signal()

    def rotate_log(self):
        self.log_timer.stop()
        self.log_handler.doRollover()
        self.log_timer.start()