Skip to content

fix(ws_bridge): avoid WDT panics, RX poison, and incomplete HA sync - #309

Merged
eigger merged 5 commits into
masterfrom
fix/ws-bridge-wdt-rx-tx
Aug 14, 2026
Merged

fix(ws_bridge): avoid WDT panics, RX poison, and incomplete HA sync#309
eigger merged 5 commits into
masterfrom
fix/ws-bridge-wdt-rx-tx

Conversation

@eigger

@eigger eigger commented Aug 13, 2026

Copy link
Copy Markdown
Owner

Summary

  • Stop/start the websocket client on a short-lived task so force_reconnect_() cannot block the ESPHome loop long enough to trip the 5s task WDT (panic reboot).
  • Clear rx_accum_ when the event pool is exhausted and cap/drop oversized frames so a single dropped DATA event cannot poison every later HA command.
  • Keep the TX queue on send_text() lock-timeout (-1 is not always a socket abort), skip ws_bridge/sync if any declare was dropped, share one 1200ms send budget per loop(), and CAS auth state so a disconnect cannot be revived.

Test plan

  • python -m esphome compile tests/components/ws_bridge/test.esp32-idf.yaml (already passed locally)
  • Unreachable/wrong HA host: device should reconnect with backoff instead of WDT boot-looping
  • sync_entities: true with a congested link: HA must not delete entities after a dropped declare
  • TLS (Nabu Casa / reverse proxy): handshake should not stack-overflow the WS task
  • Periodic re-announce send failure should retry next interval, not every loop

Made with Cursor

eigger and others added 5 commits August 14, 2026 08:55
esp_websocket_client_stop() waits with portMAX_DELAY and can block for tens of seconds during DNS/TLS. Delegate it to a short-lived task so the 5s task WDT cannot panic-reboot the device.

Co-authored-by: Cursor <cursoragent@cursor.com>
Leaving a completed payload in rx_accum_ when allocate() fails concatenates the next frame onto it and poisons every subsequent HA command. Also ignore remaining chunks of oversized messages (WS CONT and buffer_size TEXT splits) and skip empty payloads.

Co-authored-by: Cursor <cursoragent@cursor.com>
…sync

esp_websocket_client_send_text() returns -1 on client->lock timeout without aborting the socket. Dropping the backlog there discarded live declares. If any declare is lost, skip ws_bridge/sync so Home Assistant does not delete the missing entities.

Co-authored-by: Cursor <cursoragent@cursor.com>
Multiple send_text waits of 1000ms in one loop() can approach the 5s task WDT, especially when command-event drains also send. Cap cumulative send time at 1200ms without shortening the per-send timeout that #305 needs to avoid connection abort.

Co-authored-by: Cursor <cursoragent@cursor.com>
auth_ok is processed on the main loop while CONNECTED/DISCONNECTED is stored by the WS task. An unconditional store could set CONNECTED after the socket had already dropped, leaving is_connected() true until ping timeout.

Co-authored-by: Cursor <cursoragent@cursor.com>
@eigger
eigger merged commit 0048dce into master Aug 14, 2026
3 checks passed
@eigger
eigger deleted the fix/ws-bridge-wdt-rx-tx branch August 14, 2026 00:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant