1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00

Add media content id attribute to Bang & Olufsen (#156597)

This commit is contained in:
Markus Jacobsen
2025-11-27 15:53:43 +01:00
committed by GitHub
parent 9ee7ed5cdb
commit f7c41e694c
5 changed files with 192 additions and 123 deletions

View File

@@ -17,8 +17,12 @@ from homeassistant.components.media_player import (
class BangOlufsenSource:
"""Class used for associating device source ids with friendly names. May not include all sources."""
DEEZER: Final[Source] = Source(name="Deezer", id="deezer")
LINE_IN: Final[Source] = Source(name="Line-In", id="lineIn")
NET_RADIO: Final[Source] = Source(name="B&O Radio", id="netRadio")
SPDIF: Final[Source] = Source(name="Optical", id="spdif")
TIDAL: Final[Source] = Source(name="Tidal", id="tidal")
UNKNOWN: Final[Source] = Source(name="Unknown Source", id="unknown")
URI_STREAMER: Final[Source] = Source(name="Audio Streamer", id="uriStreamer")
@@ -78,6 +82,16 @@ class BangOlufsenModel(StrEnum):
BEOREMOTE_ONE = "Beoremote One"
class BangOlufsenAttribute(StrEnum):
"""Enum for extra_state_attribute keys."""
BEOLINK = "beolink"
BEOLINK_PEERS = "peers"
BEOLINK_SELF = "self"
BEOLINK_LEADER = "leader"
BEOLINK_LISTENERS = "listeners"
# Physical "buttons" on devices
class BangOlufsenButtons(StrEnum):
"""Enum for device buttons."""

View File

@@ -82,6 +82,7 @@ from .const import (
FALLBACK_SOURCES,
MANUFACTURER,
VALID_MEDIA_TYPES,
BangOlufsenAttribute,
BangOlufsenMediaType,
BangOlufsenSource,
WebsocketNotification,
@@ -224,7 +225,8 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Beolink compatible sources
self._beolink_sources: dict[str, bool] = {}
self._remote_leader: BeolinkLeader | None = None
# Extra state attributes for showing Beolink: peer(s), listener(s), leader and self
# Extra state attributes:
# Beolink: peer(s), listener(s), leader and self
self._beolink_attributes: dict[str, dict[str, dict[str, str]]] = {}
async def async_added_to_hass(self) -> None:
@@ -436,7 +438,10 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
await self._async_update_beolink()
async def _async_update_beolink(self) -> None:
"""Update the current Beolink leader, listeners, peers and self."""
"""Update the current Beolink leader, listeners, peers and self.
Updates Home Assistant state.
"""
self._beolink_attributes = {}
@@ -445,18 +450,24 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Add Beolink self
self._beolink_attributes = {
"beolink": {"self": {self.device_entry.name: self._beolink_jid}}
BangOlufsenAttribute.BEOLINK: {
BangOlufsenAttribute.BEOLINK_SELF: {
self.device_entry.name: self._beolink_jid
}
}
}
# Add Beolink peers
peers = await self._client.get_beolink_peers()
if len(peers) > 0:
self._beolink_attributes["beolink"]["peers"] = {}
self._beolink_attributes[BangOlufsenAttribute.BEOLINK][
BangOlufsenAttribute.BEOLINK_PEERS
] = {}
for peer in peers:
self._beolink_attributes["beolink"]["peers"][peer.friendly_name] = (
peer.jid
)
self._beolink_attributes[BangOlufsenAttribute.BEOLINK][
BangOlufsenAttribute.BEOLINK_PEERS
][peer.friendly_name] = peer.jid
# Add Beolink listeners / leader
self._remote_leader = self._playback_metadata.remote_leader
@@ -477,7 +488,9 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
# Add self
group_members.append(self.entity_id)
self._beolink_attributes["beolink"]["leader"] = {
self._beolink_attributes[BangOlufsenAttribute.BEOLINK][
BangOlufsenAttribute.BEOLINK_LEADER
] = {
self._remote_leader.friendly_name: self._remote_leader.jid,
}
@@ -514,9 +527,9 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
beolink_listener.jid
)
break
self._beolink_attributes["beolink"]["listeners"] = (
beolink_listeners_attribute
)
self._beolink_attributes[BangOlufsenAttribute.BEOLINK][
BangOlufsenAttribute.BEOLINK_LISTENERS
] = beolink_listeners_attribute
self._attr_group_members = group_members
@@ -615,11 +628,18 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
return None
@property
def media_content_type(self) -> str:
def media_content_type(self) -> MediaType | str | None:
"""Return the current media type."""
# Hard to determine content type
if self._source_change.id == BangOlufsenSource.URI_STREAMER.id:
return MediaType.URL
content_type = {
BangOlufsenSource.URI_STREAMER.id: MediaType.URL,
BangOlufsenSource.DEEZER.id: BangOlufsenMediaType.DEEZER,
BangOlufsenSource.TIDAL.id: BangOlufsenMediaType.TIDAL,
BangOlufsenSource.NET_RADIO.id: BangOlufsenMediaType.RADIO,
}
# Hard to determine content type.
if self._source_change.id in content_type:
return content_type[self._source_change.id]
return MediaType.MUSIC
@property
@@ -632,6 +652,11 @@ class BangOlufsenMediaPlayer(BangOlufsenEntity, MediaPlayerEntity):
"""Return the current playback progress."""
return self._playback_progress.progress
@property
def media_content_id(self) -> str | None:
"""Return internal ID of Deezer, Tidal and radio stations."""
return self._playback_metadata.source_internal_id
@property
def media_image_url(self) -> str | None:
"""Return URL of the currently playing music."""

View File

@@ -168,6 +168,7 @@ TEST_PLAYBACK_METADATA = PlaybackContentMetadata(
title="Test title",
total_duration_seconds=123,
track=1,
source_internal_id="123",
)
TEST_PLAYBACK_ERROR = PlaybackError(error="Test error")
TEST_PLAYBACK_PROGRESS = PlaybackProgress(progress=123)

View File

@@ -2,16 +2,16 @@
# name: test_async_beolink_allstandby
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -50,16 +50,16 @@
# name: test_async_beolink_expand[all_discovered-True-None-log_messages0-3]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -71,7 +71,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -99,16 +99,16 @@
# name: test_async_beolink_expand[all_discovered-True-expand_side_effect1-log_messages1-3]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -120,7 +120,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -148,16 +148,16 @@
# name: test_async_beolink_expand[beolink_jids-parameter_value2-None-log_messages2-2]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -169,7 +169,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -197,16 +197,16 @@
# name: test_async_beolink_expand[beolink_jids-parameter_value3-expand_side_effect3-log_messages3-2]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -218,7 +218,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -246,16 +246,16 @@
# name: test_async_beolink_join[service_parameters0-method_parameters0]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -294,16 +294,16 @@
# name: test_async_beolink_join[service_parameters1-method_parameters1]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -342,16 +342,16 @@
# name: test_async_beolink_join[service_parameters2-method_parameters2]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -390,16 +390,16 @@
# name: test_async_beolink_join_invalid[service_parameters0-expected_result0]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -438,16 +438,16 @@
# name: test_async_beolink_join_invalid[service_parameters1-expected_result1]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -486,16 +486,16 @@
# name: test_async_beolink_join_invalid[service_parameters2-expected_result2]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -534,16 +534,16 @@
# name: test_async_beolink_unexpand
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -582,16 +582,16 @@
# name: test_async_join_players[group_members0-1-0]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -603,7 +603,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -631,16 +631,16 @@
# name: test_async_join_players[group_members0-1-0].1
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.22222222@products.bang-olufsen.com',
}),
}),
@@ -680,16 +680,16 @@
# name: test_async_join_players[group_members1-0-1]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -701,7 +701,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -729,16 +729,16 @@
# name: test_async_join_players[group_members1-0-1].1
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.22222222@products.bang-olufsen.com',
}),
}),
@@ -778,16 +778,16 @@
# name: test_async_join_players_invalid[source0-group_members0-expected_result0-invalid_source]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -828,16 +828,16 @@
# name: test_async_join_players_invalid[source0-group_members0-expected_result0-invalid_source].1
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.22222222@products.bang-olufsen.com',
}),
}),
@@ -877,16 +877,16 @@
# name: test_async_join_players_invalid[source1-group_members1-expected_result1-invalid_grouping_entity]
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -898,7 +898,7 @@
'listener_not_in_hass-1111.1111111.33333333@products.bang-olufsen.com',
'listener_not_in_hass-1111.1111111.44444444@products.bang-olufsen.com',
]),
'media_content_type': <MediaType.MUSIC: 'music'>,
'media_content_type': <BangOlufsenMediaType.TIDAL: 'tidal'>,
'repeat': <RepeatMode.OFF: 'off'>,
'shuffle': False,
'sound_mode': 'Test Listening Mode (123)',
@@ -926,16 +926,16 @@
# name: test_async_join_players_invalid[source1-group_members1-expected_result1-invalid_grouping_entity].1
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.22222222@products.bang-olufsen.com',
}),
}),
@@ -975,16 +975,16 @@
# name: test_async_unjoin_player
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -1023,15 +1023,15 @@
# name: test_async_update_beolink_listener
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'leader': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LEADER: 'leader'>: dict({
'Laundry room Core': '1111.1111111.22222222@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.11111111@products.bang-olufsen.com',
}),
}),
@@ -1069,16 +1069,16 @@
# name: test_async_update_beolink_listener.1
StateSnapshot({
'attributes': ReadOnlyDict({
'beolink': dict({
'listeners': dict({
<BangOlufsenAttribute.BEOLINK: 'beolink'>: dict({
<BangOlufsenAttribute.BEOLINK_LISTENERS: 'listeners'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'peers': dict({
<BangOlufsenAttribute.BEOLINK_PEERS: 'peers'>: dict({
'Bedroom Premiere': '1111.1111111.33333333@products.bang-olufsen.com',
'Lounge room Balance': '1111.1111111.44444444@products.bang-olufsen.com',
}),
'self': dict({
<BangOlufsenAttribute.BEOLINK_SELF: 'self'>: dict({
'Living room Balance': '1111.1111111.22222222@products.bang-olufsen.com',
}),
}),

View File

@@ -24,6 +24,7 @@ from homeassistant.components.bang_olufsen.const import (
BANG_OLUFSEN_REPEAT_FROM_HA,
BANG_OLUFSEN_STATES,
DOMAIN,
BangOlufsenMediaType,
BangOlufsenSource,
)
from homeassistant.components.media_player import (
@@ -260,6 +261,7 @@ async def test_async_update_playback_metadata(
assert ATTR_MEDIA_ALBUM_ARTIST not in states.attributes
assert ATTR_MEDIA_TRACK not in states.attributes
assert ATTR_MEDIA_CHANNEL not in states.attributes
assert ATTR_MEDIA_CONTENT_ID not in states.attributes
# Send the WebSocket event dispatch
playback_metadata_callback(TEST_PLAYBACK_METADATA)
@@ -276,6 +278,12 @@ async def test_async_update_playback_metadata(
)
assert states.attributes[ATTR_MEDIA_TRACK] == TEST_PLAYBACK_METADATA.track
assert states.attributes[ATTR_MEDIA_CHANNEL] == TEST_PLAYBACK_METADATA.organization
assert states.attributes[ATTR_MEDIA_CHANNEL] == TEST_PLAYBACK_METADATA.organization
assert (
states.attributes[ATTR_MEDIA_CONTENT_ID]
== TEST_PLAYBACK_METADATA.source_internal_id
)
assert states.attributes[ATTR_MEDIA_CONTENT_TYPE] == MediaType.MUSIC
async def test_async_update_playback_error(
@@ -342,28 +350,47 @@ async def test_async_update_playback_state(
@pytest.mark.parametrize(
("source", "content_type", "progress", "metadata"),
("source", "content_type", "progress", "metadata", "content_id_available"),
[
# Normal source, music mediatype expected
(
TEST_SOURCE,
MediaType.MUSIC,
TEST_PLAYBACK_PROGRESS.progress,
PlaybackContentMetadata(),
),
# URI source, url media type expected
(
BangOlufsenSource.URI_STREAMER,
MediaType.URL,
TEST_PLAYBACK_PROGRESS.progress,
PlaybackContentMetadata(),
False,
),
# Line-In source,media type expected, progress 0 expected
# Line-In source, music media type expected, progress 0 expected
(
BangOlufsenSource.LINE_IN,
MediaType.MUSIC,
0,
PlaybackContentMetadata(),
False,
),
# Tidal source, tidal media type expected, media content id expected
(
BangOlufsenSource.TIDAL,
BangOlufsenMediaType.TIDAL,
TEST_PLAYBACK_PROGRESS.progress,
PlaybackContentMetadata(source_internal_id="123"),
True,
),
# Deezer source, deezer media type expected, media content id expected
(
BangOlufsenSource.DEEZER,
BangOlufsenMediaType.DEEZER,
TEST_PLAYBACK_PROGRESS.progress,
PlaybackContentMetadata(source_internal_id="123"),
True,
),
# Radio source, radio media type expected, media content id expected
(
BangOlufsenSource.NET_RADIO,
BangOlufsenMediaType.RADIO,
TEST_PLAYBACK_PROGRESS.progress,
PlaybackContentMetadata(source_internal_id="123"),
True,
),
],
)
@@ -375,6 +402,7 @@ async def test_async_update_source_change(
content_type: MediaType,
progress: int,
metadata: PlaybackContentMetadata,
content_id_available: bool,
) -> None:
"""Test _async_update_source_change."""
playback_progress_callback = (
@@ -402,6 +430,7 @@ async def test_async_update_source_change(
assert states.attributes[ATTR_INPUT_SOURCE] == source.name
assert states.attributes[ATTR_MEDIA_CONTENT_TYPE] == content_type
assert states.attributes[ATTR_MEDIA_POSITION] == progress
assert (ATTR_MEDIA_CONTENT_ID in states.attributes) == content_id_available
async def test_async_turn_off(