Improve Sonos diagnostics (#64586)

This commit is contained in:
jjlawren 2022-01-20 17:14:08 -06:00 committed by GitHub
parent 3792b8b3ca
commit e7f0962979
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 25 deletions

View File

@ -21,20 +21,24 @@ MEDIA_DIAGNOSTIC_ATTRIBUTES = (
"source_name",
"title",
"uri",
"_last_event_variables",
)
SPEAKER_DIAGNOSTIC_ATTRIBUTES = (
"available",
"battery_info",
"hardware_version",
"household_id",
"is_coordinator",
"model_name",
"model_number",
"software_version",
"sonos_group_entities",
"subscription_address",
"subscriptions_failed",
"version",
"zone_name",
"_group_members_missing",
"_last_activity",
"_last_event_cache",
)
@ -52,8 +56,7 @@ async def async_get_config_entry_diagnostics(
continue
for key, value in data.items():
if isinstance(value, SonosSpeaker):
speaker_info = await async_generate_speaker_info(hass, value)
payload[section][key] = speaker_info
payload[section][key] = await async_generate_speaker_info(hass, value)
else:
payload[section][key] = value
@ -66,21 +69,8 @@ async def async_generate_media_info(
"""Generate a diagnostic payload for current media metadata."""
payload = {}
def get_contents(item):
if isinstance(item, (int, float, str)):
return item
if isinstance(item, dict):
payload = {}
for key, value in item.items():
payload[key] = get_contents(value)
return payload
if hasattr(item, "__dict__"):
return vars(item)
return item
for attrib in MEDIA_DIAGNOSTIC_ATTRIBUTES:
value = getattr(speaker.media, attrib)
payload[attrib] = get_contents(value)
payload[attrib] = getattr(speaker.media, attrib)
def poll_current_track_info():
return speaker.soco.avTransport.GetPositionInfo(
@ -99,7 +89,22 @@ async def async_generate_speaker_info(
) -> dict[str, Any]:
"""Generate the diagnostic payload for a specific speaker."""
payload = {}
def get_contents(item):
if isinstance(item, (int, float, str)):
return item
if isinstance(item, dict):
payload = {}
for key, value in item.items():
payload[key] = get_contents(value)
return payload
if hasattr(item, "__dict__"):
return vars(item)
return item
for attrib in SPEAKER_DIAGNOSTIC_ATTRIBUTES:
payload[attrib] = getattr(speaker, attrib)
value = getattr(speaker, attrib)
payload[attrib] = get_contents(value)
payload["media"] = await async_generate_media_info(hass, speaker)
return payload

View File

@ -123,7 +123,6 @@ class SonosMedia:
self.position: float | None = None
self.position_updated_at: datetime.datetime | None = None
self._last_event_variables: dict[str, Any] | None = None
def clear(self) -> None:
"""Clear basic media info."""
@ -164,6 +163,7 @@ class SonosSpeaker:
self._resubscription_lock: asyncio.Lock | None = None
self._event_dispatchers: dict[str, Callable] = {}
self._last_activity: float = NEVER_TIME
self._last_event_cache: dict[str, Any] = {}
# Scheduled callback handles
self._poll_timer: Callable | None = None
@ -172,8 +172,11 @@ class SonosSpeaker:
self.dispatchers: list[Callable] = []
# Device information
self.hardware_version = speaker_info["hardware_version"]
self.software_version = speaker_info["software_version"]
self.mac_address = speaker_info["mac_address"]
self.model_name = speaker_info["model_name"]
self.model_number = speaker_info["model_number"]
self.uid = speaker_info["uid"]
self.version = speaker_info["display_version"]
self.zone_name = speaker_info["zone_name"]
@ -427,6 +430,9 @@ class SonosSpeaker:
dispatcher = self._event_dispatchers[event.service.service_type]
dispatcher(event)
# Save most recent event variables for diagnostics
self._last_event_cache[event.service.service_type] = event.variables
@callback
def async_dispatch_alarms(self, event: SonosEvent) -> None:
"""Add the soco instance associated with the event to the callback."""
@ -1003,12 +1009,6 @@ class SonosSpeaker:
if new_status == SONOS_STATE_TRANSITIONING:
return
if variables:
# Store for diagnostics
self.media._last_event_variables = ( # pylint: disable=protected-access
variables
)
self.media.clear()
update_position = new_status != self.media.playback_status
self.media.playback_status = new_status

View File

@ -206,6 +206,8 @@ def speaker_info_fixture():
"zone_name": "Zone A",
"uid": "RINCON_test",
"model_name": "Model Name",
"model_number": "S12",
"hardware_version": "1.20.1.6-1.1",
"software_version": "49.2-64250",
"mac_address": "00-11-22-33-44-55",
"display_version": "13.1",