Example #1
0
async def queue_go():
    q = Queue(10)
    asyncio.create_task(foo(q))
    asyncio.create_task(bar(q))
    await asyncio.sleep(3)
    for n in range(4):
        asyncio.create_task(q_put(n, q))
    await asyncio.sleep(1)
    assert q.qsize() == 10
    await q.get()
    await asyncio.sleep(0.1)
    assert q.qsize() == 10
    while not q.empty():
        await q.get()
        await asyncio.sleep(0.1)
    assert q.empty()
    print('Competing put tasks test complete')

    for n in range(4):
        asyncio.create_task(q_get(n, q))
    await asyncio.sleep(1)
    x = 0
    while not q.full():
        await q.put(x)
        await asyncio.sleep(0.3)
        x += 1
    assert q.qsize() == 10
    print('Competing get tasks test complete')
    await asyncio.gather(putter(q), getter(q))
    print('Queue tests complete')
    print("I've seen starships burn off the shoulder of Orion...")
    print("Time to die...")
Example #2
0
    def __init__(self,
                 name,
                 url,
                 fw_version,
                 actuators,
                 timer,
                 uart,
                 tx_en,
                 events_callback=None):
        self.events_cb = events_callback

        self.uart = uart

        # Serial TX enable pin
        self.tx_en = tx_en
        self.tx_en.off()

        self.send_queue = Queue(maxsize=50)
        self.event_queue = Queue(maxsize=50)

        self.cc_device = CCDevice(name, url, fw_version, actuators=actuators)
        self.cc_slave = CCSlave(self.on_response, self.on_event, timer,
                                self.cc_device)

        # Allocate fixed buffers once up-front and use memoryviews
        # to save on allocations and reduce memory fragmentation
        self.rx_buf_size = 2 * RX_BUFFER_SIZE
        self._rx_buffer = bytearray(self.rx_buf_size)
        self._tx_buffer = bytearray(TX_BUFFER_SIZE)

        self.RX_BUF = memoryview(self._rx_buffer)
        self.TX_BUF = memoryview(self._tx_buffer)

        # asyncio event set by the hard UART interrupt handler
        self.rx_event = IRQ_EVENT()

        # Hook up our callback to the UART receive interrupt. This will simply set
        # the asyncio event and get the heck out. The asyncio handler will be the
        # workhorse and do the work outside of the hard interrupt handler
        # TODO: This may not be fully public/finished API but seems to work well for my STM32 board
        #self.uart.irq(handler, trigger, hard)  # Not properly documented in uPython
        # TODO: machine.UART.IRQ_RXIDLE seems specific to STM32?
        self.uart.irq(self.on_serial_rx_data, machine.UART.IRQ_RXIDLE, True)

        asyncio.create_task(self.handle_serial_rx())
        asyncio.create_task(self.handle_serial_tx())
        asyncio.create_task(self.cc_slave_process())
        asyncio.create_task(self.process_events())
Example #3
0
class ThreadPool:
    def __init__(self, max_workers):
        self.max_workers = max_workers
        self.runnables = Queue()
        self.workers = []
        for _ in range(max_workers):
            self.workers.append(Worker(self.runnables))

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, exc_traceback):
        self.join()

    def submit(self, f, *args):
        self.runnables.put({"function": f, "args": args})

    def join(self):
        for worker in self.workers:
            worker.is_closed = True

        for worker in self.workers:
            worker.thread.join()
Example #4
0
    def init(self, queue_size=QUEUE_SIZE_DEFAULT, long_keypress_count=LONG_KEYPRESS_COUNT_DEFAULT):
        ## Create the queue to push key events to.
        self.queue = Queue(maxsize=queue_size)

        self.running = False
        self.long_keypress_count = long_keypress_count

        ## The chars on the keypad
        keys = [
            '1', '2', '3',
            '4', '5', '6',
            '7', '8', '9',
            '*', '0', '#',
            ]

        ## The chars to display/return when the key is pressed down for a long time.
        self.chars_long = [
            'A', 'B', 'C',
            'D', 'E', 'F',
            'G', 'H', 'I',
            'J', 'K', 'L',
            ]

        ## Initialise all keys to the UP state.
        self.keys = [ { 'char':key, 'state':self.KEY_UP, 'down_count':0 } for key in keys ]

        ## Pin names for rows and columns.
        self.rows = env.KEYPAD_ROW_PINS
        self.cols = env.KEYPAD_COL_PINS

        ## Initialise row pins as outputs.
        self.row_pins = [ Pin(pin_name, mode=Pin.OUT, pull=None) for pin_name in self.rows ]

        ## Initialise column pins as inputs.
        self.col_pins = [ Pin(pin_name, mode=Pin.IN, pull=Pin.PULL_DOWN) for pin_name in self.cols ]

        self.row_scan_delay_ms = 40 // len(self.rows)
