Reduce Spotify API usage (#66315)

This commit is contained in:
Franck Nijhof 2022-02-11 22:16:41 +01:00 committed by GitHub
parent 2e6ee5165e
commit caedef5f1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 8 deletions

View File

@ -1,6 +1,11 @@
"""The spotify integration."""
from __future__ import annotations
from datetime import timedelta
from typing import Any
import aiohttp
import requests
from spotipy import Spotify, SpotifyException
import voluptuous as vol
@ -20,13 +25,16 @@ from homeassistant.helpers.config_entry_oauth2_flow import (
async_get_config_entry_implementation,
)
from homeassistant.helpers.typing import ConfigType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from . import config_flow
from .const import (
DATA_SPOTIFY_CLIENT,
DATA_SPOTIFY_DEVICES,
DATA_SPOTIFY_ME,
DATA_SPOTIFY_SESSION,
DOMAIN,
LOGGER,
MEDIA_PLAYER_PREFIX,
SPOTIFY_SCOPES,
)
@ -112,9 +120,34 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except SpotifyException as err:
raise ConfigEntryNotReady from err
async def _update_devices() -> list[dict[str, Any]]:
try:
devices: dict[str, Any] | None = await hass.async_add_executor_job(
spotify.devices
)
except (requests.RequestException, SpotifyException) as err:
raise UpdateFailed from err
if devices is None:
return []
return devices.get("devices", [])
device_coordinator: DataUpdateCoordinator[
list[dict[str, Any]]
] = DataUpdateCoordinator(
hass,
LOGGER,
name=f"{entry.title} Devices",
update_interval=timedelta(minutes=5),
update_method=_update_devices,
)
await device_coordinator.async_config_entry_first_refresh()
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = {
DATA_SPOTIFY_CLIENT: spotify,
DATA_SPOTIFY_DEVICES: device_coordinator,
DATA_SPOTIFY_ME: current_user,
DATA_SPOTIFY_SESSION: session,
}

View File

@ -1,8 +1,13 @@
"""Define constants for the Spotify integration."""
import logging
DOMAIN = "spotify"
LOGGER = logging.getLogger(__package__)
DATA_SPOTIFY_CLIENT = "spotify_client"
DATA_SPOTIFY_DEVICES = "spotify_devices"
DATA_SPOTIFY_ME = "spotify_me"
DATA_SPOTIFY_SESSION = "spotify_session"

View File

@ -52,7 +52,7 @@ from homeassistant.const import (
STATE_PAUSED,
STATE_PLAYING,
)
from homeassistant.core import HomeAssistant
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.config_entry_oauth2_flow import OAuth2Session
from homeassistant.helpers.device_registry import DeviceEntryType
@ -62,6 +62,7 @@ from homeassistant.util.dt import utc_from_timestamp
from .const import (
DATA_SPOTIFY_CLIENT,
DATA_SPOTIFY_DEVICES,
DATA_SPOTIFY_ME,
DATA_SPOTIFY_SESSION,
DOMAIN,
@ -269,7 +270,6 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
)
self._currently_playing: dict | None = {}
self._devices: list[dict] | None = []
self._playlist: dict | None = None
self._attr_name = self._name
@ -290,6 +290,11 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
"""Return spotify API."""
return self._spotify_data[DATA_SPOTIFY_CLIENT]
@property
def _devices(self) -> list:
"""Return spotify devices."""
return self._spotify_data[DATA_SPOTIFY_DEVICES].data
@property
def device_info(self) -> DeviceInfo:
"""Return device information about this entity."""
@ -517,13 +522,13 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
current = self._spotify.current_playback()
self._currently_playing = current or {}
self._playlist = None
context = self._currently_playing.get("context")
if context is not None and context["type"] == MEDIA_TYPE_PLAYLIST:
self._playlist = self._spotify.playlist(current["context"]["uri"])
devices = self._spotify.devices() or {}
self._devices = devices.get("devices", [])
if context is not None and (
self._playlist is None or self._playlist["uri"] != context["uri"]
):
self._playlist = None
if context["type"] == MEDIA_TYPE_PLAYLIST:
self._playlist = self._spotify.playlist(current["context"]["uri"])
async def async_browse_media(self, media_content_type=None, media_content_id=None):
"""Implement the websocket media browsing helper."""
@ -543,6 +548,22 @@ class SpotifyMediaPlayer(MediaPlayerEntity):
media_content_id,
)
@callback
def _handle_devices_update(self) -> None:
"""Handle updated data from the coordinator."""
if not self.enabled:
return
self.async_write_ha_state()
async def async_added_to_hass(self) -> None:
"""When entity is added to hass."""
await super().async_added_to_hass()
self.async_on_remove(
self._spotify_data[DATA_SPOTIFY_DEVICES].async_add_listener(
self._handle_devices_update
)
)
async def async_browse_media_internal(
hass,