From 7e68cd4484c2e5ed7cf13e2615d721026327640f Mon Sep 17 00:00:00 2001 From: Richard Maher Date: Wed, 22 Oct 2025 06:24:54 -0700 Subject: [PATCH] Fix event stream disconnections with heartbeat monitoring Set 1-hour timeout instead of default 5-minute timeout on event stream request. Implement 15-second heartbeat monitoring with asyncio.wait_for() to detect and recover from camera restarts and network issues. --- custom_components/dahua/client.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/custom_components/dahua/client.py b/custom_components/dahua/client.py index 4165b56..bd0ddce 100644 --- a/custom_components/dahua/client.py +++ b/custom_components/dahua/client.py @@ -763,12 +763,32 @@ async def stream_events(self, on_receive, events: list, channel: int): try: auth = DigestAuth(self._username, self._password, self._session) - response = await auth.request("GET", url) + response = await auth.request("GET", url, timeout=aiohttp.ClientTimeout(total=3600)) response.raise_for_status() # https://docs.aiohttp.org/en/stable/streams.html - async for data, _ in response.content.iter_chunks(): - on_receive(data, channel) + # Monitor heartbeat - timeout if no data for 15 seconds (3x heartbeat interval) + chunk_iterator = response.content.iter_chunks() + + while True: + try: + # Wait for next chunk with 15-second timeout + data, _ = await asyncio.wait_for( + chunk_iterator.__anext__(), + timeout=15.0 + ) + + on_receive(data, channel) + + except asyncio.TimeoutError: + _LOGGER.debug("No data received for 15+ seconds, reconnecting...") + raise + except StopAsyncIteration: + break + + except asyncio.TimeoutError: + # Re-raise to trigger reconnection in thread.py + raise except Exception as exception: pass finally: