Skip to content

Refresh device state after auto-reconnect#18

Merged
SteveEasley merged 1 commit intoSteveEasley:mainfrom
robotdan:fix/refresh-after-reconnect
Apr 5, 2026
Merged

Refresh device state after auto-reconnect#18
SteveEasley merged 1 commit intoSteveEasley:mainfrom
robotdan:fix/refresh-after-reconnect

Conversation

@robotdan
Copy link
Copy Markdown
Contributor

@robotdan robotdan commented Apr 2, 2026

Problem

After a successful auto-reconnect, the library re-establishes the socket and dispatches STATE_CONNECTED, but the Device dataclasses (power, movie, OSD, play status, etc.) still hold stale values from before the disconnect. Every consumer must independently subscribe to STATE_CONNECTED, call device.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_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 reconnect. The callback is awaited before STATE_CONNECTED is 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 their STATE_CONNECTED handler would get a harmless redundant refresh, and can simplify their code over time.

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.
Copy link
Copy Markdown
Owner

@SteveEasley SteveEasley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@SteveEasley SteveEasley merged commit 61b2b9f into SteveEasley:main Apr 5, 2026
4 checks passed
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>
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.

2 participants