Skip to content

Commit

Permalink
Update API
Browse files Browse the repository at this point in the history
Improve async_beolink_expand stability for many devices
Add "Is playing" check and error to async_beolink_expand
Avoid setting volume_level property value
  • Loading branch information
mj23000 committed Jan 22, 2025
1 parent f966825 commit efaf6ff
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 22 deletions.
4 changes: 2 additions & 2 deletions custom_components/bang_olufsen/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"integration_type": "device",
"iot_class": "local_push",
"issue_tracker": "https://github.com/bang-olufsen/bang_olufsen-hacs/issues",
"requirements": ["mozart-api==4.1.1.116.5"],
"version": "3.4.2",
"requirements": ["mozart-api==4.1.1.116.6"],
"version": "3.4.3",
"zeroconf": ["_bangolufsen._tcp.local.", "_zenith._tcp.local."]
}
55 changes: 35 additions & 20 deletions custom_components/bang_olufsen/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from aiohttp import ClientConnectorError
from mozart_api import __version__ as MOZART_API_VERSION
from mozart_api.exceptions import ApiException, NotFoundException
from mozart_api.exceptions import ApiException
from mozart_api.models import (
Action,
Art,
Expand Down Expand Up @@ -77,6 +77,7 @@
async_get_current_platform,
)
from homeassistant.util.dt import utcnow
from homeassistant.util.json import JsonObjectType

from . import MANUFACTURER, MozartConfigEntry, set_platform_initialized
from .const import (
Expand Down Expand Up @@ -159,7 +160,7 @@ async def async_setup_entry(
vol.Optional("source_id"): vol.In(BEOLINK_JOIN_SOURCES),
},
func="async_beolink_join",
supports_response=SupportsResponse.OPTIONAL,
supports_response=SupportsResponse.ONLY,
)

platform.async_register_entity_service(
Expand All @@ -176,7 +177,7 @@ async def async_setup_entry(
),
},
func="async_beolink_expand",
supports_response=SupportsResponse.OPTIONAL,
supports_response=SupportsResponse.ONLY,
)

platform.async_register_entity_service(
Expand Down Expand Up @@ -1184,7 +1185,7 @@ async def async_beolink_join(

async def async_beolink_expand(
self, beolink_jids: list[str] | None = None, all_discovered: bool = False
) -> None:
) -> ServiceResponse:
"""Expand a Beolink multi-room experience with a device or devices."""

# Ensure that the current source is expandable
Expand All @@ -1198,26 +1199,38 @@ async def async_beolink_expand(
},
)

# Ensure that the current device is playing
if self.state != MediaPlayerState.PLAYING:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="beolink_not_playing",
)

result: JsonObjectType = {}

# Expand to all discovered devices
if all_discovered:
peers = await self._client.get_beolink_peers()

for peer in peers:
try:
await self._client.post_beolink_expand(jid=peer.jid)
except NotFoundException:
_LOGGER.warning("Unable to expand to %s", peer.jid)
response = await self._client.async_post_beolink_expand(peer.jid)

# Add result
result[peer.jid] = {
"result": response if response is True else type(response).__name__
}

# Try to expand to all defined devices
elif beolink_jids:
for beolink_jid in beolink_jids:
try:
await self._client.post_beolink_expand(jid=beolink_jid)
except NotFoundException:
_LOGGER.warning(
"Unable to expand to %s. Is the device available on the network?",
beolink_jid,
)
response = await self._client.async_post_beolink_expand(beolink_jid)

# Add result
result[beolink_jid] = {
"result": response if response is True else type(response).__name__
}

return result

async def async_beolink_unexpand(self, beolink_jids: list[str]) -> None:
"""Unexpand a Beolink multi-room experience with a device or devices."""
Expand Down Expand Up @@ -1329,17 +1342,19 @@ async def async_beolink_set_volume(self, volume_level: str) -> None:

async def async_set_relative_volume_level(self, volume: float) -> None:
"""Set a volume level relative to the current level."""
current_volume_level = self.volume_level

# Handle if the volume level is not set
if self.volume_level is None:
self.volume_level = 0
if current_volume_level is None:
current_volume_level = 0

# Ensure that volume level behaves as expected
if self.volume_level + volume >= 1.0:
if current_volume_level + volume >= 1.0:
new_volume = 1.0
elif self.volume_level + volume <= 0:
elif current_volume_level + volume <= 0:
new_volume = 0.0
else:
new_volume = self.volume_level + volume
new_volume = current_volume_level + volume

await self.async_set_volume_level(volume=new_volume)

Expand Down
3 changes: 3 additions & 0 deletions custom_components/bang_olufsen/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,9 @@
"invalid_source": {
"message": "Invalid source: {invalid_source}. Valid sources are: {valid_sources}"
},
"beolink_not_playing": {
"message": "Can't Beolink expand from a non-playing device."
},
"invalid_media_type": {
"message": "{invalid_media_type} is an invalid type. Valid values are: {valid_media_types}."
},
Expand Down
3 changes: 3 additions & 0 deletions custom_components/bang_olufsen/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1241,6 +1241,9 @@
}
},
"exceptions": {
"beolink_not_playing": {
"message": "Can't Beolink expand from a non-playing device."
},
"invalid_beolink_parameter": {
"message": "Invalid parameter: {parameter} for {command} which expects a parameter of type: {parameter_type}."
},
Expand Down

0 comments on commit efaf6ff

Please sign in to comment.