1 """Provides diagnostics for Sonos."""
3 from __future__
import annotations
12 from .const
import DATA_SONOS, DOMAIN
13 from .speaker
import SonosSpeaker
15 MEDIA_DIAGNOSTIC_ATTRIBUTES = (
27 SPEAKER_DIAGNOSTIC_ATTRIBUTES = (
36 "sonos_group_entities",
37 "subscription_address",
38 "subscriptions_failed",
41 "_group_members_missing",
48 hass: HomeAssistant, config_entry: ConfigEntry
50 """Return diagnostics for a config entry."""
51 payload: dict[str, Any] = {
"current_timestamp": time.monotonic()}
53 for section
in (
"discovered",
"discovery_known"):
55 data: set[Any] | dict[str, Any] = getattr(hass.data[DATA_SONOS], section)
56 if isinstance(data, set):
57 payload[section] = data
59 for key, value
in data.items():
60 if isinstance(value, SonosSpeaker):
63 payload[section][key] = value
68 hass: HomeAssistant, config_entry: ConfigEntry, device: DeviceEntry
70 """Return diagnostics for a device."""
72 (identifier[1]
for identifier
in device.identifiers
if identifier[0] == DOMAIN),
78 if (speaker := hass.data[DATA_SONOS].discovered.get(uid))
is None:
85 hass: HomeAssistant, speaker: SonosSpeaker
87 """Generate a diagnostic payload for current media metadata."""
88 payload: dict[str, Any] = {}
90 for attrib
in MEDIA_DIAGNOSTIC_ATTRIBUTES:
91 payload[attrib] = getattr(speaker.media, attrib)
93 def poll_current_track_info() -> dict[str, Any] | str:
95 return speaker.soco.avTransport.GetPositionInfo(
96 [(
"InstanceID", 0), (
"Channel",
"Master")],
100 return f
"Error retrieving: {ex}"
102 payload[
"current_track_poll"] = await hass.async_add_executor_job(
103 poll_current_track_info
110 hass: HomeAssistant, speaker: SonosSpeaker
112 """Generate the diagnostic payload for a specific speaker."""
113 payload: dict[str, Any] = {}
116 item: float | str | dict[str, Any],
117 ) -> int | float | str | dict[str, Any]:
118 if isinstance(item, (int, float, str)):
120 if isinstance(item, dict):
122 for key, value
in item.items():
123 payload[key] = get_contents(value)
125 if hasattr(item,
"__dict__"):
129 for attrib
in SPEAKER_DIAGNOSTIC_ATTRIBUTES:
130 value = getattr(speaker, attrib)
131 payload[attrib] = get_contents(value)
133 payload[
"enabled_entities"] = {
135 for entity_id, s
in hass.data[DATA_SONOS].entity_id_mappings.items()
139 payload[
"activity_stats"] = speaker.activity_stats.report()
140 payload[
"event_stats"] = speaker.event_stats.report()
141 payload[
"zone_group_state_stats"] = {
142 "processed": speaker.soco.zone_group_state.processed_count,
143 "total_requests": speaker.soco.zone_group_state.total_requests,
dict[str, Any] async_generate_speaker_info(HomeAssistant hass, SonosSpeaker speaker)
dict[str, Any] async_get_config_entry_diagnostics(HomeAssistant hass, ConfigEntry config_entry)
dict[str, Any] async_get_device_diagnostics(HomeAssistant hass, ConfigEntry config_entry, DeviceEntry device)
dict[str, Any] async_generate_media_info(HomeAssistant hass, SonosSpeaker speaker)