1
mirror of https://github.com/home-assistant/core synced 2024-09-06 10:29:55 +02:00

Add activity statistics to Sonos diagnostics (#65214)

This commit is contained in:
jjlawren 2022-01-30 15:15:51 -06:00 committed by GitHub
parent 78ad49325d
commit 2129972904
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 12 deletions

View File

@ -193,6 +193,7 @@ class SonosDiscoveryManager:
async def _async_stop_event_listener(self, event: Event | None = None) -> None:
for speaker in self.data.discovered.values():
speaker.activity_stats.log_report()
speaker.event_stats.log_report()
await asyncio.gather(
*(speaker.async_offline() for speaker in self.data.discovered.values())

View File

@ -130,5 +130,6 @@ async def async_generate_speaker_info(
if s is speaker
}
payload["media"] = await async_generate_media_info(hass, speaker)
payload["activity_stats"] = speaker.activity_stats.report()
payload["event_stats"] = speaker.event_stats.report()
return payload

View File

@ -62,7 +62,7 @@ from .const import (
)
from .favorites import SonosFavorites
from .helpers import soco_error
from .statistics import EventStatistics
from .statistics import ActivityStatistics, EventStatistics
NEVER_TIME = -1200.0
EVENT_CHARGING = {
@ -177,6 +177,7 @@ class SonosSpeaker:
self._event_dispatchers: dict[str, Callable] = {}
self._last_activity: float = NEVER_TIME
self._last_event_cache: dict[str, Any] = {}
self.activity_stats: ActivityStatistics = ActivityStatistics(self.zone_name)
self.event_stats: EventStatistics = EventStatistics(self.zone_name)
# Scheduled callback handles
@ -528,6 +529,7 @@ class SonosSpeaker:
"""Track the last activity on this speaker, set availability and resubscribe."""
_LOGGER.debug("Activity on %s from %s", self.zone_name, source)
self._last_activity = time.monotonic()
self.activity_stats.activity(source, self._last_activity)
was_available = self.available
self.available = True
if not was_available:

View File

@ -9,13 +9,49 @@ from soco.events_base import Event as SonosEvent, parse_event_xml
_LOGGER = logging.getLogger(__name__)
class EventStatistics:
class SonosStatistics:
"""Base class of Sonos statistics."""
def __init__(self, zone_name: str, kind: str) -> None:
"""Initialize SonosStatistics."""
self._stats = {}
self._stat_type = kind
self.zone_name = zone_name
def report(self) -> dict:
"""Generate a report for use in diagnostics."""
return self._stats.copy()
def log_report(self) -> None:
"""Log statistics for this speaker."""
_LOGGER.debug(
"%s statistics for %s: %s",
self._stat_type,
self.zone_name,
self.report(),
)
class ActivityStatistics(SonosStatistics):
"""Representation of Sonos activity statistics."""
def __init__(self, zone_name: str) -> None:
"""Initialize ActivityStatistics."""
super().__init__(zone_name, "Activity")
def activity(self, source: str, timestamp: float) -> None:
"""Track an activity occurrence."""
activity_entry = self._stats.setdefault(source, {"count": 0})
activity_entry["count"] += 1
activity_entry["last_seen"] = timestamp
class EventStatistics(SonosStatistics):
"""Representation of Sonos event statistics."""
def __init__(self, zone_name: str) -> None:
"""Initialize EventStatistics."""
self._stats = {}
self.zone_name = zone_name
super().__init__(zone_name, "Event")
def receive(self, event: SonosEvent) -> None:
"""Mark a received event by subscription type."""
@ -38,11 +74,3 @@ class EventStatistics:
payload["soco:from_didl_string"] = from_didl_string.cache_info()
payload["soco:parse_event_xml"] = parse_event_xml.cache_info()
return payload
def log_report(self) -> None:
"""Log event statistics for this speaker."""
_LOGGER.debug(
"Event statistics for %s: %s",
self.zone_name,
self.report(),
)