# Copyright 2022 Scott K Logan # Licensed under the Apache License, Version 2.0 from asyncio.events import AbstractEventLoop from asyncio.events import get_event_loop from typing import Optional from typing import Tuple from aioraven.device import RAVEnConnectionError from aioraven.protocols import RAVEnReaderProtocol from aioraven.reader import RAVEnReader from aioraven.streams import RAVEnStreamDevice from aioraven.streams import RAVEnWriter from serial import SerialException from serial_asyncio_fast import create_serial_connection async def open_serial_connection( url: str, *args: int, loop: Optional[AbstractEventLoop] = None, **kwargs: int, ) -> Tuple[RAVEnReader, RAVEnWriter]: """ Establish a serial connection to a RAVEn device. Positional and keyword arguments are passed to `serial_asyncio_fast.create_serial_connection()`. :param loop: The event loop instance to use. """ if loop is None: loop = get_event_loop() reader = RAVEnReader(loop=loop) protocol = RAVEnReaderProtocol(reader, loop=loop) kwargs.setdefault('baudrate', 115200) try: transport, _ = await create_serial_connection( loop, lambda: protocol, url, *args, **kwargs) except SerialException as ex: raise RAVEnConnectionError(f'{ex}') from ex writer = RAVEnWriter(transport, protocol) return reader, writer class RAVEnSerialDevice(RAVEnStreamDevice): """A serial-connected RAVEn device.""" def __init__( self, url: str, *args: int, loop: Optional[AbstractEventLoop] = None, **kwargs: int ) -> None: """ Construct a RAVEnSerialDevice. Additional positional and keyword arguments are passed to `serial_asyncio_fast.create_serial_connection()`. :param url: The pyserial URL of the device to connect to. :param loop: The event loop instance to use. """ self._url = url self._args = args self._loop = loop self._kwargs = kwargs def __repr__(self) -> str: info = [self.__class__.__name__] info.append('url=%s' % self._url) return '<%s>' % ' '.join(info) async def open(self) -> None: """Open the connection to the RAVEn device.""" if self._reader or self._writer: return self._reader, self._writer = await open_serial_connection( self._url, *self._args, loop=self._loop, **self._kwargs)