From c11dd58c1d32f5767d0e124d2f5ac81d5194d532 Mon Sep 17 00:00:00 2001 From: Greg Dowling Date: Thu, 12 Oct 2023 11:52:01 +0100 Subject: [PATCH] Improve handling of roon media players with fixed and incremental volume (#99819) --- homeassistant/components/roon/media_player.py | 45 +++++++++++++------ 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/roon/media_player.py b/homeassistant/components/roon/media_player.py index d56bacd67c4ab..d6128d2672358 100644 --- a/homeassistant/components/roon/media_player.py +++ b/homeassistant/components/roon/media_player.py @@ -92,7 +92,6 @@ class RoonDevice(MediaPlayerEntity): MediaPlayerEntityFeature.BROWSE_MEDIA | MediaPlayerEntityFeature.GROUPING | MediaPlayerEntityFeature.PAUSE - | MediaPlayerEntityFeature.VOLUME_SET | MediaPlayerEntityFeature.STOP | MediaPlayerEntityFeature.PREVIOUS_TRACK | MediaPlayerEntityFeature.NEXT_TRACK @@ -104,7 +103,6 @@ class RoonDevice(MediaPlayerEntity): | MediaPlayerEntityFeature.VOLUME_MUTE | MediaPlayerEntityFeature.PLAY | MediaPlayerEntityFeature.PLAY_MEDIA - | MediaPlayerEntityFeature.VOLUME_STEP ) def __init__(self, server, player_data): @@ -124,6 +122,8 @@ def __init__(self, server, player_data): self._attr_shuffle = False self._attr_media_image_url = None self._attr_volume_level = 0 + self._volume_fixed = True + self._volume_incremental = False self.update_data(player_data) async def async_added_to_hass(self) -> None: @@ -190,12 +190,21 @@ def _parse_volume(cls, player_data): "level": 0, "step": 0, "muted": False, + "fixed": True, + "incremental": False, } try: volume_data = player_data["volume"] - volume_muted = volume_data["is_muted"] - volume_step = convert(volume_data["step"], int, 0) + except KeyError: + return volume + + volume["fixed"] = False + volume["incremental"] = volume_data["type"] == "incremental" + volume["muted"] = volume_data.get("is_muted", False) + volume["step"] = convert(volume_data.get("step"), int, 0) + + try: volume_max = volume_data["max"] volume_min = volume_data["min"] raw_level = convert(volume_data["value"], float, 0) @@ -204,15 +213,9 @@ def _parse_volume(cls, player_data): volume_percentage_factor = volume_range / 100 level = (raw_level - volume_min) / volume_percentage_factor - volume_level = convert(level, int, 0) / 100 - + volume["level"] = convert(level, int, 0) / 100 except KeyError: - # catch KeyError pass - else: - volume["muted"] = volume_muted - volume["step"] = volume_step - volume["level"] = volume_level return volume @@ -288,6 +291,16 @@ def update_state(self): self._attr_is_volume_muted = volume["muted"] self._attr_volume_step = volume["step"] self._attr_volume_level = volume["level"] + self._volume_fixed = volume["fixed"] + self._volume_incremental = volume["incremental"] + if not self._volume_fixed: + self._attr_supported_features = ( + self._attr_supported_features | MediaPlayerEntityFeature.VOLUME_STEP + ) + if not self._volume_incremental: + self._attr_supported_features = ( + self._attr_supported_features | MediaPlayerEntityFeature.VOLUME_SET + ) now_playing = self._parse_now_playing(self.player_data) self._attr_media_title = now_playing["title"] @@ -359,11 +372,17 @@ def mute_volume(self, mute=True): def volume_up(self) -> None: """Send new volume_level to device.""" - self._server.roonapi.change_volume_percent(self.output_id, 3) + if self._volume_incremental: + self._server.roonapi.change_volume_raw(self.output_id, 1, "relative_step") + else: + self._server.roonapi.change_volume_percent(self.output_id, 3) def volume_down(self) -> None: """Send new volume_level to device.""" - self._server.roonapi.change_volume_percent(self.output_id, -3) + if self._volume_incremental: + self._server.roonapi.change_volume_raw(self.output_id, -1, "relative_step") + else: + self._server.roonapi.change_volume_percent(self.output_id, -3) def turn_on(self) -> None: """Turn on device (if supported)."""