Titre :
Event stream can hang silently forever - missing socket read timeout in stream_events
Corps :
Describe the bug
stream_events in client.py opens the long-poll connection to eventManager.cgi (action=attach&codes=[...]) without any read timeout on the request. If the camera's event stream stops delivering real events but keeps the TCP connection alive (for example only sending the requested heartbeat pulses, or just going quiet without closing the socket), the request never raises an exception, so the reconnect logic in _async_stream_events (which only restarts the loop on an exception) never fires. The result: dahua_event_received stops firing entirely, silently, with nothing in the logs, until Home Assistant or the integration entry is manually reloaded.
We reproduced this in production on a Dahua DH-IPC-HDW5859TM-ASE-IL (firmware V3.146.0000000.8.R) - the camera was confirmed, via a separate raw eventManager.cgi capture and the camera's own HTTP trigger webhook, to be actively emitting CrossRegionDetection events, while the corresponding binary_sensor in HA had been frozen for over an hour with no errors logged.
To Reproduce
Hard to reproduce on demand since it depends on camera/network behavior, but we validated the failure mode with a mock server (aiohttp) that sends heartbeats every 5 seconds then goes silent without closing the connection. The unpatched integration stays stuck indefinitely; a version with a socket read timeout set on the request times out and reconnects as expected.
Suggested fix
In client.py, inside stream_events, add a read timeout to the request call, something like this:
timeout = aiohttp.ClientTimeout(sock_read=60, total=None)
response = await auth.request("GET", url, timeout=timeout)
60 seconds comfortably exceeds the default heartbeat interval so it never fires during normal operation, but it reliably catches a stalled connection.
As an extra safety net, the stream loop in init.py could also be restarted periodically (e.g. every 4 hours) using asyncio.wait_for around the stream_events call, letting the existing reconnect logic kick back in. That guards against any other kind of "zombie" state at the cost of a sub-second reconnect every few hours.
Environment
Integration version: please fill in your installed HACS version
Home Assistant: 2026.6.0
Camera models affected: Dahua WizMind IPC-HDW5442TM-ASE-0280B-S3 and DH-IPC-HDW5859TM-ASE-IL
Happy to open a PR with this change if useful.
Titre :
Event stream can hang silently forever - missing socket read timeout in stream_events
Corps :
Describe the bug
stream_events in client.py opens the long-poll connection to eventManager.cgi (action=attach&codes=[...]) without any read timeout on the request. If the camera's event stream stops delivering real events but keeps the TCP connection alive (for example only sending the requested heartbeat pulses, or just going quiet without closing the socket), the request never raises an exception, so the reconnect logic in _async_stream_events (which only restarts the loop on an exception) never fires. The result: dahua_event_received stops firing entirely, silently, with nothing in the logs, until Home Assistant or the integration entry is manually reloaded.
We reproduced this in production on a Dahua DH-IPC-HDW5859TM-ASE-IL (firmware V3.146.0000000.8.R) - the camera was confirmed, via a separate raw eventManager.cgi capture and the camera's own HTTP trigger webhook, to be actively emitting CrossRegionDetection events, while the corresponding binary_sensor in HA had been frozen for over an hour with no errors logged.
To Reproduce
Hard to reproduce on demand since it depends on camera/network behavior, but we validated the failure mode with a mock server (aiohttp) that sends heartbeats every 5 seconds then goes silent without closing the connection. The unpatched integration stays stuck indefinitely; a version with a socket read timeout set on the request times out and reconnects as expected.
Suggested fix
In client.py, inside stream_events, add a read timeout to the request call, something like this:
timeout = aiohttp.ClientTimeout(sock_read=60, total=None)
response = await auth.request("GET", url, timeout=timeout)
60 seconds comfortably exceeds the default heartbeat interval so it never fires during normal operation, but it reliably catches a stalled connection.
As an extra safety net, the stream loop in init.py could also be restarted periodically (e.g. every 4 hours) using asyncio.wait_for around the stream_events call, letting the existing reconnect logic kick back in. That guards against any other kind of "zombie" state at the cost of a sub-second reconnect every few hours.
Environment
Integration version: please fill in your installed HACS version
Home Assistant: 2026.6.0
Camera models affected: Dahua WizMind IPC-HDW5442TM-ASE-0280B-S3 and DH-IPC-HDW5859TM-ASE-IL
Happy to open a PR with this change if useful.