From: Marcel van der Veldt Date: Sun, 21 Jan 2024 01:50:38 +0000 (+0100) Subject: A few small tweaks (#1012) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=815da908194ac88d728d25455cf11e606ba5bca1;p=music-assistant-server.git A few small tweaks (#1012) --- diff --git a/music_assistant/common/models/config_entries.py b/music_assistant/common/models/config_entries.py index bc02e6ba..1d822c3c 100644 --- a/music_assistant/common/models/config_entries.py +++ b/music_assistant/common/models/config_entries.py @@ -18,6 +18,7 @@ from music_assistant.constants import ( CONF_EQ_MID, CONF_EQ_TREBLE, CONF_FLOW_MODE, + CONF_HIDE_PLAYER, CONF_LOG_LEVEL, CONF_OUTPUT_CHANNELS, CONF_VOLUME_NORMALIZATION, @@ -404,3 +405,14 @@ CONF_ENTRY_CROSSFADE_DURATION = ConfigEntry( depends_on=CONF_CROSSFADE, advanced=True, ) + +CONF_ENTRY_HIDE_PLAYER = ConfigEntry( + key=CONF_HIDE_PLAYER, + type=ConfigEntryType.BOOLEAN, + label="Hide this player in the user interface", + default_value=False, + description="Hide this player in the user interface. \n\n" + "Note that it can still be controlled and it will also show up in any " + "sync groups the player belongs to.", + advanced=True, +) diff --git a/music_assistant/common/models/player.py b/music_assistant/common/models/player.py index 8dbeb126..157a1674 100644 --- a/music_assistant/common/models/player.py +++ b/music_assistant/common/models/player.py @@ -84,10 +84,10 @@ class Player(DataClassDictMixin): # nor will it be added to the HA integration enabled: bool = True - # hidden_by: if the player is enabled + # hidden: if the player is hidden in the UI # will be set by the player manager based on config - # a disabled player is hidden in the UI only but can still be controlled - hidden_by: set = field(default_factory=set) + # a hidden player is hidden in the UI only but can still be controlled + hidden: bool = False # group_volume: if the player is a player group or syncgroup master, # this will return the average volume of all child players diff --git a/music_assistant/constants.py b/music_assistant/constants.py index 145e655a..65d2c40a 100755 --- a/music_assistant/constants.py +++ b/music_assistant/constants.py @@ -52,6 +52,7 @@ CONF_AUTO_PLAY: Final[str] = "auto_play" CONF_GROUP_PLAYERS: Final[str] = "group_players" CONF_CROSSFADE: Final[str] = "crossfade" CONF_GROUP_MEMBERS: Final[str] = "group_members" +CONF_HIDE_PLAYER: Final[str] = "hide_player" # config default values DEFAULT_HOST: Final[str] = "0.0.0.0" diff --git a/music_assistant/server/controllers/players.py b/music_assistant/server/controllers/players.py index c2e32bbe..cced5ca3 100755 --- a/music_assistant/server/controllers/players.py +++ b/music_assistant/server/controllers/players.py @@ -30,6 +30,7 @@ from music_assistant.common.models.queue_item import QueueItem from music_assistant.constants import ( CONF_AUTO_PLAY, CONF_GROUP_MEMBERS, + CONF_HIDE_PLAYER, CONF_PLAYERS, ROOT_LOGGER_NAME, SYNCGROUP_PREFIX, @@ -234,7 +235,7 @@ class PlayerController(CoreController): player.volume_level = player.group_volume # prefer any overridden name from config player.display_name = ( - self.mass.config.get(f"{CONF_PLAYERS}/{player_id}/name") + self.mass.config.get_raw_player_config_value(player.player_id, "name") or player.name or player.player_id ) @@ -247,7 +248,9 @@ class PlayerController(CoreController): # mark player as powered if its playing # could happen for players that do not officially support power commands player.powered = True - + player.hidden = self.mass.config.get_raw_player_config_value( + player.player_id, CONF_HIDE_PLAYER, False + ) # handle syncgroup - get attributes from first player that has this group as source if player.player_id.startswith(SYNCGROUP_PREFIX): if sync_leader := self.get_sync_leader(player): diff --git a/music_assistant/server/models/player_provider.py b/music_assistant/server/models/player_provider.py index f6d62eaa..85f03c53 100644 --- a/music_assistant/server/models/player_provider.py +++ b/music_assistant/server/models/player_provider.py @@ -6,6 +6,7 @@ from typing import TYPE_CHECKING from music_assistant.common.models.config_entries import ( CONF_ENTRY_AUTO_PLAY, + CONF_ENTRY_HIDE_PLAYER, CONF_ENTRY_VOLUME_NORMALIZATION, CONF_ENTRY_VOLUME_NORMALIZATION_TARGET, ConfigEntry, @@ -38,6 +39,7 @@ class PlayerProvider(Provider): CONF_ENTRY_VOLUME_NORMALIZATION, CONF_ENTRY_AUTO_PLAY, CONF_ENTRY_VOLUME_NORMALIZATION_TARGET, + CONF_ENTRY_HIDE_PLAYER, ) if player_id.startswith(SYNCGROUP_PREFIX): # add default entries for syncgroups diff --git a/music_assistant/server/providers/airplay/__init__.py b/music_assistant/server/providers/airplay/__init__.py index c5808589..6d75afc4 100644 --- a/music_assistant/server/providers/airplay/__init__.py +++ b/music_assistant/server/providers/airplay/__init__.py @@ -134,7 +134,10 @@ class AirplayProvider(PlayerProvider): @property def supported_features(self) -> tuple[ProviderFeature, ...]: """Return the features supported by this Provider.""" - return (ProviderFeature.SYNC_PLAYERS,) + # for now do not allow creation of airplay groups + # in preparation of new airplay provider coming up soon + # return (ProviderFeature.SYNC_PLAYERS,) + return tuple() async def handle_setup(self) -> None: """Handle async initialization of the provider.""" @@ -287,6 +290,9 @@ class AirplayProvider(PlayerProvider): manufacturer="Generic", ) player.supports_24bit = False + # disable sonos by default + if "sonos" in player.name.lower() or "rincon" in player.name.lower(): + player.enabled_by_default = False # extend info from the discovery xml async with aiofiles.open(self._config_file, "r") as _file: @@ -301,20 +307,10 @@ class AirplayProvider(PlayerProvider): udn = device_elem.find("udn").text udn_name = udn.split("@")[1].split("._")[0] player.name = udn_name - # disable sonos by default - if "sonos" in (device_elem.find("friendly_name").text or "").lower(): - player.enabled_by_default = False - # TODO: query more info directly from the device - player.device_info = DeviceInfo( - model="Airplay device", - address=player.device_info.address, - manufacturer="SONOS", - ) break def _handle_player_update_callback(self, player: Player) -> None: """Handle player update callback from slimproto source player.""" - # we could override anything on the player object here async def _get_bridge_binary(self): """Find the correct bridge binary belonging to the platform."""