mirror of
https://github.com/home-assistant/core.git
synced 2025-07-20 03:37:07 +00:00
Support media_player grouping services for Sonos (#63256)
This commit is contained in:
parent
d6c8f3965a
commit
754f4c52c2
@ -96,6 +96,7 @@ class SonosData:
|
|||||||
self.discovery_known: set[str] = set()
|
self.discovery_known: set[str] = set()
|
||||||
self.boot_counts: dict[str, int] = {}
|
self.boot_counts: dict[str, int] = {}
|
||||||
self.mdns_names: dict[str, str] = {}
|
self.mdns_names: dict[str, str] = {}
|
||||||
|
self.entity_id_mappings: dict[str, SonosSpeaker] = {}
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
@ -14,6 +14,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
|
DATA_SONOS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SONOS_FAVORITES_UPDATED,
|
SONOS_FAVORITES_UPDATED,
|
||||||
SONOS_POLL_UPDATE,
|
SONOS_POLL_UPDATE,
|
||||||
@ -35,6 +36,7 @@ class SonosEntity(Entity):
|
|||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Handle common setup when added to hass."""
|
"""Handle common setup when added to hass."""
|
||||||
|
self.hass.data[DATA_SONOS].entity_id_mappings[self.entity_id] = self.speaker
|
||||||
self.async_on_remove(
|
self.async_on_remove(
|
||||||
async_dispatcher_connect(
|
async_dispatcher_connect(
|
||||||
self.hass,
|
self.hass,
|
||||||
@ -57,6 +59,10 @@ class SonosEntity(Entity):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
|
"""Clean up when entity is removed."""
|
||||||
|
del self.hass.data[DATA_SONOS].entity_id_mappings[self.entity_id]
|
||||||
|
|
||||||
async def async_poll(self, now: datetime.datetime) -> None:
|
async def async_poll(self, now: datetime.datetime) -> None:
|
||||||
"""Poll the entity if subscriptions fail."""
|
"""Poll the entity if subscriptions fail."""
|
||||||
if not self.speaker.subscriptions_failed:
|
if not self.speaker.subscriptions_failed:
|
||||||
|
@ -28,6 +28,7 @@ from homeassistant.components.media_player.const import (
|
|||||||
REPEAT_MODE_ONE,
|
REPEAT_MODE_ONE,
|
||||||
SUPPORT_BROWSE_MEDIA,
|
SUPPORT_BROWSE_MEDIA,
|
||||||
SUPPORT_CLEAR_PLAYLIST,
|
SUPPORT_CLEAR_PLAYLIST,
|
||||||
|
SUPPORT_GROUPING,
|
||||||
SUPPORT_NEXT_TRACK,
|
SUPPORT_NEXT_TRACK,
|
||||||
SUPPORT_PAUSE,
|
SUPPORT_PAUSE,
|
||||||
SUPPORT_PLAY,
|
SUPPORT_PLAY,
|
||||||
@ -47,6 +48,7 @@ from homeassistant.components.plex.services import play_on_sonos
|
|||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import ATTR_TIME, STATE_IDLE, STATE_PAUSED, STATE_PLAYING
|
from homeassistant.const import ATTR_TIME, STATE_IDLE, STATE_PAUSED, STATE_PLAYING
|
||||||
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
from homeassistant.core import HomeAssistant, ServiceCall, callback
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import config_validation as cv, entity_platform, service
|
from homeassistant.helpers import config_validation as cv, entity_platform, service
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
@ -73,6 +75,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
SUPPORT_SONOS = (
|
SUPPORT_SONOS = (
|
||||||
SUPPORT_BROWSE_MEDIA
|
SUPPORT_BROWSE_MEDIA
|
||||||
| SUPPORT_CLEAR_PLAYLIST
|
| SUPPORT_CLEAR_PLAYLIST
|
||||||
|
| SUPPORT_GROUPING
|
||||||
| SUPPORT_NEXT_TRACK
|
| SUPPORT_NEXT_TRACK
|
||||||
| SUPPORT_PAUSE
|
| SUPPORT_PAUSE
|
||||||
| SUPPORT_PLAY
|
| SUPPORT_PLAY
|
||||||
@ -666,3 +669,18 @@ class SonosMediaPlayerEntity(SonosEntity, MediaPlayerEntity):
|
|||||||
f"Media not found: {media_content_type} / {media_content_id}"
|
f"Media not found: {media_content_type} / {media_content_id}"
|
||||||
)
|
)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def join_players(self, group_members):
|
||||||
|
"""Join `group_members` as a player group with the current player."""
|
||||||
|
speakers = []
|
||||||
|
for entity_id in group_members:
|
||||||
|
if speaker := self.hass.data[DATA_SONOS].entity_id_mappings.get(entity_id):
|
||||||
|
speakers.append(speaker)
|
||||||
|
else:
|
||||||
|
raise HomeAssistantError(f"Not a known Sonos entity_id: {entity_id}")
|
||||||
|
|
||||||
|
self.speaker.join(speakers)
|
||||||
|
|
||||||
|
def unjoin_player(self):
|
||||||
|
"""Remove this player from any group."""
|
||||||
|
self.speaker.unjoin()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user