mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
LinkPlay group members should return the entity ids (#141791)
This commit is contained in:
parent
d3745d2519
commit
cd104dc08c
@ -13,7 +13,7 @@ from homeassistant.const import CONF_HOST
|
|||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
|
||||||
from .const import CONTROLLER, CONTROLLER_KEY, DOMAIN, PLATFORMS
|
from .const import DOMAIN, PLATFORMS, SHARED_DATA, LinkPlaySharedData
|
||||||
from .utils import async_get_client_session
|
from .utils import async_get_client_session
|
||||||
|
|
||||||
|
|
||||||
@ -44,11 +44,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: LinkPlayConfigEntry) ->
|
|||||||
# setup the controller and discover multirooms
|
# setup the controller and discover multirooms
|
||||||
controller: LinkPlayController | None = None
|
controller: LinkPlayController | None = None
|
||||||
hass.data.setdefault(DOMAIN, {})
|
hass.data.setdefault(DOMAIN, {})
|
||||||
if CONTROLLER not in hass.data[DOMAIN]:
|
if SHARED_DATA not in hass.data[DOMAIN]:
|
||||||
controller = LinkPlayController(session)
|
controller = LinkPlayController(session)
|
||||||
hass.data[DOMAIN][CONTROLLER_KEY] = controller
|
hass.data[DOMAIN][SHARED_DATA] = LinkPlaySharedData(controller, {})
|
||||||
else:
|
else:
|
||||||
controller = hass.data[DOMAIN][CONTROLLER_KEY]
|
controller = hass.data[DOMAIN][SHARED_DATA].controller
|
||||||
|
|
||||||
await controller.add_bridge(bridge)
|
await controller.add_bridge(bridge)
|
||||||
await controller.discover_multirooms()
|
await controller.discover_multirooms()
|
||||||
@ -62,4 +62,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: LinkPlayConfigEntry) ->
|
|||||||
async def async_unload_entry(hass: HomeAssistant, entry: LinkPlayConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: LinkPlayConfigEntry) -> bool:
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
|
|
||||||
|
# remove the bridge from the controller and discover multirooms
|
||||||
|
bridge: LinkPlayBridge | None = entry.runtime_data.bridge
|
||||||
|
controller: LinkPlayController = hass.data[DOMAIN][SHARED_DATA].controller
|
||||||
|
await controller.remove_bridge(bridge)
|
||||||
|
await controller.discover_multirooms()
|
||||||
|
|
||||||
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
|
@ -1,12 +1,23 @@
|
|||||||
"""LinkPlay constants."""
|
"""LinkPlay constants."""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
from linkplay.controller import LinkPlayController
|
from linkplay.controller import LinkPlayController
|
||||||
|
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.util.hass_dict import HassKey
|
from homeassistant.util.hass_dict import HassKey
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LinkPlaySharedData:
|
||||||
|
"""Shared data for LinkPlay."""
|
||||||
|
|
||||||
|
controller: LinkPlayController
|
||||||
|
entity_to_bridge: dict[str, str]
|
||||||
|
|
||||||
|
|
||||||
DOMAIN = "linkplay"
|
DOMAIN = "linkplay"
|
||||||
CONTROLLER = "controller"
|
SHARED_DATA = "shared_data"
|
||||||
CONTROLLER_KEY: HassKey[LinkPlayController] = HassKey(CONTROLLER)
|
SHARED_DATA_KEY: HassKey[LinkPlaySharedData] = HassKey(SHARED_DATA)
|
||||||
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER]
|
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER]
|
||||||
DATA_SESSION = "session"
|
DATA_SESSION = "session"
|
||||||
|
@ -23,19 +23,14 @@ from homeassistant.components.media_player import (
|
|||||||
RepeatMode,
|
RepeatMode,
|
||||||
async_process_play_media_url,
|
async_process_play_media_url,
|
||||||
)
|
)
|
||||||
from homeassistant.const import Platform
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
|
||||||
from homeassistant.helpers import (
|
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||||
config_validation as cv,
|
|
||||||
entity_platform,
|
|
||||||
entity_registry as er,
|
|
||||||
)
|
|
||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
from homeassistant.util.dt import utcnow
|
from homeassistant.util.dt import utcnow
|
||||||
|
|
||||||
from . import LinkPlayConfigEntry, LinkPlayData
|
from . import SHARED_DATA, LinkPlayConfigEntry
|
||||||
from .const import CONTROLLER_KEY, DOMAIN
|
from .const import DOMAIN
|
||||||
from .entity import LinkPlayBaseEntity, exception_wrap
|
from .entity import LinkPlayBaseEntity, exception_wrap
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
@ -163,6 +158,13 @@ class LinkPlayMediaPlayerEntity(LinkPlayBaseEntity, MediaPlayerEntity):
|
|||||||
mode.value for mode in bridge.player.available_equalizer_modes
|
mode.value for mode in bridge.player.available_equalizer_modes
|
||||||
]
|
]
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Handle common setup when added to hass."""
|
||||||
|
await super().async_added_to_hass()
|
||||||
|
self.hass.data[DOMAIN][SHARED_DATA].entity_to_bridge[self.entity_id] = (
|
||||||
|
self._bridge.device.uuid
|
||||||
|
)
|
||||||
|
|
||||||
@exception_wrap
|
@exception_wrap
|
||||||
async def async_update(self) -> None:
|
async def async_update(self) -> None:
|
||||||
"""Update the state of the media player."""
|
"""Update the state of the media player."""
|
||||||
@ -276,62 +278,56 @@ class LinkPlayMediaPlayerEntity(LinkPlayBaseEntity, MediaPlayerEntity):
|
|||||||
async def async_join_players(self, group_members: list[str]) -> None:
|
async def async_join_players(self, group_members: list[str]) -> None:
|
||||||
"""Join `group_members` as a player group with the current player."""
|
"""Join `group_members` as a player group with the current player."""
|
||||||
|
|
||||||
controller: LinkPlayController = self.hass.data[DOMAIN][CONTROLLER_KEY]
|
controller: LinkPlayController = self.hass.data[DOMAIN][SHARED_DATA].controller
|
||||||
multiroom = self._bridge.multiroom
|
multiroom = self._bridge.multiroom
|
||||||
if multiroom is None:
|
if multiroom is None:
|
||||||
multiroom = LinkPlayMultiroom(self._bridge)
|
multiroom = LinkPlayMultiroom(self._bridge)
|
||||||
|
|
||||||
for group_member in group_members:
|
for group_member in group_members:
|
||||||
bridge = self._get_linkplay_bridge(group_member)
|
bridge = await self._get_linkplay_bridge(group_member)
|
||||||
if bridge:
|
if bridge:
|
||||||
await multiroom.add_follower(bridge)
|
await multiroom.add_follower(bridge)
|
||||||
|
|
||||||
await controller.discover_multirooms()
|
await controller.discover_multirooms()
|
||||||
|
|
||||||
def _get_linkplay_bridge(self, entity_id: str) -> LinkPlayBridge:
|
async def _get_linkplay_bridge(self, entity_id: str) -> LinkPlayBridge:
|
||||||
"""Get linkplay bridge from entity_id."""
|
"""Get linkplay bridge from entity_id."""
|
||||||
|
|
||||||
entity_registry = er.async_get(self.hass)
|
shared_data = self.hass.data[DOMAIN][SHARED_DATA]
|
||||||
|
controller = shared_data.controller
|
||||||
|
bridge_uuid = shared_data.entity_to_bridge.get(entity_id, None)
|
||||||
|
bridge = await controller.find_bridge(bridge_uuid)
|
||||||
|
|
||||||
# Check for valid linkplay media_player entity
|
if bridge is None:
|
||||||
entity_entry = entity_registry.async_get(entity_id)
|
|
||||||
|
|
||||||
if (
|
|
||||||
entity_entry is None
|
|
||||||
or entity_entry.domain != Platform.MEDIA_PLAYER
|
|
||||||
or entity_entry.platform != DOMAIN
|
|
||||||
or entity_entry.config_entry_id is None
|
|
||||||
):
|
|
||||||
raise ServiceValidationError(
|
raise ServiceValidationError(
|
||||||
translation_domain=DOMAIN,
|
translation_domain=DOMAIN,
|
||||||
translation_key="invalid_grouping_entity",
|
translation_key="invalid_grouping_entity",
|
||||||
translation_placeholders={"entity_id": entity_id},
|
translation_placeholders={"entity_id": entity_id},
|
||||||
)
|
)
|
||||||
|
|
||||||
config_entry = self.hass.config_entries.async_get_entry(
|
return bridge
|
||||||
entity_entry.config_entry_id
|
|
||||||
)
|
|
||||||
assert config_entry
|
|
||||||
|
|
||||||
# Return bridge
|
|
||||||
data: LinkPlayData = config_entry.runtime_data
|
|
||||||
return data.bridge
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def group_members(self) -> list[str]:
|
def group_members(self) -> list[str]:
|
||||||
"""List of players which are grouped together."""
|
"""List of players which are grouped together."""
|
||||||
multiroom = self._bridge.multiroom
|
multiroom = self._bridge.multiroom
|
||||||
if multiroom is not None:
|
if multiroom is None:
|
||||||
return [multiroom.leader.device.uuid] + [
|
return []
|
||||||
follower.device.uuid for follower in multiroom.followers
|
|
||||||
]
|
|
||||||
|
|
||||||
return []
|
shared_data = self.hass.data[DOMAIN][SHARED_DATA]
|
||||||
|
|
||||||
|
return [
|
||||||
|
entity_id
|
||||||
|
for entity_id, bridge in shared_data.entity_to_bridge.items()
|
||||||
|
if bridge
|
||||||
|
in [multiroom.leader.device.uuid]
|
||||||
|
+ [follower.device.uuid for follower in multiroom.followers]
|
||||||
|
]
|
||||||
|
|
||||||
@exception_wrap
|
@exception_wrap
|
||||||
async def async_unjoin_player(self) -> None:
|
async def async_unjoin_player(self) -> None:
|
||||||
"""Remove this player from any group."""
|
"""Remove this player from any group."""
|
||||||
controller: LinkPlayController = self.hass.data[DOMAIN][CONTROLLER_KEY]
|
controller: LinkPlayController = self.hass.data[DOMAIN][SHARED_DATA].controller
|
||||||
|
|
||||||
multiroom = self._bridge.multiroom
|
multiroom = self._bridge.multiroom
|
||||||
if multiroom is not None:
|
if multiroom is not None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user