|
1 | 1 | """Uart module.""" |
2 | 2 |
|
| 3 | +from __future__ import annotations |
| 4 | + |
3 | 5 | import asyncio |
4 | 6 | import binascii |
5 | 7 | import logging |
6 | | -from typing import Callable, Dict |
| 8 | +from typing import Any, Callable |
7 | 9 |
|
8 | 10 | import zigpy.config |
9 | 11 | import zigpy.serial |
10 | 12 |
|
11 | 13 | LOGGER = logging.getLogger(__name__) |
12 | 14 |
|
13 | 15 |
|
14 | | -class Gateway(asyncio.Protocol): |
| 16 | +class Gateway(zigpy.serial.SerialProtocol): |
15 | 17 | END = b"\xC0" |
16 | 18 | ESC = b"\xDB" |
17 | 19 | ESC_END = b"\xDC" |
18 | 20 | ESC_ESC = b"\xDD" |
19 | 21 |
|
20 | | - def __init__(self, api, connected_future=None): |
| 22 | + def __init__(self, api): |
21 | 23 | """Initialize instance of the UART gateway.""" |
22 | | - |
| 24 | + super().__init__() |
23 | 25 | self._api = api |
24 | | - self._buffer = b"" |
25 | | - self._connected_future = connected_future |
26 | | - self._transport = None |
27 | 26 |
|
28 | | - def connection_lost(self, exc) -> None: |
| 27 | + def connection_lost(self, exc: Exception | None) -> None: |
29 | 28 | """Port was closed expectedly or unexpectedly.""" |
| 29 | + super().connection_lost(exc) |
30 | 30 |
|
31 | | - if exc is not None: |
32 | | - LOGGER.warning("Lost connection: %r", exc, exc_info=exc) |
33 | | - |
34 | | - self._api.connection_lost(exc) |
35 | | - |
36 | | - def connection_made(self, transport): |
37 | | - """Call this when the uart connection is established.""" |
38 | | - |
39 | | - LOGGER.debug("Connection made") |
40 | | - self._transport = transport |
41 | | - if self._connected_future and not self._connected_future.done(): |
42 | | - self._connected_future.set_result(True) |
| 31 | + if self._api is not None: |
| 32 | + self._api.connection_lost(exc) |
43 | 33 |
|
44 | 34 | def close(self): |
45 | | - self._transport.close() |
| 35 | + super().close() |
| 36 | + self._api = None |
46 | 37 |
|
47 | | - def send(self, data): |
| 38 | + def send(self, data: bytes) -> None: |
48 | 39 | """Send data, taking care of escaping and framing.""" |
49 | | - LOGGER.debug("Send: %s", binascii.hexlify(data).decode()) |
50 | 40 | checksum = bytes(self._checksum(data)) |
51 | 41 | frame = self._escape(data + checksum) |
52 | 42 | self._transport.write(self.END + frame + self.END) |
53 | 43 |
|
54 | | - def data_received(self, data): |
| 44 | + def data_received(self, data: bytes) -> None: |
55 | 45 | """Handle data received from the uart.""" |
56 | | - self._buffer += data |
| 46 | + super().data_received(data) |
| 47 | + |
57 | 48 | while self._buffer: |
58 | 49 | end = self._buffer.find(self.END) |
59 | 50 | if end < 0: |
@@ -121,23 +112,19 @@ def _checksum(self, data): |
121 | 112 | return bytes(ret) |
122 | 113 |
|
123 | 114 |
|
124 | | -async def connect(config: Dict[str, any], api: Callable) -> Gateway: |
125 | | - loop = asyncio.get_running_loop() |
126 | | - connected_future = loop.create_future() |
127 | | - protocol = Gateway(api, connected_future) |
| 115 | +async def connect(config: dict[str, Any], api: Callable) -> Gateway: |
| 116 | + protocol = Gateway(api) |
128 | 117 |
|
129 | 118 | LOGGER.debug("Connecting to %s", config[zigpy.config.CONF_DEVICE_PATH]) |
130 | 119 |
|
131 | 120 | _, protocol = await zigpy.serial.create_serial_connection( |
132 | | - loop=loop, |
| 121 | + loop=asyncio.get_running_loop(), |
133 | 122 | protocol_factory=lambda: protocol, |
134 | 123 | url=config[zigpy.config.CONF_DEVICE_PATH], |
135 | 124 | baudrate=config[zigpy.config.CONF_DEVICE_BAUDRATE], |
136 | | - xonxoff=False, |
| 125 | + flow_control=config[zigpy.config.CONF_DEVICE_FLOW_CONTROL], |
137 | 126 | ) |
138 | 127 |
|
139 | | - await connected_future |
140 | | - |
141 | | - LOGGER.debug("Connected to %s", config[zigpy.config.CONF_DEVICE_PATH]) |
| 128 | + await protocol.wait_until_connected() |
142 | 129 |
|
143 | 130 | return protocol |
0 commit comments