async def _process_input_async(ps: InteractiveShell, transport: serial_asyncio.SerialTransport, transform: Transform): newline_sym = transform.tx('\n') while True: tx_data = await ps.prompt_async() tx_data = tx_data + newline_sym tx_data = tx_data.encode('utf-8') transport.write(tx_data)
async def connect_serial(address) -> Connection: LOGGER.info(f'Connecting over Serial to {address}') protocol = FileSenderProtocol() ser = serial.serial_for_url(address, baudrate=YMODEM_TRANSFER_BAUD_RATE) transport = SerialTransport(asyncio.get_event_loop(), protocol, ser) transport.serial.rts = False transport.set_write_buffer_limits( high=255) # receiver RX buffer is 256, so limit send buffer to 255 conn = Connection(address, transport, protocol) await conn.protocol.connected return conn
async def connect_serial(app: web.Application, factory: ProtocolFactory_ ) -> Awaitable[ConnectionResult_]: config = app['config'] port = config['device_serial'] id = config['device_id'] address = detect_device(port, id) protocol = factory() ser = serial.serial_for_url(address, baudrate=DEFAULT_BAUD_RATE) loop = asyncio.get_event_loop() transport = SerialTransport(loop, protocol, ser) transport.serial.rts = False transport.set_write_buffer_limits(high=255) # receiver RX buffer is 256, so limit send buffer to 255 return address, transport, protocol
def open_serial_connection(self, limit=None, **kwargs): # type: ignore """A wrapper for create_serial_connection() returning a (reader, writer) pair. The reader returned is a StreamReader instance; the writer is a StreamWriter instance. The arguments are all the usual arguments to Serial(). Additional optional keyword arguments are loop (to set the event loop instance to use) and limit (to set the buffer limit passed to the StreamReader. This function is a coroutine. """ if not limit: limit = asyncio.streams._DEFAULT_LIMIT # type: ignore reader = asyncio.StreamReader(limit=limit, loop=self.loop) protocol = asyncio.StreamReaderProtocol(reader, loop=self.loop) transport = SerialTransport( self.loop, protocol, self._open_mock_serial(kwargs['url'], kwargs.get("do_not_open", False))) writer = asyncio.StreamWriter(transport, protocol, reader, self.loop) return reader, writer
def __init__(self, loop, port_id, parser_factory, handler_factory, dev, baud=115200): """Class that moves bytes from a serial port to a Parser and messages to that serial port (typically from the Handler) Args: loop: asyncio event loop port_id: an ID for the port, used mostly by Handler parser_factory: Parser Class handler_factory: Handler Class dev: Serial Device baud: Serial Device baud rate """ SpheroPortBase.__init__(self, port_id, parser_factory, handler_factory) asyncio.Protocol.__init__(self) self.__loop = loop ser = serial.Serial(dev, baud) self.__transport = SerialTransport(loop, self, ser)
def dummy_serial_conn(loop, protocol_factory, url, *args, **kwargs): fut = loop.create_future() assert url == device protocol = protocol_factory() # Our event loop doesn't really do anything event_loop.add_writer = lambda *args, **kwargs: None event_loop.add_reader = lambda *args, **kwargs: None event_loop.remove_writer = lambda *args, **kwargs: None event_loop.remove_reader = lambda *args, **kwargs: None transport = SerialTransport(event_loop, protocol, serial_interface) protocol.connection_made(transport) fut.set_result((transport, protocol)) return fut
def fixed_create_serial_connection(loop, protocol_factory, *args, **kwargs): url = kwargs.pop("port") ser = serial.serial_for_url(url, *args, **kwargs) protocol = protocol_factory() transport = SerialTransport(loop, protocol, ser) return (transport, protocol)
def _create_serial_interface(self): ser = serial_for_url(self.serial_port, **SERIAL_CONFIG) self._protocol = SerialProtocol(self.cmd_que, self._process_packet) transport = SerialTransport(self._loop, self._protocol, ser) return (transport, self._protocol)
class SerialSpheroPort(SpheroPortBase, asyncio.Protocol): __slots__ = ['__loop', '__transport'] def __init__(self, loop, port_id, parser_factory, handler_factory, dev, baud=115200): """Class that moves bytes from a serial port to a Parser and messages to that serial port (typically from the Handler) Args: loop: asyncio event loop port_id: an ID for the port, used mostly by Handler parser_factory: Parser Class handler_factory: Handler Class dev: Serial Device baud: Serial Device baud rate """ SpheroPortBase.__init__(self, port_id, parser_factory, handler_factory) asyncio.Protocol.__init__(self) self.__loop = loop ser = serial.Serial(dev, baud) self.__transport = SerialTransport(loop, self, ser) def connection_made(self, transport): self.__transport = transport def connection_lost(self, exc): pass def send(self, msg): """Send a Message instance to the port Args: msg (Message): Instance of Message """ data = msg.serialise() logger.debug('Writing serial data: [{}]'.format(', '.join( '0x{:02x}'.format(x) for x in data))) self.__transport.write(data) def data_received(self, data): logger.debug('Reading serial data: [{}]'.format(', '.join( '0x{:02x}'.format(x) for x in data))) self._parser.feed(data) def pause_writing(self): pass def resume_writing(self): """Not implemented """ pass def eof_received(self): pass def close(self): self.__transport.close()
async def create_serial_connection(self, loop, protocol: Output, serial: Serial): protocol.set_handler(self.handle_read) self.transport = SerialTransport(loop, protocol, serial) return self.transport, protocol
class Robot: AUTO = ROBOT_AUTO def __init__(self, port: Port = ROBOT_AUTO, read_handler: Optional[Callable] = None): self.loop = None self.robot_thread = None self.transport = None self.read_handler = read_handler self.MODE_FREE_DRIVE = 'mode_free' self.MODE_LINE_TASK = 'mode_line' self.MODE_MICRO_ROV = 'mode_micro' self.mode = self.MODE_FREE_DRIVE self.flags = [] self.serial = self.create_serial(port) self.serial_buffer: str = '' assert self.serial is not None, "No compatible device is connected." def set_handler(self, read_handler): self.read_handler = read_handler def handle_read(self, data: str): rv = '' self.serial_buffer += data if '\n' in self.serial_buffer: arr = self.serial_buffer.splitlines() rv = arr.pop(0) self.serial_buffer = '\n'.join(arr) if self.read_handler is not None: self.read_handler(rv) async def create_serial_connection(self, loop, protocol: Output, serial: Serial): protocol.set_handler(self.handle_read) self.transport = SerialTransport(loop, protocol, serial) return self.transport, protocol def run(self): def thread_content(serial: Serial, creator: Callable): protocol = Output() try: asyncio.get_event_loop() except RuntimeError: asyncio.set_event_loop(asyncio.new_event_loop()) aio_loop = asyncio.get_event_loop() conn = creator(aio_loop, protocol, serial) aio_loop.run_until_complete(conn) aio_loop.run_forever() self.robot_thread = Thread(target=thread_content, args=(self.serial, self.create_serial_connection)) self.robot_thread.daemon = False self.robot_thread.start() def close(self): pass def write(self, data: str): if not data.endswith('\n'): data = data + '\n' if self.serial is None: raise RuntimeError # print(f'writing {data} to serial') self.transport.write(bytes(data, 'UTF-8')) @staticmethod def create_serial(port: Port = ROBOT_AUTO, baud: int = 9600) -> Optional[Serial]: """ Lists serial port names :raises EnvironmentError: On unsupported or unknown platforms :returns: A list of the serial ports available on the system """ if platform.startswith('win'): ports = ['COM%s' % (i + 1) for i in range(255)] sole_port = 'COM%s' % port elif platform.startswith('linux') or platform.startswith('cygwin'): # this excludes your current terminal "/dev/tty" ports = glob('/dev/tty[A-Za-z0-9]*') sole_port = '/dev/tty%s' % port elif platform.startswith('darwin'): ports = glob('/dev/tty.*') sole_port = '/dev/tty%s' % port else: raise EnvironmentError('Unsupported platform') if port is None: for port_instance in ports: try: s = Serial(port_instance, baud, timeout=2, writeTimeout=0) return s except (OSError, SerialException): return None else: try: s = Serial(sole_port, baud, timeout=2, writeTimeout=0) return s except (OSError, SerialException) as e: raise e