diff --git a/homeassistant/components/sonos/const.py b/homeassistant/components/sonos/const.py index 9aaecee08af..e14024c32d2 100644 --- a/homeassistant/components/sonos/const.py +++ b/homeassistant/components/sonos/const.py @@ -147,3 +147,4 @@ BATTERY_SCAN_INTERVAL = datetime.timedelta(minutes=15) SCAN_INTERVAL = datetime.timedelta(seconds=10) DISCOVERY_INTERVAL = datetime.timedelta(seconds=60) SEEN_EXPIRE_TIME = 3.5 * DISCOVERY_INTERVAL +SUBSCRIPTION_TIMEOUT = 1200 diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 0c2b28dbdf2..e647fc2fd68 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -48,6 +48,7 @@ from .const import ( SONOS_STATE_UPDATED, SOURCE_LINEIN, SOURCE_TV, + SUBSCRIPTION_TIMEOUT, ) from .favorites import SonosFavorites from .helpers import soco_error @@ -251,8 +252,11 @@ class SonosSpeaker: self, target: SubscriptionBase, sub_callback: Callable ) -> None: """Create a Sonos subscription.""" - subscription = await target.subscribe(auto_renew=True) + subscription = await target.subscribe( + auto_renew=True, requested_timeout=SUBSCRIPTION_TIMEOUT + ) subscription.callback = sub_callback + subscription.auto_renew_fail = self.async_renew_failed self._subscriptions.append(subscription) @callback @@ -309,11 +313,19 @@ class SonosSpeaker: self.async_write_entity_states() + @callback + def async_renew_failed(self, exception: Exception) -> None: + """Handle a failed subscription renewal.""" + if self.available: + self.hass.async_add_job(self.async_unseen) + async def async_unseen(self, now: datetime.datetime | None = None) -> None: """Make this player unavailable when it was not seen recently.""" self.async_write_entity_states() - self._seen_timer = None + if self._seen_timer: + self._seen_timer() + self._seen_timer = None if self._poll_timer: self._poll_timer()