Skip to content

Commit 36c2404

Browse files
joostlekCFenner
andauthored
Add base entity to Spotify (#128847)
Co-authored-by: Christopher Fenner <[email protected]>
1 parent ba673be commit 36c2404

File tree

6 files changed

+49
-52
lines changed

6 files changed

+49
-52
lines changed

homeassistant/components/spotify/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from .browse_media import async_browse_media
2323
from .const import DOMAIN, LOGGER, SPOTIFY_SCOPES
24-
from .coordinator import SpotifyCoordinator
24+
from .coordinator import SpotifyConfigEntry, SpotifyCoordinator
2525
from .models import SpotifyData
2626
from .util import (
2727
is_spotify_media_type,
@@ -40,9 +40,6 @@
4040
]
4141

4242

43-
type SpotifyConfigEntry = ConfigEntry[SpotifyData]
44-
45-
4643
async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> bool:
4744
"""Set up Spotify from a config entry."""
4845
implementation = await async_get_config_entry_implementation(hass, entry)

homeassistant/components/spotify/coordinator.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from dataclasses import dataclass
44
from datetime import datetime, timedelta
55
import logging
6+
from typing import TYPE_CHECKING
67

78
from spotifyaio import (
89
ContextType,
@@ -15,15 +16,22 @@
1516
)
1617
from spotifyaio.models import AudioFeatures
1718

19+
from homeassistant.config_entries import ConfigEntry
1820
from homeassistant.core import HomeAssistant
1921
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
2022
import homeassistant.util.dt as dt_util
2123

2224
from .const import DOMAIN
2325

26+
if TYPE_CHECKING:
27+
from .models import SpotifyData
28+
2429
_LOGGER = logging.getLogger(__name__)
2530

2631

32+
type SpotifyConfigEntry = ConfigEntry[SpotifyData]
33+
34+
2735
@dataclass
2836
class SpotifyCoordinatorData:
2937
"""Class to hold Spotify data."""
@@ -45,6 +53,7 @@ class SpotifyCoordinator(DataUpdateCoordinator[SpotifyCoordinatorData]):
4553
"""Class to manage fetching Spotify data."""
4654

4755
current_user: UserProfile
56+
config_entry: SpotifyConfigEntry
4857

4958
def __init__(self, hass: HomeAssistant, client: SpotifyClient) -> None:
5059
"""Initialize."""

homeassistant/components/spotify/diagnostics.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from homeassistant.core import HomeAssistant
99

10-
from . import SpotifyConfigEntry
10+
from .coordinator import SpotifyConfigEntry
1111

1212

1313
async def async_get_config_entry_diagnostics(
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"""Base entity for Spotify."""
2+
3+
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
4+
from homeassistant.helpers.update_coordinator import CoordinatorEntity
5+
6+
from .const import DOMAIN
7+
from .coordinator import SpotifyCoordinator
8+
9+
10+
class SpotifyEntity(CoordinatorEntity[SpotifyCoordinator]):
11+
"""Defines a base Spotify entity."""
12+
13+
_attr_has_entity_name = True
14+
15+
def __init__(self, coordinator: SpotifyCoordinator) -> None:
16+
"""Initialize the Spotify entity."""
17+
super().__init__(coordinator)
18+
self._attr_device_info = DeviceInfo(
19+
identifiers={(DOMAIN, coordinator.current_user.user_id)},
20+
manufacturer="Spotify AB",
21+
model=f"Spotify {coordinator.current_user.product}",
22+
name=f"Spotify {coordinator.config_entry.title}",
23+
entry_type=DeviceEntryType.SERVICE,
24+
configuration_url="https://open.spotify.com",
25+
)

homeassistant/components/spotify/media_player.py

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,13 @@
3030
RepeatMode,
3131
)
3232
from homeassistant.core import HomeAssistant, callback
33-
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
3433
from homeassistant.helpers.entity_platform import AddEntitiesCallback
35-
from homeassistant.helpers.update_coordinator import (
36-
CoordinatorEntity,
37-
DataUpdateCoordinator,
38-
)
34+
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
3935

40-
from . import SpotifyConfigEntry
4136
from .browse_media import async_browse_media_internal
42-
from .const import DOMAIN, MEDIA_PLAYER_PREFIX, PLAYABLE_MEDIA_TYPES
43-
from .coordinator import SpotifyCoordinator
37+
from .const import MEDIA_PLAYER_PREFIX, PLAYABLE_MEDIA_TYPES
38+
from .coordinator import SpotifyConfigEntry, SpotifyCoordinator
39+
from .entity import SpotifyEntity
4440

4541
_LOGGER = logging.getLogger(__name__)
4642

@@ -80,8 +76,6 @@ async def async_setup_entry(
8076
spotify = SpotifyMediaPlayer(
8177
data.coordinator,
8278
data.devices,
83-
entry.unique_id,
84-
entry.title,
8579
)
8680
async_add_entities([spotify])
8781

@@ -99,10 +93,9 @@ def wrapper(self: SpotifyMediaPlayer) -> _R | None:
9993
return wrapper
10094

10195

102-
class SpotifyMediaPlayer(CoordinatorEntity[SpotifyCoordinator], MediaPlayerEntity):
96+
class SpotifyMediaPlayer(SpotifyEntity, MediaPlayerEntity):
10397
"""Representation of a Spotify controller."""
10498

105-
_attr_has_entity_name = True
10699
_attr_media_image_remotely_accessible = False
107100
_attr_name = None
108101
_attr_translation_key = "spotify"
@@ -111,23 +104,11 @@ def __init__(
111104
self,
112105
coordinator: SpotifyCoordinator,
113106
device_coordinator: DataUpdateCoordinator[list[Device]],
114-
user_id: str,
115-
name: str,
116107
) -> None:
117108
"""Initialize."""
118109
super().__init__(coordinator)
119110
self.devices = device_coordinator
120-
121-
self._attr_unique_id = user_id
122-
123-
self._attr_device_info = DeviceInfo(
124-
identifiers={(DOMAIN, user_id)},
125-
manufacturer="Spotify AB",
126-
model=f"Spotify {coordinator.current_user.product}",
127-
name=f"Spotify {name}",
128-
entry_type=DeviceEntryType.SERVICE,
129-
configuration_url="https://open.spotify.com",
130-
)
111+
self._attr_unique_id = coordinator.current_user.user_id
131112

132113
@property
133114
def currently_playing(self) -> PlaybackState | None:

homeassistant/components/spotify/sensor.py

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,10 @@
77

88
from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
99
from homeassistant.core import HomeAssistant
10-
from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
1110
from homeassistant.helpers.entity_platform import AddEntitiesCallback
12-
from homeassistant.helpers.update_coordinator import CoordinatorEntity
1311

14-
from . import DOMAIN, SpotifyConfigEntry
15-
from .coordinator import SpotifyCoordinator
12+
from .coordinator import SpotifyConfigEntry, SpotifyCoordinator
13+
from .entity import SpotifyEntity
1614

1715

1816
@dataclass(frozen=True, kw_only=True)
@@ -41,41 +39,28 @@ async def async_setup_entry(
4139
"""Set up Spotify sensor based on a config entry."""
4240
coordinator = entry.runtime_data.coordinator
4341

44-
user_id = entry.unique_id
45-
46-
assert user_id is not None
47-
4842
async_add_entities(
49-
SpotifyAudioFeatureSensor(coordinator, description, user_id, entry.title)
43+
SpotifyAudioFeatureSensor(coordinator, description)
5044
for description in AUDIO_FEATURE_SENSORS
5145
)
5246

5347

54-
class SpotifyAudioFeatureSensor(CoordinatorEntity[SpotifyCoordinator], SensorEntity):
48+
class SpotifyAudioFeatureSensor(SpotifyEntity, SensorEntity):
5549
"""Representation of a Spotify sensor."""
5650

57-
_attr_has_entity_name = True
5851
entity_description: SpotifyAudioFeaturesSensorEntityDescription
5952

6053
def __init__(
6154
self,
6255
coordinator: SpotifyCoordinator,
6356
entity_description: SpotifyAudioFeaturesSensorEntityDescription,
64-
user_id: str,
65-
name: str,
6657
) -> None:
6758
"""Initialize."""
6859
super().__init__(coordinator)
69-
self._attr_unique_id = f"{user_id}_{entity_description.key}"
70-
self.entity_description = entity_description
71-
self._attr_device_info = DeviceInfo(
72-
identifiers={(DOMAIN, user_id)},
73-
manufacturer="Spotify AB",
74-
model=f"Spotify {coordinator.current_user.product}",
75-
name=f"Spotify {name}",
76-
entry_type=DeviceEntryType.SERVICE,
77-
configuration_url="https://open.spotify.com",
60+
self._attr_unique_id = (
61+
f"{coordinator.current_user.user_id}_{entity_description.key}"
7862
)
63+
self.entity_description = entity_description
7964

8065
@property
8166
def native_value(self) -> float | None:

0 commit comments

Comments
 (0)