Esempio n. 1
0
    def __init__(self):
        self.coro_ops = UniversalQueue()

        self.root = tk.Tk()
        self.root.bind('<Escape>', self.disconnect)

        self.root.title('noio_ws Test Client')
        self.root.minsize(150, 100)
        self.root['bg'] = '#D9D7BF'

        self.message_area = tk.Text(self.root)
        self.message_area['state'] = 'disabled'
        self.message_area['bg'] = '#D9D7BF'
        self.message_area['fg'] = '#3B3A32'

        self.entry_area = tk.Entry(self.root)
        self.entry_area['relief'] = 'solid'
        self.entry_area['bd'] = 1
        self.entry_area['bg'] = '#D9D7BF'
        self.entry_area['fg'] = '#3B3A32'
        self.entry_area.bind('<Return>', self.callback_sender)

        self.entry_area.pack(side='bottom', fill='x')
        self.message_area.pack(side='left', fill='both', expand=True)

        self.wcon = ws.Connection(role='CLIENT')
Esempio n. 2
0
 def __init__(self, firmware: typing.io.BinaryIO, firmware_size: int,
              metadata: dict, delay: int):
     super().__init__("LEGO Bootloader")
     self.ble_id = None
     self.ble_name = "LEGO Bootloader"
     self.manufacturer_id = 0x00
     self.firmware = firmware
     self.firmware_size = firmware_size
     self.metadata = metadata
     self.delay = delay
     self.message_queue = None
     self.peripherals = {}
     self.peripheral_queue = UniversalQueue()
Esempio n. 3
0
    def __init__(self, name, query_port_info=False, ble_id=None):
        super().__init__(name)
        self.ble_id = ble_id
        self.query_port_info = query_port_info
        self.message_queue = None
        self.uart_uuid = uuid.UUID('00001623-1212-efde-1623-785feabcd123')
        self.char_uuid = uuid.UUID('00001624-1212-efde-1623-785feabcd123')
        self.tx = None
        self.peripherals = {}  # attach_sensor method will add sensors to this
        self.port_to_peripheral = {
        }  # Quick mapping from a port number to a peripheral object
        # Only gets populated once the peripheral attaches itself physically
        self.peripheral_queue = UniversalQueue(
        )  # Incoming messages from peripherals

        # Keep track of port info as we get messages from the hub ('update_port' messages)
        self.port_info = {}

        # Register this hub
        Hub.hubs.append(self)

        # Outgoing messages to web client
        # Assigned during system instantiaion before ble connect
        self.web_queue_out = None

        self.web_message = WebMessage(self)
Esempio n. 4
0
async def main():
    q = UniversalQueue()
    Thread(target=consumer, args=(q, )).start()
    t = await spawn(producer, 100, 1, q)
    t1 = await spawn(producer, 100, 0.2, q)
    t2 = await spawn(producer, 100, 0.5, q)
    await t.join()
    await t1.join()
    await t2.join()
Esempio n. 5
0
class FirmwareUpdateHub(Process):
    uart_uuid = uuid.UUID('00001625-1212-efde-1623-785feabcd123')
    char_uuid = uuid.UUID('00001626-1212-efde-1623-785feabcd123')
    query_port_info = None

    def __init__(self, firmware: typing.io.BinaryIO, firmware_size: int,
                 metadata: dict, delay: int):
        super().__init__("LEGO Bootloader")
        self.ble_id = None
        self.ble_name = "LEGO Bootloader"
        self.manufacturer_id = 0x00
        self.firmware = firmware
        self.firmware_size = firmware_size
        self.metadata = metadata
        self.delay = delay
        self.message_queue = None
        self.peripherals = {}
        self.peripheral_queue = UniversalQueue()

    async def peripheral_message_loop(self):
        pass

    async def run(self):
        print('getting device info...')
        await self.send_message('info', [FlashLoaderFunction.GET_INFO])
        _, info = await self.peripheral_queue.get()
        if not isinstance(info, InfoReply):
            raise RuntimeError('Failed to get device info')

        hub_type = HubType(info.type_id)
        print('Connected to', hub_type)

        fw_hub_type = HubType(self.metadata['device-id'])
        if hub_type != fw_hub_type:
            raise RuntimeError(f'Firmware is for {str(fw_hub_type)}' +
                               f' but we are connected to {str(hub_type)}')

        # HACK for cityhub bootloader bug. BlueZ will disconnect on certain
        # commands if we don't request a response.
        response = hub_type == HubType.CITYHUB

        print('erasing flash...')
        await self.send_message('erase', [FlashLoaderFunction.ERASE_FLASH],
                                response)
        _, result = await self.peripheral_queue.get()
        if not isinstance(result, EraseReply) or result.result:
            raise RuntimeError('Failed to erase flash')

        print('validating size...')
        size = list(struct.pack('<I', self.firmware_size))
        await self.send_message('init',
                                [FlashLoaderFunction.INIT_LOADER] + size,
                                response)
        _, result = await self.peripheral_queue.get()
        if not isinstance(result, InitReply) or result.result:
            raise RuntimeError('Failed to init')

        print('flashing firmware...')
        with tqdm(total=self.firmware_size, unit='B', unit_scale=True) as pbar:
            addr = info.start_addr
            while True:
                if not self.peripheral_queue.empty():
                    # we were not expecting a reply yet, this is probably an
                    # error, e.g. we overflowed the buffer
                    _, result = await self.peripheral_queue.get()
                    if isinstance(result, ErrorReply):
                        print('Received error reply', result)
                    else:
                        print('Unexpected message from hub. Please try again.')
                    return

                # BLE packet can only handle up to 14 bytes at a time
                payload = self.firmware.read(14)
                if not payload:
                    break

                size = len(payload)
                data = list(
                    struct.pack('<BI' + 'B' * size, size + 4, addr, *payload))
                addr += size
                await self.send_message(
                    'flash', [FlashLoaderFunction.PROGRAM_FLASH] + data)
                # If we send data too fast, we can overrun the Bluetooth
                # buffer on the hub
                await sleep(self.delay / 1000)
                pbar.update(size)

        _, result = await self.peripheral_queue.get()
        if not isinstance(result,
                          FlashReply) or result.count != self.firmware_size:
            raise RuntimeError('Failed to flash firmware')

        print('rebooting hub...')
        await self.send_message('reboot', [FlashLoaderFunction.START_APP])
        # This command does not get a reply

    async def send_message(self, msg_name, msg_bytes, response=False):
        while not self.tx:
            await sleep(0.1)
        await self.message_queue.put(
            (msg_name, self, bytearray(msg_bytes), response))
