Skip to content

Commit 81b4122

Browse files
authored
Add proper Beosound Premiere support to Bang & Olufsen (home-assistant#156954)
1 parent bd0ab4d commit 81b4122

File tree

10 files changed

+173
-98
lines changed

10 files changed

+173
-98
lines changed

homeassistant/components/bang_olufsen/const.py

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,26 @@ class BangOlufsenModel(StrEnum):
7171
BEOSOUND_BALANCE = "Beosound Balance"
7272
BEOSOUND_EMERGE = "Beosound Emerge"
7373
BEOSOUND_LEVEL = "Beosound Level"
74+
BEOSOUND_PREMIERE = "Beosound Premiere"
7475
BEOSOUND_THEATRE = "Beosound Theatre"
7576

7677

78+
# Physical "buttons" on devices
79+
class BangOlufsenButtons(StrEnum):
80+
"""Enum for device buttons."""
81+
82+
BLUETOOTH = "Bluetooth"
83+
MICROPHONE = "Microphone"
84+
NEXT = "Next"
85+
PLAY_PAUSE = "PlayPause"
86+
PRESET_1 = "Preset1"
87+
PRESET_2 = "Preset2"
88+
PRESET_3 = "Preset3"
89+
PRESET_4 = "Preset4"
90+
PREVIOUS = "Previous"
91+
VOLUME = "Volume"
92+
93+
7794
# Dispatcher events
7895
class WebsocketNotification(StrEnum):
7996
"""Enum for WebSocket notification types."""
@@ -204,23 +221,6 @@ class WebsocketNotification(StrEnum):
204221
),
205222
]
206223
)
207-
# Map for storing compatibility of devices.
208-
209-
MODEL_SUPPORT_DEVICE_BUTTONS: Final[str] = "device_buttons"
210-
211-
MODEL_SUPPORT_MAP = {
212-
MODEL_SUPPORT_DEVICE_BUTTONS: (
213-
BangOlufsenModel.BEOLAB_8,
214-
BangOlufsenModel.BEOLAB_28,
215-
BangOlufsenModel.BEOSOUND_2,
216-
BangOlufsenModel.BEOSOUND_A5,
217-
BangOlufsenModel.BEOSOUND_A9,
218-
BangOlufsenModel.BEOSOUND_BALANCE,
219-
BangOlufsenModel.BEOSOUND_EMERGE,
220-
BangOlufsenModel.BEOSOUND_LEVEL,
221-
BangOlufsenModel.BEOSOUND_THEATRE,
222-
)
223-
}
224224

225225
# Device events
226226
BANG_OLUFSEN_WEBSOCKET_EVENT: Final[str] = f"{DOMAIN}_websocket_event"
@@ -236,18 +236,7 @@ class WebsocketNotification(StrEnum):
236236

237237
CONNECTION_STATUS: Final[str] = "CONNECTION_STATUS"
238238

239-
DEVICE_BUTTONS: Final[list[str]] = [
240-
"Bluetooth",
241-
"Microphone",
242-
"Next",
243-
"PlayPause",
244-
"Preset1",
245-
"Preset2",
246-
"Preset3",
247-
"Preset4",
248-
"Previous",
249-
"Volume",
250-
]
239+
DEVICE_BUTTONS: Final[list[str]] = [x.value for x in BangOlufsenButtons]
251240

252241

