mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add select source action to Music Assistant (#145619)
This commit is contained in:
parent
0d81694640
commit
6f9a39ab89
@ -292,6 +292,10 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
|
|||||||
self._attr_state = MediaPlayerState(player.state.value)
|
self._attr_state = MediaPlayerState(player.state.value)
|
||||||
else:
|
else:
|
||||||
self._attr_state = MediaPlayerState(STATE_OFF)
|
self._attr_state = MediaPlayerState(STATE_OFF)
|
||||||
|
self._attr_source = player.active_source
|
||||||
|
self._attr_source_list = [
|
||||||
|
source.name for source in player.source_list if not source.passive
|
||||||
|
]
|
||||||
|
|
||||||
group_members: list[str] = []
|
group_members: list[str] = []
|
||||||
if player.group_childs:
|
if player.group_childs:
|
||||||
@ -459,6 +463,11 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
|
|||||||
"""Remove this player from any group."""
|
"""Remove this player from any group."""
|
||||||
await self.mass.players.player_command_ungroup(self.player_id)
|
await self.mass.players.player_command_ungroup(self.player_id)
|
||||||
|
|
||||||
|
@catch_musicassistant_error
|
||||||
|
async def async_select_source(self, source: str) -> None:
|
||||||
|
"""Select input source."""
|
||||||
|
await self.mass.players.player_command_select_source(self.player_id, source)
|
||||||
|
|
||||||
@catch_musicassistant_error
|
@catch_musicassistant_error
|
||||||
async def _async_handle_play_media(
|
async def _async_handle_play_media(
|
||||||
self,
|
self,
|
||||||
@ -735,4 +744,6 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
|
|||||||
if self.player.power_control != PLAYER_CONTROL_NONE:
|
if self.player.power_control != PLAYER_CONTROL_NONE:
|
||||||
supported_features |= MediaPlayerEntityFeature.TURN_ON
|
supported_features |= MediaPlayerEntityFeature.TURN_ON
|
||||||
supported_features |= MediaPlayerEntityFeature.TURN_OFF
|
supported_features |= MediaPlayerEntityFeature.TURN_OFF
|
||||||
|
if PlayerFeature.SELECT_SOURCE in self.player.supported_features:
|
||||||
|
supported_features |= MediaPlayerEntityFeature.SELECT_SOURCE
|
||||||
self._attr_supported_features = supported_features
|
self._attr_supported_features = supported_features
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"pause",
|
"pause",
|
||||||
"set_members",
|
"set_members",
|
||||||
"power",
|
"power",
|
||||||
"enqueue"
|
"enqueue",
|
||||||
|
"select_source"
|
||||||
],
|
],
|
||||||
"elapsed_time": null,
|
"elapsed_time": null,
|
||||||
"elapsed_time_last_updated": 0,
|
"elapsed_time_last_updated": 0,
|
||||||
@ -43,7 +44,32 @@
|
|||||||
"hide_player_in_ui": ["when_unavailable"],
|
"hide_player_in_ui": ["when_unavailable"],
|
||||||
"expose_to_ha": true,
|
"expose_to_ha": true,
|
||||||
"can_group_with": ["00:00:00:00:00:02"],
|
"can_group_with": ["00:00:00:00:00:02"],
|
||||||
"source_list": []
|
"source_list": [
|
||||||
|
{
|
||||||
|
"id": "00:00:00:00:00:01",
|
||||||
|
"name": "Music Assistant Queue",
|
||||||
|
"passive": false,
|
||||||
|
"can_play_pause": true,
|
||||||
|
"can_seek": true,
|
||||||
|
"can_next_previous": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "spotify",
|
||||||
|
"name": "Spotify Connect",
|
||||||
|
"passive": true,
|
||||||
|
"can_play_pause": true,
|
||||||
|
"can_seek": true,
|
||||||
|
"can_next_previous": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "linein",
|
||||||
|
"name": "Line-In",
|
||||||
|
"passive": false,
|
||||||
|
"can_play_pause": false,
|
||||||
|
"can_seek": false,
|
||||||
|
"can_next_previous": false
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"player_id": "00:00:00:00:00:02",
|
"player_id": "00:00:00:00:00:02",
|
||||||
|
@ -54,6 +54,7 @@
|
|||||||
'media_duration': 300,
|
'media_duration': 300,
|
||||||
'media_position': 0,
|
'media_position': 0,
|
||||||
'media_title': 'Test Track',
|
'media_title': 'Test Track',
|
||||||
|
'source': 'spotify',
|
||||||
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
||||||
'volume_level': 0.2,
|
'volume_level': 0.2,
|
||||||
}),
|
}),
|
||||||
@ -125,6 +126,7 @@
|
|||||||
'media_title': 'November Rain',
|
'media_title': 'November Rain',
|
||||||
'repeat': 'all',
|
'repeat': 'all',
|
||||||
'shuffle': True,
|
'shuffle': True,
|
||||||
|
'source': 'test_group_player_1',
|
||||||
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
||||||
'volume_level': 0.06,
|
'volume_level': 0.06,
|
||||||
}),
|
}),
|
||||||
@ -142,6 +144,10 @@
|
|||||||
}),
|
}),
|
||||||
'area_id': None,
|
'area_id': None,
|
||||||
'capabilities': dict({
|
'capabilities': dict({
|
||||||
|
'source_list': list([
|
||||||
|
'Music Assistant Queue',
|
||||||
|
'Line-In',
|
||||||
|
]),
|
||||||
}),
|
}),
|
||||||
'config_entry_id': <ANY>,
|
'config_entry_id': <ANY>,
|
||||||
'config_subentry_id': <ANY>,
|
'config_subentry_id': <ANY>,
|
||||||
@ -165,7 +171,7 @@
|
|||||||
'original_name': None,
|
'original_name': None,
|
||||||
'platform': 'music_assistant',
|
'platform': 'music_assistant',
|
||||||
'previous_unique_id': None,
|
'previous_unique_id': None,
|
||||||
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
'supported_features': <MediaPlayerEntityFeature: 8323007>,
|
||||||
'translation_key': None,
|
'translation_key': None,
|
||||||
'unique_id': '00:00:00:00:00:01',
|
'unique_id': '00:00:00:00:00:01',
|
||||||
'unit_of_measurement': None,
|
'unit_of_measurement': None,
|
||||||
@ -181,7 +187,11 @@
|
|||||||
]),
|
]),
|
||||||
'icon': 'mdi:speaker',
|
'icon': 'mdi:speaker',
|
||||||
'mass_player_type': 'player',
|
'mass_player_type': 'player',
|
||||||
'supported_features': <MediaPlayerEntityFeature: 8320959>,
|
'source_list': list([
|
||||||
|
'Music Assistant Queue',
|
||||||
|
'Line-In',
|
||||||
|
]),
|
||||||
|
'supported_features': <MediaPlayerEntityFeature: 8323007>,
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'media_player.test_player_1',
|
'entity_id': 'media_player.test_player_1',
|
||||||
|
@ -16,6 +16,7 @@ from syrupy.filters import paths
|
|||||||
|
|
||||||
from homeassistant.components.media_player import (
|
from homeassistant.components.media_player import (
|
||||||
ATTR_GROUP_MEMBERS,
|
ATTR_GROUP_MEMBERS,
|
||||||
|
ATTR_INPUT_SOURCE,
|
||||||
ATTR_MEDIA_ENQUEUE,
|
ATTR_MEDIA_ENQUEUE,
|
||||||
ATTR_MEDIA_REPEAT,
|
ATTR_MEDIA_REPEAT,
|
||||||
ATTR_MEDIA_SEEK_POSITION,
|
ATTR_MEDIA_SEEK_POSITION,
|
||||||
@ -25,6 +26,7 @@ from homeassistant.components.media_player import (
|
|||||||
DOMAIN as MEDIA_PLAYER_DOMAIN,
|
DOMAIN as MEDIA_PLAYER_DOMAIN,
|
||||||
SERVICE_CLEAR_PLAYLIST,
|
SERVICE_CLEAR_PLAYLIST,
|
||||||
SERVICE_JOIN,
|
SERVICE_JOIN,
|
||||||
|
SERVICE_SELECT_SOURCE,
|
||||||
SERVICE_UNJOIN,
|
SERVICE_UNJOIN,
|
||||||
MediaPlayerEntityFeature,
|
MediaPlayerEntityFeature,
|
||||||
)
|
)
|
||||||
@ -620,6 +622,31 @@ async def test_media_player_get_queue_action(
|
|||||||
assert response == snapshot(exclude=paths(f"{entity_id}.elapsed_time"))
|
assert response == snapshot(exclude=paths(f"{entity_id}.elapsed_time"))
|
||||||
|
|
||||||
|
|
||||||
|
async def test_media_player_select_source_action(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
music_assistant_client: MagicMock,
|
||||||
|
) -> None:
|
||||||
|
"""Test media_player entity select source action."""
|
||||||
|
await setup_integration_from_fixtures(hass, music_assistant_client)
|
||||||
|
entity_id = "media_player.test_player_1"
|
||||||
|
mass_player_id = "00:00:00:00:00:01"
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
await hass.services.async_call(
|
||||||
|
MEDIA_PLAYER_DOMAIN,
|
||||||
|
SERVICE_SELECT_SOURCE,
|
||||||
|
{
|
||||||
|
ATTR_ENTITY_ID: entity_id,
|
||||||
|
ATTR_INPUT_SOURCE: "linein",
|
||||||
|
},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert music_assistant_client.send_command.call_count == 1
|
||||||
|
assert music_assistant_client.send_command.call_args == call(
|
||||||
|
"players/cmd/select_source", player_id=mass_player_id, source="linein"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_media_player_supported_features(
|
async def test_media_player_supported_features(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
music_assistant_client: MagicMock,
|
music_assistant_client: MagicMock,
|
||||||
@ -652,6 +679,7 @@ async def test_media_player_supported_features(
|
|||||||
| MediaPlayerEntityFeature.TURN_ON
|
| MediaPlayerEntityFeature.TURN_ON
|
||||||
| MediaPlayerEntityFeature.TURN_OFF
|
| MediaPlayerEntityFeature.TURN_OFF
|
||||||
| MediaPlayerEntityFeature.SEARCH_MEDIA
|
| MediaPlayerEntityFeature.SEARCH_MEDIA
|
||||||
|
| MediaPlayerEntityFeature.SELECT_SOURCE
|
||||||
)
|
)
|
||||||
assert state.attributes["supported_features"] == expected_features
|
assert state.attributes["supported_features"] == expected_features
|
||||||
# remove power control capability from player, trigger subscription callback
|
# remove power control capability from player, trigger subscription callback
|
||||||
|
Loading…
x
Reference in New Issue
Block a user