Refresh device state after auto-reconnect#18
Merged
SteveEasley merged 1 commit intoSteveEasley:mainfrom Apr 5, 2026
Merged
Conversation
Add an on_reconnect callback to Connection, following the existing on_event pattern. Device uses this callback to re-fetch power/readiness state and call refresh() after a successful auto-reconnect, so consumers see fresh state when they handle the STATE_CONNECTED signal.
robotdan
added a commit
to robotdan/pykaleidescape
that referenced
this pull request
May 6, 2026
The two tests added in PR SteveEasley#18 omitted the standard `await asyncio.sleep(0.1)` between the initial `connect()` and `emulator.stop()`. Without that pause, the emulator's `_handle_client` callback hasn't registered the new client yet, so `emulator.stop()` finds an empty `_clients` list, doesn't disconnect anything, and the test client never sees EOF. STATE_DISCONNECTED is never dispatched and `disconnect_signal.wait()` hangs. Match the existing pattern from `test_reconnect_during_event` and `test_reconnect_cancelled` (both use the same sleep for the same reason). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SteveEasley
pushed a commit
that referenced
this pull request
May 6, 2026
PR #18 (Refresh device state after auto-reconnect) added two tests that wait on `connect_signal` (STATE_CONNECTED) after the initial connect. PR #19 (Dispatch STATE_CONNECTED only on auto-reconnect) then moved the STATE_CONNECTED dispatch out of `_connect()` and into `_reconnect()`. PR #19 updated other tests with the same pattern, but #19 was opened before #18 merged, so the two tests added by #18 weren't updated. Result: `await connect_signal.wait()` after initial connect waits forever, hanging CI for the full 6h job timeout. Every CI run on main since #18 has been cancelled this way (#19, #20, #21, v1.1.6, #22). Match the pattern used by other tests updated in #19: assert `state == STATE_CONNECTED` directly after the initial connect, and keep `connect_signal.wait()` only for the post-reconnect signal where STATE_CONNECTED is actually dispatched. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
After a successful auto-reconnect, the library re-establishes the socket and dispatches
STATE_CONNECTED, but theDevicedataclasses (power, movie, OSD, play status, etc.) still hold stale values from before the disconnect. Every consumer must independently subscribe toSTATE_CONNECTED, calldevice.refresh(), and handle exceptions.In practice, the Home Assistant kaleidescape integration does not call
refresh()after reconnect, meaning entities display stale data until the next device-initiated event happens to update them.Fix
Add an
on_reconnectcallback toConnection, following the existingon_eventpattern.Deviceuses this callback to re-fetch power/readiness state and callrefresh()after a successful reconnect. The callback is awaited beforeSTATE_CONNECTEDis dispatched — so consumers see fresh state when they handle the signal.This is non-breaking: existing consumers continue to work unchanged. Those that already call
refresh()in theirSTATE_CONNECTEDhandler would get a harmless redundant refresh, and can simplify their code over time.