Keep UPnP event subscriptions alive when a device drops its SID - #22
Open
MarvinSchenkel wants to merge 1 commit into
Open
Keep UPnP event subscriptions alive when a device drops its SID#22MarvinSchenkel wants to merge 1 commit into
MarvinSchenkel wants to merge 1 commit into
Conversation
async_resubscribe raises a plain KeyError when the event handler no longer holds a SID for the service. It is not a UpnpError, so it escaped the renewal before the next renewal was scheduled, leaving the device without eventing and skipping the re-init that ensure_subscriptions falls back to. Subscribe from scratch when the SID is gone, and schedule the next renewal once per successful run instead of once per service.
MarvinSchenkel
marked this pull request as ready for review
August 21, 2026 09:37
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.
A device can silently stop reporting state after a subscription renewal.
UpnpEventHandler.async_resubscribe()raises a plainKeyErrorwhen the handler no longer holds a SID for the service. It documents this itself (:raise KeyError: Supplied service_or_sid is not known.), but_renew_subscriptions()only catchesUpnpError. TheKeyErrorescapes the method before the_schedule_subscription_renewal()call on the line below it ever runs.The renewal is a one-shot
loop.call_later, so nothing re-arms it. That leaves the device with no event subscription and no renewal timer, while it still reports_available = Trueand_event_handler_started = True. Live state only reaches the consumer over NOTIFY, so the player freezes on whatever it last reported.The same exception also skips the recovery. It propagates out of
ensure_subscriptions()before reaching theif not ok: await async_init_services_and_subscribe()fallback that would have re-subscribed.The caller is fire-and-forget, so it lands as an unretrieved task exception:
We hit this 52 times across 13 separate events on three devices in about a day, mostly right after an ungroup.
Changes
_renew_service_subscription(). Whensid_for_service()returnsNonethe SID is gone, so it sends a fullasync_subscribe()instead of a resubscribe that can only fail._schedule_subscription_renewal()out of the three try blocks into theif success_all:branch, so a successful run arms the next renewal once rather than once per service.I did consider just catching
KeyErroralongsideUpnpError. That stops the crash, but the next renewal raises the same thing again, and falling into the failure branch stops the notify server and waits for availability polling to recover. Checking the SID first repairs the subscription in place and the device never stops eventing.