mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 09:47:13 +00:00
Add Bang & Olufsen button Event entities (#127550)
* Add button events * Remove unused common keys Rename Preset to Favourite * Add event testing * Add check for Beoconnect Core * Rename device controls * Add test for Beoconnect core event entity creation * Fix config entry type * Add a type checking check before assertion * Add icon translations * Remove useless defined icons * Remove base event class * Update homeassistant/components/bang_olufsen/event.py Co-authored-by: Josef Zweck <josef@zweck.dev> --------- Co-authored-by: Josef Zweck <josef@zweck.dev>
This commit is contained in:
parent
f1ad3040b8
commit
2054988790
@ -34,7 +34,7 @@ class BangOlufsenData:
|
||||
|
||||
type BangOlufsenConfigEntry = ConfigEntry[BangOlufsenData]
|
||||
|
||||
PLATFORMS = [Platform.MEDIA_PLAYER]
|
||||
PLATFORMS = [Platform.EVENT, Platform.MEDIA_PLAYER]
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: BangOlufsenConfigEntry) -> bool:
|
||||
|
@ -79,6 +79,7 @@ class WebsocketNotification(StrEnum):
|
||||
"""Enum for WebSocket notification types."""
|
||||
|
||||
ACTIVE_LISTENING_MODE = "active_listening_mode"
|
||||
BUTTON = "button"
|
||||
PLAYBACK_ERROR = "playback_error"
|
||||
PLAYBACK_METADATA = "playback_metadata"
|
||||
PLAYBACK_PROGRESS = "playback_progress"
|
||||
@ -203,14 +204,60 @@ FALLBACK_SOURCES: Final[SourceArray] = SourceArray(
|
||||
),
|
||||
]
|
||||
)
|
||||
# Map for storing compatibility of devices.
|
||||
|
||||
MODEL_SUPPORT_DEVICE_BUTTONS: Final[str] = "device_buttons"
|
||||
|
||||
MODEL_SUPPORT_MAP = {
|
||||
MODEL_SUPPORT_DEVICE_BUTTONS: (
|
||||
BangOlufsenModel.BEOLAB_8,
|
||||
BangOlufsenModel.BEOLAB_28,
|
||||
BangOlufsenModel.BEOSOUND_2,
|
||||
BangOlufsenModel.BEOSOUND_A5,
|
||||
BangOlufsenModel.BEOSOUND_A9,
|
||||
BangOlufsenModel.BEOSOUND_BALANCE,
|
||||
BangOlufsenModel.BEOSOUND_EMERGE,
|
||||
BangOlufsenModel.BEOSOUND_LEVEL,
|
||||
BangOlufsenModel.BEOSOUND_THEATRE,
|
||||
)
|
||||
}
|
||||
|
||||
# Device events
|
||||
BANG_OLUFSEN_WEBSOCKET_EVENT: Final[str] = f"{DOMAIN}_websocket_event"
|
||||
|
||||
# Dict used to translate native Bang & Olufsen event names to string.json compatible ones
|
||||
EVENT_TRANSLATION_MAP: dict[str, str] = {
|
||||
"shortPress (Release)": "short_press_release",
|
||||
"longPress (Timeout)": "long_press_timeout",
|
||||
"longPress (Release)": "long_press_release",
|
||||
"veryLongPress (Timeout)": "very_long_press_timeout",
|
||||
"veryLongPress (Release)": "very_long_press_release",
|
||||
}
|
||||
|
||||
CONNECTION_STATUS: Final[str] = "CONNECTION_STATUS"
|
||||
|
||||
DEVICE_BUTTONS: Final[list[str]] = [
|
||||
"Bluetooth",
|
||||
"Microphone",
|
||||
"Next",
|
||||
"PlayPause",
|
||||
"Preset1",
|
||||
"Preset2",
|
||||
"Preset3",
|
||||
"Preset4",
|
||||
"Previous",
|
||||
"Volume",
|
||||
]
|
||||
|
||||
|
||||
DEVICE_BUTTON_EVENTS: Final[list[str]] = [
|
||||
"short_press_release",
|
||||
"long_press_timeout",
|
||||
"long_press_release",
|
||||
"very_long_press_timeout",
|
||||
"very_long_press_release",
|
||||
]
|
||||
|
||||
# Beolink Converter NL/ML sources need to be transformed to upper case
|
||||
BEOLINK_JOIN_SOURCES_TO_UPPER = (
|
||||
"aux_a",
|
||||
|
76
homeassistant/components/bang_olufsen/event.py
Normal file
76
homeassistant/components/bang_olufsen/event.py
Normal file
@ -0,0 +1,76 @@
|
||||
"""Event entities for the Bang & Olufsen integration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.event import EventDeviceClass, EventEntity
|
||||
from homeassistant.const import CONF_MODEL
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import BangOlufsenConfigEntry
|
||||
from .const import (
|
||||
CONNECTION_STATUS,
|
||||
DEVICE_BUTTON_EVENTS,
|
||||
DEVICE_BUTTONS,
|
||||
MODEL_SUPPORT_DEVICE_BUTTONS,
|
||||
MODEL_SUPPORT_MAP,
|
||||
WebsocketNotification,
|
||||
)
|
||||
from .entity import BangOlufsenEntity
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: BangOlufsenConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up Sensor entities from config entry."""
|
||||
|
||||
if config_entry.data[CONF_MODEL] in MODEL_SUPPORT_MAP[MODEL_SUPPORT_DEVICE_BUTTONS]:
|
||||
async_add_entities(
|
||||
BangOlufsenButtonEvent(config_entry, button_type)
|
||||
for button_type in DEVICE_BUTTONS
|
||||
)
|
||||
|
||||
|
||||
class BangOlufsenButtonEvent(BangOlufsenEntity, EventEntity):
|
||||
"""Event class for Button events."""
|
||||
|
||||
_attr_device_class = EventDeviceClass.BUTTON
|
||||
_attr_entity_registry_enabled_default = False
|
||||
_attr_event_types = DEVICE_BUTTON_EVENTS
|
||||
|
||||
def __init__(self, config_entry: BangOlufsenConfigEntry, button_type: str) -> None:
|
||||
"""Initialize Button."""
|
||||
super().__init__(config_entry, config_entry.runtime_data.client)
|
||||
|
||||
self._attr_unique_id = f"{self._unique_id}_{button_type}"
|
||||
|
||||
# Make the native button name Home Assistant compatible
|
||||
self._attr_translation_key = button_type.lower()
|
||||
|
||||
self._button_type = button_type
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Listen to WebSocket button events."""
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
f"{self._unique_id}_{CONNECTION_STATUS}",
|
||||
self._async_update_connection_state,
|
||||
)
|
||||
)
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
self.hass,
|
||||
f"{self._unique_id}_{WebsocketNotification.BUTTON}_{self._button_type}",
|
||||
self._async_handle_event,
|
||||
)
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_handle_event(self, event: str) -> None:
|
||||
"""Handle event."""
|
||||
self._trigger_event(event)
|
||||
self.async_write_ha_state()
|
@ -1,7 +1,12 @@
|
||||
{
|
||||
"common": {
|
||||
"jid_options_description": "Advanced grouping options, where devices' unique Beolink IDs (Called JIDs) are used directly. JIDs can be found in the state attributes of the media player entity.",
|
||||
"jid_options_name": "JID options",
|
||||
"jid_options_description": "Advanced grouping options, where devices' unique Beolink IDs (Called JIDs) are used directly. JIDs can be found in the state attributes of the media player entity."
|
||||
"long_press_release": "Release of long press",
|
||||
"long_press_timeout": "Long press",
|
||||
"short_press_release": "Release of short press",
|
||||
"very_long_press_release": "Release of very long press",
|
||||
"very_long_press_timeout": "Very long press"
|
||||
},
|
||||
"config": {
|
||||
"error": {
|
||||
@ -29,6 +34,150 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"event": {
|
||||
"bluetooth": {
|
||||
"name": "Bluetooth",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"microphone": {
|
||||
"name": "Microphone",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"next": {
|
||||
"name": "Next",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"playpause": {
|
||||
"name": "Play / Pause",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"preset1": {
|
||||
"name": "Favourite 1",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"preset2": {
|
||||
"name": "Favourite 2",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"preset3": {
|
||||
"name": "Favourite 3",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"preset4": {
|
||||
"name": "Favourite 4",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"previous": {
|
||||
"name": "Previous",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
"name": "Volume",
|
||||
"state_attributes": {
|
||||
"event_type": {
|
||||
"state": {
|
||||
"short_press_release": "[%key:component::bang_olufsen::common::short_press_release%]",
|
||||
"long_press_timeout": "[%key:component::bang_olufsen::common::long_press_timeout%]",
|
||||
"long_press_release": "[%key:component::bang_olufsen::common::long_press_release%]",
|
||||
"very_long_press_timeout": "[%key:component::bang_olufsen::common::very_long_press_timeout%]",
|
||||
"very_long_press_release": "[%key:component::bang_olufsen::common::very_long_press_release%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"selector": {
|
||||
"source_ids": {
|
||||
"options": {
|
||||
|
@ -3,8 +3,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from mozart_api.models import (
|
||||
ButtonEvent,
|
||||
ListeningModeProps,
|
||||
PlaybackContentMetadata,
|
||||
PlaybackError,
|
||||
@ -26,6 +28,7 @@ from homeassistant.util.enum import try_parse_enum
|
||||
from .const import (
|
||||
BANG_OLUFSEN_WEBSOCKET_EVENT,
|
||||
CONNECTION_STATUS,
|
||||
EVENT_TRANSLATION_MAP,
|
||||
WebsocketNotification,
|
||||
)
|
||||
from .entity import BangOlufsenBase
|
||||
@ -54,6 +57,8 @@ class BangOlufsenWebsocket(BangOlufsenBase):
|
||||
self._client.get_active_listening_mode_notifications(
|
||||
self.on_active_listening_mode
|
||||
)
|
||||
self._client.get_button_notifications(self.on_button_notification)
|
||||
|
||||
self._client.get_playback_error_notifications(
|
||||
self.on_playback_error_notification
|
||||
)
|
||||
@ -104,6 +109,19 @@ class BangOlufsenWebsocket(BangOlufsenBase):
|
||||
notification,
|
||||
)
|
||||
|
||||
def on_button_notification(self, notification: ButtonEvent) -> None:
|
||||
"""Send button dispatch."""
|
||||
# State is expected to always be available.
|
||||
if TYPE_CHECKING:
|
||||
assert notification.state
|
||||
|
||||
# Send to event entity
|
||||
async_dispatcher_send(
|
||||
self.hass,
|
||||
f"{self._unique_id}_{WebsocketNotification.BUTTON}_{notification.button}",
|
||||
EVENT_TRANSLATION_MAP[notification.state],
|
||||
)
|
||||
|
||||
def on_notification_notification(
|
||||
self, notification: WebsocketNotificationTag
|
||||
) -> None:
|
||||
|
@ -56,7 +56,7 @@ from tests.common import MockConfigEntry
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry() -> MockConfigEntry:
|
||||
"""Mock config entry."""
|
||||
"""Mock config entry for Beosound Balance."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=TEST_SERIAL_NUMBER,
|
||||
@ -66,8 +66,8 @@ def mock_config_entry() -> MockConfigEntry:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry_2() -> MockConfigEntry:
|
||||
"""Mock config entry."""
|
||||
def mock_config_entry_core() -> MockConfigEntry:
|
||||
"""Mock config entry for Beoconnect Core."""
|
||||
return MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
unique_id=TEST_SERIAL_NUMBER_2,
|
||||
|
@ -38,6 +38,7 @@ TEST_HOST = "192.168.0.1"
|
||||
TEST_HOST_INVALID = "192.168.0"
|
||||
TEST_HOST_IPV6 = "1111:2222:3333:4444:5555:6666:7777:8888"
|
||||
TEST_MODEL_BALANCE = "Beosound Balance"
|
||||
TEST_MODEL_CORE = "Beoconnect Core"
|
||||
TEST_MODEL_THEATRE = "Beosound Theatre"
|
||||
TEST_MODEL_LEVEL = "Beosound Level"
|
||||
TEST_SERIAL_NUMBER = "11111111"
|
||||
@ -65,6 +66,9 @@ TEST_JID_4 = f"{TEST_TYPE_NUMBER}.{TEST_ITEM_NUMBER}.44444444@products.bang-oluf
|
||||
TEST_MEDIA_PLAYER_ENTITY_ID_4 = "media_player.beosound_balance_44444444"
|
||||
TEST_HOST_4 = "192.168.0.4"
|
||||
|
||||
|
||||
TEST_BUTTON_EVENT_ENTITY_ID = "event.beosound_balance_11111111_play_pause"
|
||||
|
||||
TEST_HOSTNAME_ZEROCONF = TEST_NAME.replace(" ", "-") + ".local."
|
||||
TEST_TYPE_ZEROCONF = "_bangolufsen._tcp.local."
|
||||
TEST_NAME_ZEROCONF = TEST_NAME.replace(" ", "-") + "." + TEST_TYPE_ZEROCONF
|
||||
@ -81,7 +85,7 @@ TEST_DATA_CREATE_ENTRY = {
|
||||
}
|
||||
TEST_DATA_CREATE_ENTRY_2 = {
|
||||
CONF_HOST: TEST_HOST,
|
||||
CONF_MODEL: TEST_MODEL_BALANCE,
|
||||
CONF_MODEL: TEST_MODEL_CORE,
|
||||
CONF_BEOLINK_JID: TEST_JID_2,
|
||||
CONF_NAME: TEST_NAME_2,
|
||||
}
|
||||
|
103
tests/components/bang_olufsen/test_event.py
Normal file
103
tests/components/bang_olufsen/test_event.py
Normal file
@ -0,0 +1,103 @@
|
||||
"""Test the bang_olufsen event entities."""
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from inflection import underscore
|
||||
from mozart_api.models import ButtonEvent
|
||||
|
||||
from homeassistant.components.bang_olufsen.const import (
|
||||
DEVICE_BUTTON_EVENTS,
|
||||
DEVICE_BUTTONS,
|
||||
EVENT_TRANSLATION_MAP,
|
||||
)
|
||||
from homeassistant.components.event import ATTR_EVENT_TYPE, ATTR_EVENT_TYPES
|
||||
from homeassistant.const import STATE_UNKNOWN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_registry import EntityRegistry
|
||||
|
||||
from .const import TEST_BUTTON_EVENT_ENTITY_ID
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_button_event_creation(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_mozart_client: AsyncMock,
|
||||
entity_registry: EntityRegistry,
|
||||
) -> None:
|
||||
"""Test button event entities are created."""
|
||||
|
||||
# Load entry
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
# Add Button Event entity ids
|
||||
entity_ids = [
|
||||
f"event.beosound_balance_11111111_{underscore(button_type)}".replace(
|
||||
"preset", "preset_"
|
||||
)
|
||||
for button_type in DEVICE_BUTTONS
|
||||
]
|
||||
|
||||
# Check that the entities are available
|
||||
for entity_id in entity_ids:
|
||||
entity_registry.async_get(entity_id)
|
||||
|
||||
|
||||
async def test_button_event_creation_beoconnect_core(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry_core: MockConfigEntry,
|
||||
mock_mozart_client: AsyncMock,
|
||||
entity_registry: EntityRegistry,
|
||||
) -> None:
|
||||
"""Test button event entities are not created when using a Beoconnect Core."""
|
||||
|
||||
# Load entry
|
||||
mock_config_entry_core.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_core.entry_id)
|
||||
|
||||
# Add Button Event entity ids
|
||||
entity_ids = [
|
||||
f"event.beosound_balance_11111111_{underscore(button_type)}".replace(
|
||||
"preset", "preset_"
|
||||
)
|
||||
for button_type in DEVICE_BUTTONS
|
||||
]
|
||||
|
||||
# Check that the entities are unavailable
|
||||
for entity_id in entity_ids:
|
||||
assert not entity_registry.async_get(entity_id)
|
||||
|
||||
|
||||
async def test_button(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_mozart_client: AsyncMock,
|
||||
entity_registry: EntityRegistry,
|
||||
) -> None:
|
||||
"""Test button event entity."""
|
||||
# Load entry
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
# Enable the entity
|
||||
entity_registry.async_update_entity(TEST_BUTTON_EVENT_ENTITY_ID, disabled_by=None)
|
||||
hass.config_entries.async_schedule_reload(mock_config_entry.entry_id)
|
||||
|
||||
assert (states := hass.states.get(TEST_BUTTON_EVENT_ENTITY_ID))
|
||||
assert states.state is STATE_UNKNOWN
|
||||
assert states.attributes[ATTR_EVENT_TYPES] == list(DEVICE_BUTTON_EVENTS)
|
||||
|
||||
# Check button reacts as expected to WebSocket events
|
||||
notification_callback = mock_mozart_client.get_button_notifications.call_args[0][0]
|
||||
|
||||
notification_callback(ButtonEvent(button="PlayPause", state="shortPress (Release)"))
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (states := hass.states.get(TEST_BUTTON_EVENT_ENTITY_ID))
|
||||
assert states.state is not None
|
||||
assert (
|
||||
states.attributes[ATTR_EVENT_TYPE]
|
||||
== EVENT_TRANSLATION_MAP["shortPress (Release)"]
|
||||
)
|
@ -528,7 +528,7 @@ async def test_async_update_beolink_listener(
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_mozart_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_config_entry_2: MockConfigEntry,
|
||||
mock_config_entry_core: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test _async_update_beolink as a listener."""
|
||||
|
||||
@ -540,8 +540,8 @@ async def test_async_update_beolink_listener(
|
||||
)
|
||||
|
||||
# Add another entity
|
||||
mock_config_entry_2.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_2.entry_id)
|
||||
mock_config_entry_core.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_core.entry_id)
|
||||
|
||||
# Runs _async_update_beolink
|
||||
playback_metadata_callback(
|
||||
@ -1386,7 +1386,7 @@ async def test_async_join_players(
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_mozart_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_config_entry_2: MockConfigEntry,
|
||||
mock_config_entry_core: MockConfigEntry,
|
||||
group_members: list[str],
|
||||
expand_count: int,
|
||||
join_count: int,
|
||||
@ -1401,8 +1401,8 @@ async def test_async_join_players(
|
||||
)
|
||||
|
||||
# Add another entity
|
||||
mock_config_entry_2.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_2.entry_id)
|
||||
mock_config_entry_core.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_core.entry_id)
|
||||
|
||||
# Set the source to a beolink expandable source
|
||||
source_change_callback(TEST_SOURCE)
|
||||
@ -1453,7 +1453,7 @@ async def test_async_join_players_invalid(
|
||||
snapshot: SnapshotAssertion,
|
||||
mock_mozart_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_config_entry_2: MockConfigEntry,
|
||||
mock_config_entry_core: MockConfigEntry,
|
||||
source: Source,
|
||||
group_members: list[str],
|
||||
expected_result: AbstractContextManager,
|
||||
@ -1468,8 +1468,8 @@ async def test_async_join_players_invalid(
|
||||
mock_mozart_client.get_source_change_notifications.call_args[0][0]
|
||||
)
|
||||
|
||||
mock_config_entry_2.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_2.entry_id)
|
||||
mock_config_entry_core.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry_core.entry_id)
|
||||
|
||||
source_change_callback(source)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user