253242
DEVICE_BUTTON_EVENTS: Final[list[str]] = [

homeassistant/components/bang_olufsen/diagnostics.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66

77
from homeassistant.components.event import DOMAIN as EVENT_DOMAIN
88
from homeassistant.components.media_player import DOMAIN as MEDIA_PLAYER_DOMAIN
9+
from homeassistant.const import CONF_MODEL
910
from homeassistant.core import HomeAssistant
1011
from homeassistant.helpers import entity_registry as er
1112

1213
from . import BangOlufsenConfigEntry
13-
from .const import DEVICE_BUTTONS, DOMAIN
14+
from .const import DOMAIN
15+
from .util import get_device_buttons
1416

1517

1618
async def async_get_config_entry_diagnostics(
@@ -40,7 +42,7 @@ async def async_get_config_entry_diagnostics(
4042
data["media_player"] = state_dict
4143

4244
# Add button Event entity states (if enabled)
43-
for device_button in DEVICE_BUTTONS:
45+
for device_button in get_device_buttons(config_entry.data[CONF_MODEL]):
4446
if entity_id := entity_registry.async_get_entity_id(
4547
EVENT_DOMAIN, DOMAIN, f"{config_entry.unique_id}_{device_button}"
4648
):

homeassistant/components/bang_olufsen/event.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,9 @@
99
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
1010

1111
from . import BangOlufsenConfigEntry
12-
from .const import (
13-
CONNECTION_STATUS,
14-
DEVICE_BUTTON_EVENTS,
15-
DEVICE_BUTTONS,
16-
MODEL_SUPPORT_DEVICE_BUTTONS,
17-
MODEL_SUPPORT_MAP,
18-
WebsocketNotification,
19-
)
12+
from .const import CONNECTION_STATUS, DEVICE_BUTTON_EVENTS, WebsocketNotification
2013
from .entity import BangOlufsenEntity
14+
from .util import get_device_buttons
2115

2216
PARALLEL_UPDATES = 0
2317

@@ -29,11 +23,10 @@ async def async_setup_entry(
2923
) -> None:
3024
"""Set up Sensor entities from config entry."""
3125

32-
if config_entry.data[CONF_MODEL] in MODEL_SUPPORT_MAP[MODEL_SUPPORT_DEVICE_BUTTONS]:
33-
async_add_entities(
34-
BangOlufsenButtonEvent(config_entry, button_type)
35-
for button_type in DEVICE_BUTTONS
36-
)
26+
async_add_entities(
27+
BangOlufsenButtonEvent(config_entry, button_type)
28+
for button_type in get_device_buttons(config_entry.data[CONF_MODEL])
29+
)
3730

3831

3932
class BangOlufsenButtonEvent(BangOlufsenEntity, EventEntity):

homeassistant/components/bang_olufsen/util.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from homeassistant.helpers import device_registry as dr
77
from homeassistant.helpers.device_registry import DeviceEntry
88

9-
from .const import DOMAIN
9+
from .const import DEVICE_BUTTONS, DOMAIN, BangOlufsenButtons, BangOlufsenModel
1010

1111

1212
def get_device(hass: HomeAssistant, unique_id: str) -> DeviceEntry:
@@ -21,3 +21,18 @@ def get_device(hass: HomeAssistant, unique_id: str) -> DeviceEntry:
2121
def get_serial_number_from_jid(jid: str) -> str:
2222
"""Get serial number from Beolink JID."""
2323
return jid.split(".")[2].split("@")[0]
24+
25+
26+
def get_device_buttons(model: BangOlufsenModel) -> list[str]:
27+
"""Get supported buttons for a given model."""
28+
buttons = DEVICE_BUTTONS.copy()
29+
30+
# Beosound Premiere does not have a bluetooth button
31+
if model == BangOlufsenModel.BEOSOUND_PREMIERE:
32+
buttons.remove(BangOlufsenButtons.BLUETOOTH)
33+
34+
# Beoconnect Core does not have any buttons
35+
elif model == BangOlufsenModel.BEOCONNECT_CORE:
36+
buttons = []
37+
38+
return buttons

tests/components/bang_olufsen/conftest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from .const import (
3535
TEST_DATA_CREATE_ENTRY,
3636
TEST_DATA_CREATE_ENTRY_2,
37+
TEST_DATA_CREATE_ENTRY_3,
3738
TEST_FRIENDLY_NAME,
3839
TEST_FRIENDLY_NAME_3,
3940
TEST_FRIENDLY_NAME_4,
@@ -44,8 +45,10 @@
4445
TEST_JID_4,
4546
TEST_NAME,
4647
TEST_NAME_2,
48+
TEST_NAME_3,
4749
TEST_SERIAL_NUMBER,
4850
TEST_SERIAL_NUMBER_2,
51+
TEST_SERIAL_NUMBER_3,
4952
TEST_SOUND_MODE,
5053
TEST_SOUND_MODE_2,
5154
TEST_SOUND_MODE_NAME,
@@ -76,6 +79,17 @@ def mock_config_entry_core() -> MockConfigEntry:
7679
)
7780

7881

82+
@pytest.fixture
83+
def mock_config_entry_premiere() -> MockConfigEntry:
84+
"""Mock config entry for Beosound Premiere."""
85+
return MockConfigEntry(
86+
domain=DOMAIN,
87+
unique_id=TEST_SERIAL_NUMBER_3,
88+
data=TEST_DATA_CREATE_ENTRY_3,
89+
title=TEST_NAME_3,
90+
)
91+
92+
7993
async def mock_websocket_connection(
8094
hass: HomeAssistant, mock_mozart_client: AsyncMock
8195
) -> None:

tests/components/bang_olufsen/const.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
TEST_HOST_IPV6 = "1111:2222:3333:4444:5555:6666:7777:8888"
4040
TEST_MODEL_BALANCE = "Beosound Balance"
4141
TEST_MODEL_CORE = "Beoconnect Core"
42+
TEST_MODEL_PREMIERE = "Beosound Premiere"
4243
TEST_MODEL_THEATRE = "Beosound Theatre"
4344
TEST_MODEL_LEVEL = "Beosound Level"
4445
TEST_SERIAL_NUMBER = "11111111"
@@ -56,9 +57,11 @@
5657
TEST_MEDIA_PLAYER_ENTITY_ID_2 = "media_player.beoconnect_core_22222222"
5758
TEST_HOST_2 = "192.168.0.2"
5859

59-
TEST_FRIENDLY_NAME_3 = "Lego room Balance"
60-
TEST_JID_3 = f"{TEST_TYPE_NUMBER}.{TEST_ITEM_NUMBER}[email protected]"
61-
TEST_MEDIA_PLAYER_ENTITY_ID_3 = "media_player.beosound_balance_33333333"
60+
TEST_FRIENDLY_NAME_3 = "Bedroom Premiere"
61+
TEST_SERIAL_NUMBER_3 = "33333333"
62+
TEST_NAME_3 = f"{TEST_MODEL_PREMIERE}-{TEST_SERIAL_NUMBER_3}"
63+
TEST_JID_3 = f"{TEST_TYPE_NUMBER}.{TEST_ITEM_NUMBER}.{TEST_SERIAL_NUMBER_3}@products.bang-olufsen.com"
64+
TEST_MEDIA_PLAYER_ENTITY_ID_3 = f"media_player.beosound_premiere_{TEST_SERIAL_NUMBER_3}"
6265
TEST_HOST_3 = "192.168.0.3"
6366

6467
TEST_FRIENDLY_NAME_4 = "Lounge room Balance"
@@ -90,6 +93,13 @@
9093
CONF_NAME: TEST_NAME_2,
9194
}
9295

96+
TEST_DATA_CREATE_ENTRY_3 = {
97+
CONF_HOST: TEST_HOST_3,
98+
CONF_MODEL: TEST_MODEL_PREMIERE,
99+
CONF_BEOLINK_JID: TEST_JID_3,
100+
CONF_NAME: TEST_NAME_3,
101+
}
102+
93103
TEST_DATA_ZEROCONF = ZeroconfServiceInfo(
94104
ip_address=IPv4Address(TEST_HOST),
95105
ip_addresses=[IPv4Address(TEST_HOST)],

tests/components/bang_olufsen/snapshots/test_diagnostics.ambr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@
4444
'attributes': dict({
4545
'beolink': dict({
4646
'listeners': dict({
47-
'Lego room Balance': '[email protected]',
47+
'Bedroom Premiere': '[email protected]',
4848
'Lounge room Balance': '[email protected]',
4949
}),
5050
'peers': dict({
51-
'Lego room Balance': '[email protected]',
51+
'Bedroom Premiere': '[email protected]',
5252
'Lounge room Balance': '[email protected]',
5353
}),
5454
'self': dict({

tests/components/bang_olufsen/snapshots/test_event.ambr

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# serializer version: 1
2-
# name: test_button_event_creation
2+
# name: test_button_event_creation_balance
33
list([
44
'event.beosound_balance_11111111_bluetooth',
55
'event.beosound_balance_11111111_microphone',
@@ -19,3 +19,17 @@
1919
'media_player.beoconnect_core_22222222',
2020
])
2121
# ---
22+
# name: test_button_event_creation_beosound_premiere
23+
list([
24+
'event.beosound_premiere_33333333_microphone',
25+
'event.beosound_premiere_33333333_next',
26+
'event.beosound_premiere_33333333_play_pause',
27+
'event.beosound_premiere_33333333_favorite_1',
28+
'event.beosound_premiere_33333333_favorite_2',
29+
'event.beosound_premiere_33333333_favorite_3',
30+
'event.beosound_premiere_33333333_favorite_4',
31+
'event.beosound_premiere_33333333_previous',
32+
'event.beosound_premiere_33333333_volume',
33+
'media_player.beosound_premiere_33333333',
34+
])
35+
# ---

0 commit comments

Comments
 (0)