Skip to content

Commit 87aecf0

Browse files
authored
Linkplay: add select entity to set Audio Output hardware (home-assistant#143329)
1 parent 0b2ce73 commit 87aecf0

File tree

4 files changed

+129
-1
lines changed

4 files changed

+129
-1
lines changed

homeassistant/components/linkplay/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@ class LinkPlaySharedData:
1919
DOMAIN = "linkplay"
2020
SHARED_DATA = "shared_data"
2121
SHARED_DATA_KEY: HassKey[LinkPlaySharedData] = HassKey(SHARED_DATA)
22-
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER]
22+
PLATFORMS = [Platform.BUTTON, Platform.MEDIA_PLAYER, Platform.SELECT]
2323
DATA_SESSION = "session"

homeassistant/components/linkplay/icons.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
"timesync": {
55
"default": "mdi:clock"
66
}
7+
},
8+
"select": {
9+
"audio_output_hardware_mode": {
10+
"default": "mdi:transit-connection-horizontal"
11+
}
712
}
813
},
914
"services": {
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
"""Support for LinkPlay select."""
2+
3+
from __future__ import annotations
4+
5+
from collections.abc import Awaitable, Callable, Coroutine
6+
from dataclasses import dataclass
7+
import logging
8+
from typing import Any
9+
10+
from linkplay.bridge import LinkPlayBridge, LinkPlayPlayer
11+
from linkplay.consts import AudioOutputHwMode
12+
from linkplay.manufacturers import MANUFACTURER_WIIM
13+
14+
from homeassistant.components.select import SelectEntity, SelectEntityDescription
15+
from homeassistant.core import HomeAssistant
16+
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
17+
18+
from . import LinkPlayConfigEntry
19+
from .entity import LinkPlayBaseEntity, exception_wrap
20+
21+
_LOGGER = logging.getLogger(__name__)
22+
23+
AUDIO_OUTPUT_HW_MODE_MAP: dict[AudioOutputHwMode, str] = {
24+
AudioOutputHwMode.OPTICAL: "optical",
25+
AudioOutputHwMode.LINE_OUT: "line_out",
26+
AudioOutputHwMode.COAXIAL: "coaxial",
27+
AudioOutputHwMode.HEADPHONES: "headphones",
28+
}
29+
30+
AUDIO_OUTPUT_HW_MODE_MAP_INV: dict[str, AudioOutputHwMode] = {
31+
v: k for k, v in AUDIO_OUTPUT_HW_MODE_MAP.items()
32+
}
33+
34+
35+
async def _get_current_option(bridge: LinkPlayBridge) -> str:
36+
"""Get the current hardware mode."""
37+
modes = await bridge.player.get_audio_output_hw_mode()
38+
return AUDIO_OUTPUT_HW_MODE_MAP[modes.hardware]
39+
40+
41+
@dataclass(frozen=True, kw_only=True)
42+
class LinkPlaySelectEntityDescription(SelectEntityDescription):
43+
"""Class describing LinkPlay select entities."""
44+
45+
set_option_fn: Callable[[LinkPlayPlayer, str], Coroutine[Any, Any, None]]
46+
current_option_fn: Callable[[LinkPlayPlayer], Awaitable[str]]
47+
48+
49+
SELECT_TYPES_WIIM: tuple[LinkPlaySelectEntityDescription, ...] = (
50+
LinkPlaySelectEntityDescription(
51+
key="audio_output_hardware_mode",
52+
translation_key="audio_output_hardware_mode",
53+
current_option_fn=_get_current_option,
54+
set_option_fn=(
55+
lambda linkplay_bridge,
56+
option: linkplay_bridge.player.set_audio_output_hw_mode(
57+
AUDIO_OUTPUT_HW_MODE_MAP_INV[option]
58+
)
59+
),
60+
options=list(AUDIO_OUTPUT_HW_MODE_MAP_INV),
61+
),
62+
)
63+
64+
65+
async def async_setup_entry(
66+
hass: HomeAssistant,
67+
config_entry: LinkPlayConfigEntry,
68+
async_add_entities: AddConfigEntryEntitiesCallback,
69+
) -> None:
70+
"""Set up the LinkPlay select from config entry."""
71+
72+
# add entities
73+
if config_entry.runtime_data.bridge.device.manufacturer == MANUFACTURER_WIIM:
74+
async_add_entities(
75+
LinkPlaySelect(config_entry.runtime_data.bridge, description)
76+
for description in SELECT_TYPES_WIIM
77+
)
78+
79+
80+
class LinkPlaySelect(LinkPlayBaseEntity, SelectEntity):
81+
"""Representation of LinkPlay select."""
82+
83+
entity_description: LinkPlaySelectEntityDescription
84+
85+
def __init__(
86+
self,
87+
bridge: LinkPlayPlayer,
88+
description: LinkPlaySelectEntityDescription,
89+
) -> None:
90+
"""Initialize LinkPlay select."""
91+
super().__init__(bridge)
92+
self.entity_description = description
93+
self._attr_unique_id = f"{bridge.device.uuid}-{description.key}"
94+
95+
async def async_update(self) -> None:
96+
"""Get the current value from the device."""
97+
try:
98+
# modes = await self.entity_description.current_option_fn(self._bridge)
99+
self._attr_current_option = await self.entity_description.current_option_fn(
100+
self._bridge
101+
)
102+
103+
except ValueError as ex:
104+
_LOGGER.debug(
105+
"Cannot retrieve hardware mode value from device with error:, %s", ex
106+
)
107+
self._attr_current_option = None
108+
109+
@exception_wrap
110+
async def async_select_option(self, option: str) -> None:
111+
"""Set the option."""
112+
await self.entity_description.set_option_fn(self._bridge, option)

homeassistant/components/linkplay/strings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@
4040
"timesync": {
4141
"name": "Sync time"
4242
}
43+
},
44+
"select": {
45+
"audio_output_hardware_mode": {
46+
"name": "Audio output hardware mode",
47+
"state": {
48+
"optical": "Optical",
49+
"line_out": "Line out",
50+
"coaxial": "Coaxial",
51+
"headphones": "Headphones"
52+
}
53+
}
4354
}
4455
},
4556
"exceptions": {

0 commit comments

Comments
 (0)