Example #5
0
cond02 4 triggered. tim = 3
cond02 1 triggered. tim = 5
cond02 2 triggered. tim = 5
cond02 0 triggered. tim = 7
cond04 99 Awaiting notification and predicate.
cond04 99 triggered. tim = 9
Done.
''', 13)
    asyncio.run(cond_go())


# ************ Queue test ************

from primitives.queue import Queue

q = Queue()


async def slow_process():
    await asyncio.sleep(2)
    return 42


async def bar():
    print('Waiting for slow process.')
    result = await slow_process()
    print('Putting result onto queue')
    await q.put(result)  # Put result on q


async def foo():
Example #6
0
class Keypad_uasyncio():
    ## Key states/events
    KEY_UP          = 0
    KEY_DOWN        = 1
    KEY_DOWN_LONG   = 2
    KEY_UP_LONG     = 3     ## an event only, not a state.

    def __init__(self, queue_size=QUEUE_SIZE_DEFAULT, long_keypress_count=LONG_KEYPRESS_COUNT_DEFAULT):
        self.init(queue_size=queue_size, long_keypress_count=long_keypress_count)

    #-------------------------------------------------------------------------

    def init(self, queue_size=QUEUE_SIZE_DEFAULT, long_keypress_count=LONG_KEYPRESS_COUNT_DEFAULT):
        ## Create the queue to push key events to.
        self.queue = Queue(maxsize=queue_size)

        self.running = False
        self.long_keypress_count = long_keypress_count

        ## The chars on the keypad
        keys = [
            '1', '2', '3',
            '4', '5', '6',
            '7', '8', '9',
            '*', '0', '#',
            ]

        ## The chars to display/return when the key is pressed down for a long time.
        self.chars_long = [
            'A', 'B', 'C',
            'D', 'E', 'F',
            'G', 'H', 'I',
            'J', 'K', 'L',
            ]

        ## Initialise all keys to the UP state.
        self.keys = [ { 'char':key, 'state':self.KEY_UP, 'down_count':0 } for key in keys ]

        ## Pin names for rows and columns.
        self.rows = env.KEYPAD_ROW_PINS
        self.cols = env.KEYPAD_COL_PINS

        ## Initialise row pins as outputs.
        self.row_pins = [ Pin(pin_name, mode=Pin.OUT, pull=None) for pin_name in self.rows ]

        ## Initialise column pins as inputs.
        self.col_pins = [ Pin(pin_name, mode=Pin.IN, pull=Pin.PULL_DOWN) for pin_name in self.cols ]

        self.row_scan_delay_ms = 40 // len(self.rows)

    #-------------------------------------------------------------------------

    def start(self):
        self.running = True

    #-------------------------------------------------------------------------

    def stop(self):
        self.running = False
        for _, row_pin in enumerate(self.row_pins):
            row_pin.value(1) # prepare rows up and to cols wake up from deep sleep

    #-------------------------------------------------------------------------

    def get_key(self):
        key = self.queue.get()
        return key

    #-------------------------------------------------------------------------

    def key_process(self, key_code, col_pin):
        key = self.keys[key_code]
        key_event = None

        if col_pin.value():
            ## key pressed down
            if key['state'] == self.KEY_UP:
                ## just pressed (up => down)
                key_event = self.KEY_DOWN
                key['state'] = key_event
            elif key['state'] == self.KEY_DOWN:
                ## key still down
                    key['down_count'] += 1
                    if key['down_count'] >= self.long_keypress_count:
                        key_event = self.KEY_DOWN_LONG
                        key['state'] = key_event
        else:
            ## key not pressed (up)
            if key['state'] == self.KEY_DOWN:
                ## just released (down => up)
                key_event = self.KEY_UP if key['down_count'] < self.long_keypress_count else self.KEY_UP_LONG
            key['state'] = self.KEY_UP
            key['down_count'] = 0

        return key_event

    async def scan_coro(self):
        """A coroutine to scan each row and check column for key events."""

        while self.running:
            key_code = 0
            for row, row_pin in enumerate(self.row_pins):
                ## Assert row.
                row_pin.value(1)

                ## Delay between processing each row.
                await asyncio.sleep_ms(self.row_scan_delay_ms)

                ## Check for key events for each column of current row.
                for col, col_pin in enumerate(self.col_pins):
                    ## Process pin state.
                    key_event = self.key_process(key_code=key_code, col_pin=col_pin)
                    ## Process key event.
                    if key_event == self.KEY_UP:
                        key_char = self.keys[key_code]['char']
                        await self.queue.put(key_char)
                    elif key_event == self.KEY_DOWN_LONG:
                        key_char = self.chars_long[key_code]
                        await self.queue.put(key_char)

                    key_code += 1

                ## Deassert row.
                row_pin.value(0)
Example #7
0
class ControlChainSlaveDevice:
    def __init__(self,
                 name,
                 url,
                 fw_version,
                 actuators,
                 timer,
                 uart,
                 tx_en,
                 events_callback=None):
        self.events_cb = events_callback

        self.uart = uart

        # Serial TX enable pin
        self.tx_en = tx_en
        self.tx_en.off()

        self.send_queue = Queue(maxsize=50)
        self.event_queue = Queue(maxsize=50)

        self.cc_device = CCDevice(name, url, fw_version, actuators=actuators)
        self.cc_slave = CCSlave(self.on_response, self.on_event, timer,
                                self.cc_device)

        # Allocate fixed buffers once up-front and use memoryviews
        # to save on allocations and reduce memory fragmentation
        self.rx_buf_size = 2 * RX_BUFFER_SIZE
        self._rx_buffer = bytearray(self.rx_buf_size)
        self._tx_buffer = bytearray(TX_BUFFER_SIZE)

        self.RX_BUF = memoryview(self._rx_buffer)
        self.TX_BUF = memoryview(self._tx_buffer)

        # asyncio event set by the hard UART interrupt handler
        self.rx_event = IRQ_EVENT()

        # Hook up our callback to the UART receive interrupt. This will simply set
        # the asyncio event and get the heck out. The asyncio handler will be the
        # workhorse and do the work outside of the hard interrupt handler
        # TODO: This may not be fully public/finished API but seems to work well for my STM32 board
        #self.uart.irq(handler, trigger, hard)  # Not properly documented in uPython
        # TODO: machine.UART.IRQ_RXIDLE seems specific to STM32?
        self.uart.irq(self.on_serial_rx_data, machine.UART.IRQ_RXIDLE, True)

        asyncio.create_task(self.handle_serial_rx())
        asyncio.create_task(self.handle_serial_tx())
        asyncio.create_task(self.cc_slave_process())
        asyncio.create_task(self.process_events())

    def on_serial_rx_data(self, arg):
        '''
        Callback called as an ISR whenever there are characters waiting in the RX buffer.
        '''
        # Set the asyncio event and return ASAP
        self.rx_event.set()

    async def handle_serial_rx(self, ):
        while True:
            await self.rx_event.wait()  # Wait for the next interrupt
            bytes_read = 0
            bytes_avail = self.uart.any()
            # Read as many bytes as we can into our buffer. This should hopefully
            # avoid many calls to the interrupt handler if a long transmission
            # comes in. We can grab as many bytes as we can as they come in, in realtime.
            while bytes_avail > 0 and bytes_read + bytes_avail < self.rx_buf_size:
                buffer = self.RX_BUF[bytes_read:bytes_read + bytes_avail]
                length = len(buffer)
                remaining = length
                while remaining > 0:
                    _read = self.uart.readinto(buffer[length - remaining:],
                                               remaining)
                    remaining -= _read
                bytes_read += length
                bytes_avail = self.uart.any()

            if bytes_read > 0:
                messages = self.cc_slave.protocol.receive_data(
                    self.RX_BUF[0:bytes_read])
                for message in messages:
                    self.cc_slave.handle_message(message)

    async def handle_serial_tx(self, ):
        while True:
            # Service any queued messages to be sent
            message = await self.send_queue.get()
            # Enable serial TX
            self.tx_en.on()
            # TODO - Figure out what this should be...
            time.sleep_us(300)
            num_tx_bytes = message.get_tx_bytes(self.TX_BUF[0:])
            bytes_written = 0
            while bytes_written < num_tx_bytes:
                # print("Sending: %s" % [w for w in self.TX_BUF[bytes_written:num_tx_bytes]])
                bytes_written += self.uart.write(
                    self.TX_BUF[bytes_written:num_tx_bytes])
            self.tx_en.off()
            del message

    # Callbacks
    def on_response(self, message, priority=CC_MSG_PRIORITY_LOW):
        try:
            if priority == CC_MSG_PRIORITY_HIGH:
                self.send_queue.insert_nowait(message)
            else:
                self.send_queue.put_nowait(message)
        except QueueFull:
            print("Send queue full! Dropping message!", message.__dict__)

    def on_event(self, event):
        try:
            self.event_queue.put_nowait(event)
        except QueueFull:
            print("Event queue full! Dropping event!", event.__dict__)

    async def cc_slave_process(self, ):
        '''
        Advance the control chain slave state machines.
        '''
        while True:
            self.cc_slave.process()
            await asyncio.sleep_ms(0)

    async def process_events(self, ):
        '''
        Asynchronously process the event queue and handle any queued messages found in it,
        and advance the control chain slave state machines.
        '''
        while True:
            # Process any events in the event queue
            event = await self.event_queue.get()
            if self.events_cb is not None:
                self.events_cb(event)
            await asyncio.sleep_ms(0)

    #########################
    # User-exposed API calls
    #########################
    @property
    def is_connected(self, ):
        return self.cc_slave.comm_state == LISTENING_REQUESTS

    @property
    def assignments(self, ):
        return self.cc_device.assignments

    @property
    def actuators(self, ):
        return self.cc_device.actuators
Example #8
0
 def __init__(self, max_workers):
     self.max_workers = max_workers
     self.runnables = Queue()
     self.workers = []
     for _ in range(max_workers):
         self.workers.append(Worker(self.runnables))
Example #9
0
from config import config, serial
# MQTT Section
from mqtt_as import MQTTClient

# game mode
NORMAL = const(1)
VERSUS = const(2)

config_topic = "buzz/{}/config".format(serial)
event_topic = "buzz/{}/events".format(serial)
announce_topic = "buzz/ping"

ping = False
locked = False
# queue to push message to mqtt
notification_queue = Queue(maxsize=16)
# Reset pin
reset_pin = Pin(19, Pin.IN, Pin.PULL_UP)


def button_press(pos: int) -> None:
    """
    Handler for button press
    """
    global locked  # Prevent creating local variable
    if locked:
        print("locked no press")
        return
    if players_lock[pos]:
        print("Player lock")
        return
Example #10
0
import signal
from requests_handlers import make_initial_request, make_request
from primitives.thread_pool import ThreadPool
from data_handlers import get_aggregate_data
from primitives.queue import Queue
from server import TCPServer

if __name__ == "__main__":
  access_token, url = make_initial_request()
  q_out = Queue()
  q_in = Queue()
  q_in.put(url)

  with ThreadPool(max_workers=6) as executor:
    for _ in range(6):
      executor.submit(make_request, access_token, q_in, q_out)
    data = get_aggregate_data(q_out)
    server = TCPServer()
    server.start(data)
Example #11
0
async def queue_go(delay):
    queue = Queue()
    asyncio.create_task(consume(queue))
    asyncio.create_task(produce(queue))
    await asyncio.sleep(delay)
    print("Done")