Beispiel #1
0
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)
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()
Beispiel #3
0
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