/
/
/
1"""
2Home Assistant PlayerProvider for Music Assistant.
3
4Allows using media_player entities in HA to be used as players in MA.
5Requires the Home Assistant Plugin.
6"""
7
8from __future__ import annotations
9
10from typing import TYPE_CHECKING, cast
11
12from music_assistant_models.config_entries import ConfigEntry, ConfigValueOption, ConfigValueType
13from music_assistant_models.enums import ConfigEntryType
14from music_assistant_models.errors import SetupFailedError
15
16from music_assistant.providers.hass import DOMAIN as HASS_DOMAIN
17
18from .constants import CONF_PLAYERS
19from .helpers import get_hass_media_players
20from .provider import HomeAssistantPlayerProvider
21
22if TYPE_CHECKING:
23 from music_assistant_models.config_entries import ProviderConfig
24 from music_assistant_models.provider import ProviderManifest
25
26 from music_assistant import MusicAssistant
27 from music_assistant.models import ProviderInstanceType
28 from music_assistant.providers.hass import HomeAssistantProvider
29
30
31async def setup(
32 mass: MusicAssistant, manifest: ProviderManifest, config: ProviderConfig
33) -> ProviderInstanceType:
34 """Initialize provider(instance) with given configuration."""
35 hass_prov = mass.get_provider(HASS_DOMAIN)
36 if not hass_prov:
37 msg = "The Home Assistant Plugin needs to be set-up first"
38 raise SetupFailedError(msg)
39 hass_prov = cast("HomeAssistantProvider", hass_prov)
40 return HomeAssistantPlayerProvider(mass, manifest, config, hass_prov)
41
42
43async def get_config_entries(
44 mass: MusicAssistant,
45 instance_id: str | None = None, # noqa: ARG001
46 action: str | None = None, # noqa: ARG001
47 values: dict[str, ConfigValueType] | None = None, # noqa: ARG001
48) -> tuple[ConfigEntry, ...]:
49 """
50 Return Config entries to setup this provider.
51
52 instance_id: id of an existing provider instance (None if new instance setup).
53 action: [optional] action key called from config entries UI.
54 values: the (intermediate) raw values for config entries sent with the action.
55 """
56 hass_prov = cast("HomeAssistantProvider|None", mass.get_provider(HASS_DOMAIN))
57 player_entities: list[ConfigValueOption] = []
58 if hass_prov and hass_prov.hass.connected:
59 async for state in get_hass_media_players(hass_prov):
60 name = f"{state['attributes']['friendly_name']} ({state['entity_id']})"
61 player_entities.append(ConfigValueOption(name, state["entity_id"]))
62 return (
63 ConfigEntry(
64 key=CONF_PLAYERS,
65 type=ConfigEntryType.STRING,
66 multi_value=True,
67 label="Player entities",
68 required=True,
69 options=player_entities,
70 description="Specify which HA media_player entity id's you "
71 "like to import as players in Music Assistant.\n\n"
72 "Note that only Media player entities will be listed which are "
73 "compatible with Music Assistant.",
74 ),
75 )
76