Linkplay: add select entity to set Audio Output hardware (#143329)

This commit is contained in:
Arjan 2025-07-11 12:45:21 +02:00 committed by GitHub
parent 0b2ce73eac
commit 87aecf0ed9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 129 additions and 1 deletions

View File

@ -19,5 +19,5 @@ class LinkPlaySharedData:
DOMAIN = "linkplay" DOMAIN = "linkplay"
SHARED_DATA = "shared_data" SHARED_DATA = "shared_data"
SHARED_DATA_KEY: HassKey[LinkPlaySharedData] = HassKey(SHARED_DATA) SHARED_DATA_KEY: HassKey[LinkPlaySharedData] = HassKey(SHARED_DATA)
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER] PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER, Platform.SELECT]
DATA_SESSION = "session" DATA_SESSION = "session"

View File

@ -4,6 +4,11 @@
"timesync": { "timesync": {
"default": "mdi:clock" "default": "mdi:clock"
} }
},
"select": {
"audio_output_hardware_mode": {
"default": "mdi:transit-connection-horizontal"
}
} }
}, },
"services": { "services": {

View File

@ -0,0 +1,112 @@
"""Support for LinkPlay select."""
from __future__ import annotations
from collections.abc import Awaitable, Callable, Coroutine
from dataclasses import dataclass
import logging
from typing import Any
from linkplay.bridge import LinkPlayBridge, LinkPlayPlayer
from linkplay.consts import AudioOutputHwMode
from linkplay.manufacturers import MANUFACTURER_WIIM
from homeassistant.components.select import SelectEntity, SelectEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import LinkPlayConfigEntry
from .entity import LinkPlayBaseEntity, exception_wrap
_LOGGER = logging.getLogger(__name__)
AUDIO_OUTPUT_HW_MODE_MAP: dict[AudioOutputHwMode, str] = {
AudioOutputHwMode.OPTICAL: "optical",
AudioOutputHwMode.LINE_OUT: "line_out",
AudioOutputHwMode.COAXIAL: "coaxial",
AudioOutputHwMode.HEADPHONES: "headphones",
}
AUDIO_OUTPUT_HW_MODE_MAP_INV: dict[str, AudioOutputHwMode] = {
v: k for k, v in AUDIO_OUTPUT_HW_MODE_MAP.items()
}
async def _get_current_option(bridge: LinkPlayBridge) -> str:
"""Get the current hardware mode."""
modes = await bridge.player.get_audio_output_hw_mode()
return AUDIO_OUTPUT_HW_MODE_MAP[modes.hardware]
@dataclass(frozen=True, kw_only=True)
class LinkPlaySelectEntityDescription(SelectEntityDescription):
"""Class describing LinkPlay select entities."""
set_option_fn: Callable[[LinkPlayPlayer, str], Coroutine[Any, Any, None]]
current_option_fn: Callable[[LinkPlayPlayer], Awaitable[str]]
SELECT_TYPES_WIIM: tuple[LinkPlaySelectEntityDescription, ...] = (
LinkPlaySelectEntityDescription(
key="audio_output_hardware_mode",
translation_key="audio_output_hardware_mode",
current_option_fn=_get_current_option,
set_option_fn=(
lambda linkplay_bridge,
option: linkplay_bridge.player.set_audio_output_hw_mode(
AUDIO_OUTPUT_HW_MODE_MAP_INV[option]
)
),
options=list(AUDIO_OUTPUT_HW_MODE_MAP_INV),
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: LinkPlayConfigEntry,
async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
"""Set up the LinkPlay select from config entry."""
# add entities
if config_entry.runtime_data.bridge.device.manufacturer == MANUFACTURER_WIIM:
async_add_entities(
LinkPlaySelect(config_entry.runtime_data.bridge, description)
for description in SELECT_TYPES_WIIM
)
class LinkPlaySelect(LinkPlayBaseEntity, SelectEntity):
"""Representation of LinkPlay select."""
entity_description: LinkPlaySelectEntityDescription
def __init__(
self,
bridge: LinkPlayPlayer,
description: LinkPlaySelectEntityDescription,
) -> None:
"""Initialize LinkPlay select."""
super().__init__(bridge)
self.entity_description = description
self._attr_unique_id = f"{bridge.device.uuid}-{description.key}"
async def async_update(self) -> None:
"""Get the current value from the device."""
try:
# modes = await self.entity_description.current_option_fn(self._bridge)
self._attr_current_option = await self.entity_description.current_option_fn(
self._bridge
)
except ValueError as ex:
_LOGGER.debug(
"Cannot retrieve hardware mode value from device with error:, %s", ex
)
self._attr_current_option = None
@exception_wrap
async def async_select_option(self, option: str) -> None:
"""Set the option."""
await self.entity_description.set_option_fn(self._bridge, option)

View File

@ -40,6 +40,17 @@
"timesync": { "timesync": {
"name": "Sync time" "name": "Sync time"
} }
},
"select": {
"audio_output_hardware_mode": {
"name": "Audio output hardware mode",
"state": {
"optical": "Optical",
"line_out": "Line out",
"coaxial": "Coaxial",
"headphones": "Headphones"
}
}
} }
}, },
"exceptions": { "exceptions": {