Prefer source name in Music Assistant integration (#145622)

Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
This commit is contained in:
Marcel van der Veldt 2025-05-26 17:07:05 +02:00 committed by GitHub
parent 13d7234f97
commit c2a5e1aaf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 24 additions and 9 deletions

View File

@ -42,7 +42,7 @@ from homeassistant.components.media_player import (
)
from homeassistant.const import ATTR_NAME, STATE_OFF
from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse
from homeassistant.exceptions import HomeAssistantError
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import config_validation as cv, entity_registry as er
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
@ -227,6 +227,7 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
self._set_supported_features()
self._attr_device_class = MediaPlayerDeviceClass.SPEAKER
self._prev_time: float = 0
self._source_list_mapping: dict[str, str] = {}
async def async_added_to_hass(self) -> None:
"""Register callbacks."""
@ -292,10 +293,20 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
self._attr_state = MediaPlayerState(player.state.value)
else:
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
]
# active source and source list (translate to HA source names)
source_mappings: dict[str, str] = {}
active_source_name: str | None = None
for source in player.source_list:
if source.id == player.active_source:
active_source_name = source.name
if source.passive:
# ignore passive sources because HA does not differentiate between
# active and passive sources
continue
source_mappings[source.name] = source.id
self._attr_source_list = list(source_mappings.keys())
self._source_list_mapping = source_mappings
self._attr_source = active_source_name
group_members: list[str] = []
if player.group_childs:
@ -466,7 +477,12 @@ class MusicAssistantPlayer(MusicAssistantEntity, MediaPlayerEntity):
@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)
source_id = self._source_list_mapping.get(source)
if source_id is None:
raise ServiceValidationError(
f"Source '{source}' not found for player {self.name}"
)
await self.mass.players.player_command_select_source(self.player_id, source_id)
@catch_musicassistant_error
async def _async_handle_play_media(

View File

@ -54,7 +54,7 @@
'media_duration': 300,
'media_position': 0,
'media_title': 'Test Track',
'source': 'spotify',
'source': 'Spotify Connect',
'supported_features': <MediaPlayerEntityFeature: 8320959>,
'volume_level': 0.2,
}),
@ -126,7 +126,6 @@
'media_title': 'November Rain',
'repeat': 'all',
'shuffle': True,
'source': 'test_group_player_1',
'supported_features': <MediaPlayerEntityFeature: 8320959>,
'volume_level': 0.06,
}),

View File

@ -637,7 +637,7 @@ async def test_media_player_select_source_action(
SERVICE_SELECT_SOURCE,
{
ATTR_ENTITY_ID: entity_id,
ATTR_INPUT_SOURCE: "linein",
ATTR_INPUT_SOURCE: "Line-In",
},
blocking=True,
)