Esempio n. 6
0
class ClientChat:
    def __init__(self):
        self.coro_ops = UniversalQueue()

        self.root = tk.Tk()
        self.root.bind('<Escape>', self.disconnect)

        self.root.title('noio_ws Test Client')
        self.root.minsize(150, 100)
        self.root['bg'] = '#D9D7BF'

        self.message_area = tk.Text(self.root)
        self.message_area['state'] = 'disabled'
        self.message_area['bg'] = '#D9D7BF'
        self.message_area['fg'] = '#3B3A32'

        self.entry_area = tk.Entry(self.root)
        self.entry_area['relief'] = 'solid'
        self.entry_area['bd'] = 1
        self.entry_area['bg'] = '#D9D7BF'
        self.entry_area['fg'] = '#3B3A32'
        self.entry_area.bind('<Return>', self.callback_sender)

        self.entry_area.pack(side='bottom', fill='x')
        self.message_area.pack(side='left', fill='both', expand=True)

        self.wcon = ws.Connection(role='CLIENT')

    async def tk_mainloop(self, root):
        try:
            dooneevent = root.tk.dooneevent
        except AttributeError:
            # probably running in pypy
            dooneevent = _tkinter.dooneevent
        count = 0
        while True:

            count += 1
            dooneevent(DONT_WAIT)
            await curio.sleep(0)

            # stop if the root window is destroyed
            try:
                root.winfo_exists()
            except tk.TclError:
                break

    async def main(self):
        recv_task = await curio.spawn(self.run())
        await self.tk_mainloop(self.root)
        await recv_task.cancel()

    async def run(self):
        self.sock = curio.socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        await self.sock.connect(('localhost', 25000))
        await curio.spawn(self.get_events())
        while True:
            coro = await self.coro_ops.get()
            await coro

    async def get_events(self):
        while True:
            event = self.wcon.next_event()
            print(event)
            if event is ws.Directive.NEED_DATA:
                self.wcon.recv((await self.sock.recv(4096)))
                continue
            if event == ws.Information.CONNECTION_CLOSED:
                print('we outty')
                self.root.quit()
                self.root.destroy()
                break
            self.message_area['state'] = 'normal'
            self.message_area.insert(tk.INSERT, f'{event.message}\n')
            self.message_area['state'] = 'disabled'
            self.message_area.see("end")

    def callback_sender(self, event):
        msg = self.entry_area.get()
        if msg:
            self.entry_area.delete(0, 'end')
            self.coro_ops.put(self.ws_send(msg, 'text'))

    async def ws_send(self, message, type):
        await self.sock.sendall(self.wcon.send(ws.Data(message, type, True)))

    def disconnect(self, event):
        self.coro_ops.put(self.ws_send('', 'close'))
Esempio n. 7
0
def read_peer_info(queue: curio.UniversalQueue) -> None:
    line = input('Enter peer connection info: ')
    queue.put(parse_conn_info(line))
Esempio n. 8
0

async def startMqtt():
    global client
    client = connect_mqtt()
    subscribe(client)
    client.loop_start()


async def endMqtt():
    global client
    client.disconnect()
    client.loop_stop()


q = UniversalQueue()


# @attach(Button, name='train_btn', capabilities=['sense_press'])
@attach(LED, name='train_led')
@attach(TrainMotor, name='motor')
class Train(PoweredUpHub):
    currentSpeed = 0

    async def run(self):
        m = await spawn(startMqtt)
        self.message_info("Now up and Running")
        await self.train_led.set_color(Color.blue)
        while True:
            item = await q.get()
            self.message_info(f"have queue item `{item}`")