diff --git a/homeassistant/components/cambridge_audio/media_player.py b/homeassistant/components/cambridge_audio/media_player.py index 27be2a60e52..c1f7cfcc4bc 100644 --- a/homeassistant/components/cambridge_audio/media_player.py +++ b/homeassistant/components/cambridge_audio/media_player.py @@ -4,13 +4,20 @@ from __future__ import annotations from datetime import datetime -from aiostreammagic import StreamMagicClient +from aiostreammagic import ( + RepeatMode as CambridgeRepeatMode, + ShuffleMode, + StreamMagicClient, + TransportControl, +) from homeassistant.components.media_player import ( + MediaPlayerDeviceClass, MediaPlayerEntity, MediaPlayerEntityFeature, MediaPlayerState, MediaType, + RepeatMode, ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @@ -30,6 +37,16 @@ PREAMP_FEATURES = ( | MediaPlayerEntityFeature.VOLUME_STEP ) +TRANSPORT_FEATURES: dict[TransportControl, MediaPlayerEntityFeature] = { + TransportControl.PLAY: MediaPlayerEntityFeature.PLAY, + TransportControl.PAUSE: MediaPlayerEntityFeature.PAUSE, + TransportControl.TRACK_NEXT: MediaPlayerEntityFeature.NEXT_TRACK, + TransportControl.TRACK_PREVIOUS: MediaPlayerEntityFeature.PREVIOUS_TRACK, + TransportControl.TOGGLE_REPEAT: MediaPlayerEntityFeature.REPEAT_SET, + TransportControl.TOGGLE_SHUFFLE: MediaPlayerEntityFeature.SHUFFLE_SET, + TransportControl.SEEK: MediaPlayerEntityFeature.SEEK, +} + async def async_setup_entry( hass: HomeAssistant, @@ -46,6 +63,7 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): _attr_name = None _attr_media_content_type = MediaType.MUSIC + _attr_device_class = MediaPlayerDeviceClass.RECEIVER def __init__(self, client: StreamMagicClient) -> None: """Initialize an Cambridge Audio entity.""" @@ -71,16 +89,12 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): features = BASE_FEATURES if self.client.state.pre_amp_mode: features |= PREAMP_FEATURES - if "play_pause" in controls: + if TransportControl.PLAY_PAUSE in controls: features |= MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.PAUSE - if "play" in controls: - features |= MediaPlayerEntityFeature.PLAY - if "pause" in controls: - features |= MediaPlayerEntityFeature.PAUSE - if "track_next" in controls: - features |= MediaPlayerEntityFeature.NEXT_TRACK - if "track_previous" in controls: - features |= MediaPlayerEntityFeature.PREVIOUS_TRACK + for control in controls: + feature = TRANSPORT_FEATURES.get(control) + if feature: + features |= feature return features @property @@ -164,6 +178,22 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): volume = self.client.state.volume_percent or 0 return volume / 100 + @property + def shuffle(self) -> bool | None: + """Current shuffle configuration.""" + mode_shuffle = self.client.play_state.mode_shuffle + if not mode_shuffle: + return False + return mode_shuffle != ShuffleMode.OFF + + @property + def repeat(self) -> RepeatMode | None: + """Current repeat configuration.""" + mode_repeat = RepeatMode.OFF + if self.client.play_state.mode_repeat == CambridgeRepeatMode.ALL: + mode_repeat = RepeatMode.ALL + return mode_repeat + async def async_media_play_pause(self) -> None: """Toggle play/pause the current media.""" await self.client.play_pause() @@ -171,7 +201,10 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): async def async_media_pause(self) -> None: """Pause the current media.""" controls = self.client.now_playing.controls - if "pause" not in controls and "play_pause" in controls: + if ( + TransportControl.PAUSE not in controls + and TransportControl.PLAY_PAUSE in controls + ): await self.client.play_pause() else: await self.client.pause() @@ -182,8 +215,14 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): async def async_media_play(self) -> None: """Play the current media.""" - if self.state == MediaPlayerState.PAUSED: + controls = self.client.now_playing.controls + if ( + TransportControl.PLAY not in controls + and TransportControl.PLAY_PAUSE in controls + ): await self.client.play_pause() + else: + await self.client.play() async def async_media_next_track(self) -> None: """Skip to the next track.""" @@ -222,7 +261,22 @@ class CambridgeAudioDevice(CambridgeAudioEntity, MediaPlayerEntity): async def async_mute_volume(self, mute: bool) -> None: """Set the mute state.""" - if mute: - await self.client.mute() - else: - await self.client.unmute() + await self.client.set_mute(mute) + + async def async_media_seek(self, position: float) -> None: + """Seek to a position in the current media.""" + await self.client.media_seek(int(position)) + + async def async_set_shuffle(self, shuffle: bool) -> None: + """Set the shuffle mode for the current queue.""" + shuffle_mode = ShuffleMode.OFF + if shuffle: + shuffle_mode = ShuffleMode.ALL + await self.client.set_shuffle(shuffle_mode) + + async def async_set_repeat(self, repeat: RepeatMode) -> None: + """Set the repeat mode for the current queue.""" + repeat_mode = CambridgeRepeatMode.OFF + if repeat: + repeat_mode = CambridgeRepeatMode.ALL + await self.client.set_repeat(repeat_mode)