/
/
/
1"""Constants for the Home Assistant provider."""
2
3from __future__ import annotations
4
5from enum import IntFlag
6from typing import TYPE_CHECKING, Any
7
8from music_assistant_models.enums import PlaybackState
9
10if TYPE_CHECKING:
11 import logging
12
13CONF_POWER_CONTROLS = "power_controls"
14CONF_MUTE_CONTROLS = "mute_controls"
15CONF_VOLUME_CONTROLS = "volume_controls"
16
17# Home Assistant entity domains Music Assistant can offer as player controls.
18CONTROL_DOMAINS = ("media_player", "switch", "input_boolean", "number", "input_number")
19
20
21class MediaPlayerEntityFeature(IntFlag):
22 """Supported features of the media player entity."""
23
24 PAUSE = 1
25 SEEK = 2
26 VOLUME_SET = 4
27 VOLUME_MUTE = 8
28 PREVIOUS_TRACK = 16
29 NEXT_TRACK = 32
30
31 TURN_ON = 128
32 TURN_OFF = 256
33 PLAY_MEDIA = 512
34 VOLUME_STEP = 1024
35 SELECT_SOURCE = 2048
36 STOP = 4096
37 CLEAR_PLAYLIST = 8192
38 PLAY = 16384
39 SHUFFLE_SET = 32768
40 SELECT_SOUND_MODE = 65536
41 BROWSE_MEDIA = 131072
42 REPEAT_SET = 262144
43 GROUPING = 524288
44 MEDIA_ANNOUNCE = 1048576
45 MEDIA_ENQUEUE = 2097152
46
47
48StateMap = {
49 "playing": PlaybackState.PLAYING,
50 "paused": PlaybackState.PAUSED,
51 "buffering": PlaybackState.PLAYING,
52 "idle": PlaybackState.IDLE,
53 "off": PlaybackState.IDLE,
54 "standby": PlaybackState.IDLE,
55 "unknown": PlaybackState.IDLE,
56 "unavailable": PlaybackState.IDLE,
57}
58
59# HA states that we consider as "powered off"
60OFF_STATES = ("unavailable", "unknown", "standby", "off")
61UNAVAILABLE_STATES = ("unavailable", "unknown")
62
63
64def parse_supported_features(
65 raw_value: Any, entity_id: str, logger: logging.Logger
66) -> MediaPlayerEntityFeature:
67 """
68 Return the features supported by a Home Assistant media_player entity.
69
70 A value that can not be interpreted yields no features at all.
71
72 :param raw_value: Raw value of the entity's supported_features attribute.
73 :param entity_id: Entity id the value belongs to, used for logging.
74 :param logger: Logger to report an invalid value on.
75 """
76 if raw_value is None:
77 # attribute is absent for entities that (currently) have no state
78 return MediaPlayerEntityFeature(0)
79 if isinstance(raw_value, int) and not isinstance(raw_value, bool) and raw_value >= 0:
80 # unknown bits (features of a newer HA version) are preserved
81 return MediaPlayerEntityFeature(raw_value)
82 # integrations are free to write anything into the attribute, so a value we can not
83 # interpret must not break the handling of all other entities
84 logger.warning(
85 "Home Assistant entity %s reports an invalid supported_features value: %r - "
86 "treating it as if it supports no features",
87 entity_id,
88 raw_value,
89 )
90 return MediaPlayerEntityFeature(0)
91