From 53e63181ca8ebd1743fc72609dc22855ce4135e7 Mon Sep 17 00:00:00 2001 From: mj23000 Date: Tue, 30 May 2023 17:43:37 +0200 Subject: [PATCH] Add beolink_set_relative_volume custom service Formatting tweaks --- custom_components/bangolufsen/__init__.py | 7 +--- custom_components/bangolufsen/config_flow.py | 2 +- custom_components/bangolufsen/const.py | 8 +++- custom_components/bangolufsen/coordinator.py | 2 +- custom_components/bangolufsen/manifest.json | 2 +- custom_components/bangolufsen/media_player.py | 40 ++++++++++++++++++- custom_components/bangolufsen/services.yaml | 37 ++++++++++++----- 7 files changed, 78 insertions(+), 20 deletions(-) diff --git a/custom_components/bangolufsen/__init__.py b/custom_components/bangolufsen/__init__.py index 2d3373f..03969b1 100644 --- a/custom_components/bangolufsen/__init__.py +++ b/custom_components/bangolufsen/__init__.py @@ -7,12 +7,7 @@ from urllib3.exceptions import MaxRetryError from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_HOST, - CONF_MODEL, - CONF_NAME, - Platform, -) +from homeassistant.const import CONF_HOST, CONF_MODEL, CONF_NAME, Platform from homeassistant.core import HomeAssistant from homeassistant.helpers.event import async_call_later diff --git a/custom_components/bangolufsen/config_flow.py b/custom_components/bangolufsen/config_flow.py index 04bfc6b..6e463fd 100644 --- a/custom_components/bangolufsen/config_flow.py +++ b/custom_components/bangolufsen/config_flow.py @@ -38,9 +38,9 @@ MAX_RETRY_ERROR, MAX_VOLUME_RANGE, NEW_CONNECTION_ERROR, + NOT_MOZART_DEVICE, VALUE_ERROR, VOLUME_STEP_RANGE, - NOT_MOZART_DEVICE, ) diff --git a/custom_components/bangolufsen/const.py b/custom_components/bangolufsen/const.py index 0335ddb..b68b037 100644 --- a/custom_components/bangolufsen/const.py +++ b/custom_components/bangolufsen/const.py @@ -337,13 +337,19 @@ class SupportEnum(Enum): BEOLINK_LEADER_COMMAND: Final[str] = "BEOLINK_LEADER_COMMAND" BEOLINK_LISTENER_COMMAND: Final[str] = "BEOLINK_LISTENER_COMMAND" BEOLINK_VOLUME: Final[str] = "BEOLINK_VOLUME" +BEOLINK_RELATIVE_VOLUME: Final[str] = "BEOLINK_RELATIVE_VOLUME" # Misc. NO_METADATA: Final[tuple] = (None, "", 0) # Valid commands and their expected parameter type for beolink_command service -FLOAT_PARAMETERS: Final[tuple] = ("set_volume_level", "media_seek", float) +FLOAT_PARAMETERS: Final[tuple] = ( + "set_volume_level", + "media_seek", + "set_relative_volume_level", + float, +) BOOL_PARAMETERS: Final[tuple] = ("mute_volume", bool) STR_PARAMETERS: Final[tuple] = ("select_source", str) NONE_PARAMETERS: Final[tuple] = ( diff --git a/custom_components/bangolufsen/coordinator.py b/custom_components/bangolufsen/coordinator.py index c671095..66b2f59 100644 --- a/custom_components/bangolufsen/coordinator.py +++ b/custom_components/bangolufsen/coordinator.py @@ -3,7 +3,7 @@ from __future__ import annotations -from datetime import timedelta, datetime +from datetime import datetime, timedelta import logging from typing import TypedDict diff --git a/custom_components/bangolufsen/manifest.json b/custom_components/bangolufsen/manifest.json index 5b14eb7..91f72f1 100644 --- a/custom_components/bangolufsen/manifest.json +++ b/custom_components/bangolufsen/manifest.json @@ -7,6 +7,6 @@ "iot_class": "local_push", "issue_tracker": "https://github.com/bang-olufsen/bangolufsen-hacs/issues", "requirements": ["mozart-api==2.5.3.123.1"], - "version": "1.0.6", + "version": "1.1.0", "zeroconf": ["_bangolufsen._tcp.local."] } diff --git a/custom_components/bangolufsen/media_player.py b/custom_components/bangolufsen/media_player.py index 74bd9ad..9ecbf33 100644 --- a/custom_components/bangolufsen/media_player.py +++ b/custom_components/bangolufsen/media_player.py @@ -79,6 +79,7 @@ HIDDEN_SOURCE_IDS, NO_METADATA, VALID_MEDIA_TYPES, + BEOLINK_RELATIVE_VOLUME, ArtSizeEnum, BangOlufsenEntity, BangOlufsenMediaType, @@ -190,6 +191,12 @@ async def async_setup_entry( func="async_beolink_set_volume", ) + platform.async_register_entity_service( + name="beolink_set_relative_volume", + schema={vol.Required("volume_level"): cv.string}, + func="async_beolink_set_relative_volume", + ) + platform.async_register_entity_service( name="beolink_leader_command", schema={ @@ -334,6 +341,11 @@ async def async_added_to_hass(self) -> None: f"{self._beolink_jid}_{BEOLINK_VOLUME}", self.async_beolink_set_volume, ), + async_dispatcher_connect( + self.hass, + f"{self._beolink_jid}_{BEOLINK_RELATIVE_VOLUME}", + self.async_beolink_set_relative_volume, + ), ] ) @@ -454,7 +466,7 @@ async def _update_sources(self) -> None: # Combine the source dicts self._sources = self._audio_sources | self._video_sources - # HASS won't be necessarily be running the first time this method is run + # HASS won't necessarily be running the first time this method is run if self.hass.is_running: self.async_write_ha_state() @@ -1212,6 +1224,32 @@ async def async_beolink_set_volume(self, volume_level: str) -> None: volume_level, ) + async def async_set_relative_volume_level(self, volume: float) -> None: + """Set a volume level relative to the current level.""" + await self.async_set_volume_level(volume=self.volume_level + volume) + + async def async_beolink_set_relative_volume(self, volume_level: str) -> None: + """Set a volume level to adjust current volume level for all connected Beolink devices.""" + + # Get the remote leader to send the volume command to listeners + if self._remote_leader is not None: + async_dispatcher_send( + self.hass, + f"{self._remote_leader.jid}_{BEOLINK_RELATIVE_VOLUME}", + volume_level, + ) + + else: + await self.async_set_relative_volume_level(volume=float(volume_level)) + + for beolink_listener in self._beolink_listeners: + async_dispatcher_send( + self.hass, + f"{beolink_listener.jid}_{BEOLINK_LISTENER_COMMAND}", + "set_relative_volume_level", + volume_level, + ) + async def async_overlay_audio( self, uri: str | None = None, diff --git a/custom_components/bangolufsen/services.yaml b/custom_components/bangolufsen/services.yaml index 912608b..4309721 100644 --- a/custom_components/bangolufsen/services.yaml +++ b/custom_components/bangolufsen/services.yaml @@ -98,6 +98,24 @@ beolink_set_volume: selector: text: +beolink_set_relative_volume: + name: Beolink set relative volume + description: Set a volume level relative to the current level of all connected Beolink devices. + target: + entity: + integration: bangolufsen + domain: media_player + device: + integration: bangolufsen + fields: + volume_level: + name: Volume level + description: Specify the volume level. + required: true + example: 0.2 + selector: + text: + beolink_leader_command: name: Beolink leader command description: Send a media_player command to Beolink leader. @@ -116,19 +134,20 @@ beolink_leader_command: selector: select: options: - - "set_volume_level" - - "media_seek" - - "mute_volume" - - "select_source" - - "volume_up" - - "volume_down" - - "media_play_pause" + - "media_next_track" - "media_pause" + - "media_play_pause" - "media_play" - - "media_stop" - - "media_next_track" - "media_previous_track" + - "media_seek" + - "media_stop" + - "mute_volume" + - "select_source" + - "set_relative_volume_level" + - "set_volume_level" - "toggle" + - "volume_down" + - "volume_up" parameter: name: Parameter description: Specify the media_player command's parameter.