From 7ba5f1d2f6335e2497342f8b76c6651e908e43ad Mon Sep 17 00:00:00 2001 From: Josh Roys Date: Wed, 21 Dec 2022 14:40:07 -0500 Subject: [PATCH] Reconnect if multiple CoAP PDUs go unanswered --- aiohomekit/controller/coap/connection.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/aiohomekit/controller/coap/connection.py b/aiohomekit/controller/coap/connection.py index d1b58f54f..ee2fa6b85 100644 --- a/aiohomekit/controller/coap/connection.py +++ b/aiohomekit/controller/coap/connection.py @@ -69,6 +69,7 @@ class EncryptionContext: coap_ctx: Context lock: asyncio.Lock + timeouts: int uri: str event_ctr: int @@ -88,6 +89,7 @@ def __init__(self, recv_ctx, send_ctx, event_ctx, uri, coap_ctx): self.coap_ctx = coap_ctx self.lock = asyncio.Lock() + self.timeouts = 0 self.uri = uri def decrypt(self, enc_data: bytes) -> bytes: @@ -167,12 +169,17 @@ async def post_bytes(self, payload: bytes, timeout: int = 16.0): request = Message(code=Code.POST, payload=payload, uri=self.uri) async with asyncio_timeout(timeout): response = await self.coap_ctx.request(request).response - except (NetworkError, asyncio.TimeoutError): + except (NetworkError, asyncio.TimeoutError) as e: + self.send_ctr -= 1 + self.timeouts += 1 + logger.debug(f"Network error or timeout: {e}") raise AccessoryDisconnectedError("Request timeout") if response.code != Code.CHANGED: logger.warning(f"CoAP POST returned unexpected code {response}") + self.timeouts = 0 + return await self._decrypt_response(response) async def post( @@ -396,7 +403,11 @@ async def connect(self, pairing_data): @property def is_connected(self): - return self.enc_ctx is not None and self.enc_ctx.coap_ctx is not None + return ( + self.enc_ctx is not None + and self.enc_ctx.coap_ctx is not None + and self.enc_ctx.timeouts < 3 + ) async def get_accessory_info(self): _, body = await self.enc_ctx.post(OpCode.UNK_09_READ_GATT, 0x0000, b"")