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')
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()
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)
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()
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))
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'))
def read_peer_info(queue: curio.UniversalQueue) -> None: line = input('Enter peer connection info: ') queue.put(parse_conn_info(line))
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}`")