/
/
/
1"""Helpers for interpreting Home Assistant entities as player controls."""
2
3from __future__ import annotations
4
5from typing import TYPE_CHECKING, NamedTuple
6
7from .constants import MediaPlayerEntityFeature, parse_supported_features
8
9if TYPE_CHECKING:
10 import logging
11
12 from hass_client.models import State
13
14
15class ControlCapabilities(NamedTuple):
16 """The player control roles a Home Assistant entity can serve."""
17
18 power: bool = False
19 volume: bool = False
20 mute: bool = False
21
22
23def get_control_capabilities(state: State, logger: logging.Logger) -> ControlCapabilities:
24 """
25 Return the player control roles the given Home Assistant entity can serve.
26
27 :param state: The current state of the entity to inspect.
28 :param logger: Logger to report an unparsable supported_features attribute on.
29 :return: The supported roles; all False when the entity is unusable as a player control.
30 """
31 entity_platform = state["entity_id"].split(".")[0]
32 if entity_platform in ("switch", "input_boolean"):
33 # simple on/off controls are suitable as power and mute controls
34 return ControlCapabilities(power=True, mute=True)
35 if entity_platform in ("number", "input_number"):
36 # number and input_number are very similar, both are suitable for volume control
37 return ControlCapabilities(volume=True)
38 # media player can be used as control, depending on features
39 if entity_platform != "media_player":
40 return ControlCapabilities()
41 if "mass_player_type" in state["attributes"]:
42 # filter out mass players
43 return ControlCapabilities()
44 supported_features = parse_supported_features(
45 state["attributes"].get("supported_features"),
46 state["entity_id"],
47 logger,
48 )
49 return ControlCapabilities(
50 power=(
51 MediaPlayerEntityFeature.TURN_ON in supported_features
52 and MediaPlayerEntityFeature.TURN_OFF in supported_features
53 ),
54 volume=MediaPlayerEntityFeature.VOLUME_SET in supported_features,
55 mute=MediaPlayerEntityFeature.VOLUME_MUTE in supported_features,
56 )
57
58
59def get_control_name(entity_id: str, state: State | None) -> str:
60 """
61 Return the human readable name to present a Home Assistant entity control under.
62
63 :param entity_id: The entity the control is based on.
64 :param state: The entity's current state, if known.
65 """
66 if state and (friendly_name := state["attributes"].get("friendly_name")):
67 return f"{friendly_name} ({entity_id})"
68 return entity_id
69