Tweak Sonos activity monitoring (#66207)

* Tweak Sonos activity monitoring

* Support new 'sleeping' vanish reason
* Check availability before last-ditch check
* Use short-timeout call for last-ditch check
* Adjust reboot logging message and severity

* Simplify activity check failure
This commit is contained in:
jjlawren 2022-02-10 14:11:47 -06:00 committed by GitHub
parent fe38e6ba87
commit e86c82e675
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -79,6 +79,7 @@ SUBSCRIPTION_SERVICES = [
"renderingControl",
"zoneGroupTopology",
]
SUPPORTED_VANISH_REASONS = ("sleeping", "upgrade")
UNAVAILABLE_VALUES = {"", "NOT_IMPLEMENTED", None}
UNUSED_DEVICE_KEYS = ["SPID", "TargetRoomName"]
@ -553,25 +554,29 @@ class SonosSpeaker:
async def async_check_activity(self, now: datetime.datetime) -> None:
"""Validate availability of the speaker based on recent activity."""
if not self.available:
return
if time.monotonic() - self._last_activity < AVAILABILITY_TIMEOUT:
return
try:
_ = await self.hass.async_add_executor_job(getattr, self.soco, "volume")
except (OSError, SoCoException):
pass
# Make a short-timeout call as a final check
# before marking this speaker as unavailable
await self.hass.async_add_executor_job(
partial(
self.soco.renderingControl.GetVolume,
[("InstanceID", 0), ("Channel", "Master")],
timeout=1,
)
)
except OSError:
_LOGGER.warning(
"No recent activity and cannot reach %s, marking unavailable",
self.zone_name,
)
await self.async_offline()
else:
self.speaker_activity("timeout poll")
return
if not self.available:
return
_LOGGER.warning(
"No recent activity and cannot reach %s, marking unavailable",
self.zone_name,
)
await self.async_offline()
async def async_offline(self) -> None:
"""Handle removal of speaker when unavailable."""
@ -603,8 +608,8 @@ class SonosSpeaker:
async def async_rebooted(self, soco: SoCo) -> None:
"""Handle a detected speaker reboot."""
_LOGGER.warning(
"%s rebooted or lost network connectivity, reconnecting with %s",
_LOGGER.debug(
"%s rebooted, reconnecting with %s",
self.zone_name,
soco,
)
@ -717,7 +722,9 @@ class SonosSpeaker:
if xml := event.variables.get("zone_group_state"):
zgs = ET.fromstring(xml)
for vanished_device in zgs.find("VanishedDevices") or []:
if (reason := vanished_device.get("Reason")) != "sleeping":
if (
reason := vanished_device.get("Reason")
) not in SUPPORTED_VANISH_REASONS:
_LOGGER.debug(
"Ignoring %s marked %s as vanished with reason: %s",
self.zone_name,