parent
73aadbe8bc
commit
bf649e373c
|
@ -2,6 +2,7 @@
|
|||
import asyncio
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Dict
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -16,8 +17,8 @@ from homeassistant.util import Throttle
|
|||
|
||||
from .config_flow import format_title
|
||||
from .const import (
|
||||
COMMAND_RETRY_ATTEMPTS, COMMAND_RETRY_DELAY, DATA_CONTROLLER,
|
||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
||||
COMMAND_RETRY_ATTEMPTS, COMMAND_RETRY_DELAY, DATA_CONTROLLER_MANAGER,
|
||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_UPDATED)
|
||||
|
||||
CONFIG_SCHEMA = vol.Schema({
|
||||
DOMAIN: vol.Schema({
|
||||
|
@ -89,11 +90,14 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||
exc_info=isinstance(error, CommandError))
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
controller_manager = ControllerManager(hass, controller)
|
||||
await controller_manager.connect_listeners()
|
||||
|
||||
source_manager = SourceManager(favorites, inputs)
|
||||
source_manager.connect_update(hass, controller)
|
||||
|
||||
hass.data[DOMAIN] = {
|
||||
DATA_CONTROLLER: controller,
|
||||
DATA_CONTROLLER_MANAGER: controller_manager,
|
||||
DATA_SOURCE_MANAGER: source_manager,
|
||||
MEDIA_PLAYER_DOMAIN: players
|
||||
}
|
||||
|
@ -104,14 +108,91 @@ async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
|||
|
||||
async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
controller = hass.data[DOMAIN][DATA_CONTROLLER]
|
||||
controller.dispatcher.disconnect_all()
|
||||
await controller.disconnect()
|
||||
controller_manager = hass.data[DOMAIN][DATA_CONTROLLER_MANAGER]
|
||||
await controller_manager.disconnect()
|
||||
hass.data.pop(DOMAIN)
|
||||
return await hass.config_entries.async_forward_entry_unload(
|
||||
entry, MEDIA_PLAYER_DOMAIN)
|
||||
|
||||
|
||||
class ControllerManager:
|
||||
"""Class that manages events of the controller."""
|
||||
|
||||
def __init__(self, hass, controller):
|
||||
"""Init the controller manager."""
|
||||
self._hass = hass
|
||||
self._device_registry = None
|
||||
self._entity_registry = None
|
||||
self.controller = controller
|
||||
self._signals = []
|
||||
|
||||
async def connect_listeners(self):
|
||||
"""Subscribe to events of interest."""
|
||||
from pyheos import const
|
||||
self._device_registry, self._entity_registry = await asyncio.gather(
|
||||
self._hass.helpers.device_registry.async_get_registry(),
|
||||
self._hass.helpers.entity_registry.async_get_registry())
|
||||
# Handle controller events
|
||||
self._signals.append(self.controller.dispatcher.connect(
|
||||
const.SIGNAL_CONTROLLER_EVENT, self._controller_event))
|
||||
# Handle connection-related events
|
||||
self._signals.append(self.controller.dispatcher.connect(
|
||||
const.SIGNAL_HEOS_EVENT, self._heos_event))
|
||||
|
||||
async def disconnect(self):
|
||||
"""Disconnect subscriptions."""
|
||||
for signal_remove in self._signals:
|
||||
signal_remove()
|
||||
self._signals.clear()
|
||||
self.controller.dispatcher.disconnect_all()
|
||||
await self.controller.disconnect()
|
||||
|
||||
async def _controller_event(self, event, data):
|
||||
"""Handle controller event."""
|
||||
from pyheos import const
|
||||
if event == const.EVENT_PLAYERS_CHANGED:
|
||||
self.update_ids(data[const.DATA_MAPPED_IDS])
|
||||
# Update players
|
||||
self._hass.helpers.dispatcher.async_dispatcher_send(
|
||||
SIGNAL_HEOS_UPDATED)
|
||||
|
||||
async def _heos_event(self, event):
|
||||
"""Handle connection event."""
|
||||
from pyheos import CommandError, const
|
||||
if event == const.EVENT_CONNECTED:
|
||||
try:
|
||||
# Retrieve latest players and refresh status
|
||||
data = await self.controller.load_players()
|
||||
self.update_ids(data[const.DATA_MAPPED_IDS])
|
||||
except (CommandError, asyncio.TimeoutError, ConnectionError) as ex:
|
||||
_LOGGER.error("Unable to refresh players: %s", ex)
|
||||
# Update players
|
||||
self._hass.helpers.dispatcher.async_dispatcher_send(
|
||||
SIGNAL_HEOS_UPDATED)
|
||||
|
||||
def update_ids(self, mapped_ids: Dict[int, int]):
|
||||
"""Update the IDs in the device and entity registry."""
|
||||
# mapped_ids contains the mapped IDs (new:old)
|
||||
for new_id, old_id in mapped_ids.items():
|
||||
# update device registry
|
||||
entry = self._device_registry.async_get_device(
|
||||
{(DOMAIN, old_id)}, set())
|
||||
new_identifiers = {(DOMAIN, new_id)}
|
||||
if entry:
|
||||
self._device_registry.async_update_device(
|
||||
entry.id, new_identifiers=new_identifiers)
|
||||
_LOGGER.debug("Updated device %s identifiers to %s",
|
||||
entry.id, new_identifiers)
|
||||
# update entity registry
|
||||
entity_id = self._entity_registry.async_get_entity_id(
|
||||
MEDIA_PLAYER_DOMAIN, DOMAIN, str(old_id))
|
||||
if entity_id:
|
||||
self._entity_registry.async_update_entity(
|
||||
entity_id, new_unique_id=str(new_id))
|
||||
_LOGGER.debug("Updated entity %s unique id to %s",
|
||||
entity_id, new_id)
|
||||
|
||||
|
||||
class SourceManager:
|
||||
"""Class that manages sources for players."""
|
||||
|
||||
|
@ -195,9 +276,10 @@ class SourceManager:
|
|||
exc_info=isinstance(error, CommandError))
|
||||
return
|
||||
|
||||
async def update_sources(event, data):
|
||||
async def update_sources(event, data=None):
|
||||
if event in (const.EVENT_SOURCES_CHANGED,
|
||||
const.EVENT_USER_CHANGED):
|
||||
const.EVENT_USER_CHANGED,
|
||||
const.EVENT_CONNECTED):
|
||||
sources = await get_sources()
|
||||
# If throttled, it will return None
|
||||
if sources:
|
||||
|
@ -206,7 +288,9 @@ class SourceManager:
|
|||
_LOGGER.debug("Sources updated due to changed event")
|
||||
# Let players know to update
|
||||
hass.helpers.dispatcher.async_dispatcher_send(
|
||||
SIGNAL_HEOS_SOURCES_UPDATED)
|
||||
SIGNAL_HEOS_UPDATED)
|
||||
|
||||
controller.dispatcher.connect(
|
||||
const.SIGNAL_CONTROLLER_EVENT, update_sources)
|
||||
controller.dispatcher.connect(
|
||||
const.SIGNAL_HEOS_EVENT, update_sources)
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
COMMAND_RETRY_ATTEMPTS = 2
|
||||
COMMAND_RETRY_DELAY = 1
|
||||
DATA_CONTROLLER = "controller"
|
||||
DATA_CONTROLLER_MANAGER = "controller"
|
||||
DATA_SOURCE_MANAGER = "source_manager"
|
||||
DATA_DISCOVERED_HOSTS = "heos_discovered_hosts"
|
||||
DOMAIN = 'heos'
|
||||
SIGNAL_HEOS_SOURCES_UPDATED = "heos_sources_updated"
|
||||
SIGNAL_HEOS_UPDATED = "heos_updated"
|
||||
|
|
|
@ -18,7 +18,7 @@ from homeassistant.helpers.typing import HomeAssistantType
|
|||
from homeassistant.util.dt import utcnow
|
||||
|
||||
from .const import (
|
||||
DATA_SOURCE_MANAGER, DOMAIN as HEOS_DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
||||
DATA_SOURCE_MANAGER, DOMAIN as HEOS_DOMAIN, SIGNAL_HEOS_UPDATED)
|
||||
|
||||
BASE_SUPPORTED_FEATURES = SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_SET | \
|
||||
SUPPORT_VOLUME_STEP | SUPPORT_CLEAR_PLAYLIST | \
|
||||
|
@ -81,23 +81,6 @@ class HeosMediaPlayer(MediaPlayerDevice):
|
|||
const.CONTROL_PLAY_NEXT: SUPPORT_NEXT_TRACK
|
||||
}
|
||||
|
||||
async def _controller_event(self, event, data):
|
||||
"""Handle controller event."""
|
||||
from pyheos import const
|
||||
if event == const.EVENT_PLAYERS_CHANGED:
|
||||
await self.async_update_ha_state(True)
|
||||
|
||||
async def _heos_event(self, event):
|
||||
"""Handle connection event."""
|
||||
from pyheos import CommandError, const
|
||||
if event == const.EVENT_CONNECTED:
|
||||
try:
|
||||
await self._player.refresh()
|
||||
except (CommandError, asyncio.TimeoutError, ConnectionError) as ex:
|
||||
_LOGGER.error("Unable to refresh player %s: %s",
|
||||
self._player, ex)
|
||||
await self.async_update_ha_state(True)
|
||||
|
||||
async def _player_update(self, player_id, event):
|
||||
"""Handle player attribute updated."""
|
||||
from pyheos import const
|
||||
|
@ -107,7 +90,7 @@ class HeosMediaPlayer(MediaPlayerDevice):
|
|||
self._media_position_updated_at = utcnow()
|
||||
await self.async_update_ha_state(True)
|
||||
|
||||
async def _sources_updated(self):
|
||||
async def _heos_updated(self):
|
||||
"""Handle sources changed."""
|
||||
await self.async_update_ha_state(True)
|
||||
|
||||
|
@ -118,16 +101,10 @@ class HeosMediaPlayer(MediaPlayerDevice):
|
|||
# Update state when attributes of the player change
|
||||
self._signals.append(self._player.heos.dispatcher.connect(
|
||||
const.SIGNAL_PLAYER_EVENT, self._player_update))
|
||||
# Update state when available players change
|
||||
self._signals.append(self._player.heos.dispatcher.connect(
|
||||
const.SIGNAL_CONTROLLER_EVENT, self._controller_event))
|
||||
# Update state upon connect/disconnects
|
||||
self._signals.append(self._player.heos.dispatcher.connect(
|
||||
const.SIGNAL_HEOS_EVENT, self._heos_event))
|
||||
# Update state when sources change
|
||||
# Update state when heos changes
|
||||
self._signals.append(
|
||||
self.hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_SOURCES_UPDATED, self._sources_updated))
|
||||
SIGNAL_HEOS_UPDATED, self._heos_updated))
|
||||
|
||||
@log_command_error("clear playlist")
|
||||
async def async_clear_playlist(self):
|
||||
|
@ -252,7 +229,7 @@ class HeosMediaPlayer(MediaPlayerDevice):
|
|||
"""Get attributes about the device."""
|
||||
return {
|
||||
'identifiers': {
|
||||
(DOMAIN, self._player.player_id)
|
||||
(HEOS_DOMAIN, self._player.player_id)
|
||||
},
|
||||
'name': self._player.name,
|
||||
'model': self._player.model,
|
||||
|
|
|
@ -20,7 +20,7 @@ def config_entry_fixture():
|
|||
|
||||
@pytest.fixture(name="controller")
|
||||
def controller_fixture(
|
||||
players, favorites, input_sources, playlists, dispatcher):
|
||||
players, favorites, input_sources, playlists, change_data, dispatcher):
|
||||
"""Create a mock Heos controller fixture."""
|
||||
with patch("pyheos.Heos", autospec=True) as mock:
|
||||
mock_heos = mock.return_value
|
||||
|
@ -32,6 +32,7 @@ def controller_fixture(
|
|||
mock_heos.get_favorites.return_value = favorites
|
||||
mock_heos.get_input_sources.return_value = input_sources
|
||||
mock_heos.get_playlists.return_value = playlists
|
||||
mock_heos.load_players.return_value = change_data
|
||||
mock_heos.is_signed_in = True
|
||||
mock_heos.signed_in_username = "user@user.com"
|
||||
yield mock_heos
|
||||
|
@ -149,3 +150,23 @@ def playlists_fixture() -> Sequence[HeosSource]:
|
|||
playlist.type = const.TYPE_PLAYLIST
|
||||
playlist.name = "Awesome Music"
|
||||
return [playlist]
|
||||
|
||||
|
||||
@pytest.fixture(name="change_data")
|
||||
def change_data_fixture() -> Dict:
|
||||
"""Create player change data for testing."""
|
||||
return {
|
||||
const.DATA_MAPPED_IDS: {},
|
||||
const.DATA_NEW: []
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="change_data_mapped_ids")
|
||||
def change_data_mapped_ids_fixture() -> Dict:
|
||||
"""Create player change data for testing."""
|
||||
return {
|
||||
const.DATA_MAPPED_IDS: {
|
||||
101: 1
|
||||
},
|
||||
const.DATA_NEW: []
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
"""Tests for the init module."""
|
||||
import asyncio
|
||||
|
||||
from asynctest import patch
|
||||
from asynctest import Mock, patch
|
||||
from pyheos import CommandError, const
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.heos import async_setup_entry, async_unload_entry
|
||||
from homeassistant.components.heos import (
|
||||
ControllerManager, async_setup_entry, async_unload_entry)
|
||||
from homeassistant.components.heos.const import (
|
||||
DATA_CONTROLLER, DATA_SOURCE_MANAGER, DOMAIN)
|
||||
DATA_CONTROLLER_MANAGER, DATA_SOURCE_MANAGER, DOMAIN)
|
||||
from homeassistant.components.media_player.const import (
|
||||
DOMAIN as MEDIA_PLAYER_DOMAIN)
|
||||
from homeassistant.const import CONF_HOST
|
||||
|
@ -74,7 +75,7 @@ async def test_async_setup_entry_loads_platforms(
|
|||
assert controller.get_favorites.call_count == 1
|
||||
assert controller.get_input_sources.call_count == 1
|
||||
controller.disconnect.assert_not_called()
|
||||
assert hass.data[DOMAIN][DATA_CONTROLLER] == controller
|
||||
assert hass.data[DOMAIN][DATA_CONTROLLER_MANAGER].controller == controller
|
||||
assert hass.data[DOMAIN][MEDIA_PLAYER_DOMAIN] == controller.players
|
||||
assert hass.data[DOMAIN][DATA_SOURCE_MANAGER].favorites == favorites
|
||||
assert hass.data[DOMAIN][DATA_SOURCE_MANAGER].inputs == input_sources
|
||||
|
@ -97,7 +98,7 @@ async def test_async_setup_entry_not_signed_in_loads_platforms(
|
|||
assert controller.get_favorites.call_count == 0
|
||||
assert controller.get_input_sources.call_count == 1
|
||||
controller.disconnect.assert_not_called()
|
||||
assert hass.data[DOMAIN][DATA_CONTROLLER] == controller
|
||||
assert hass.data[DOMAIN][DATA_CONTROLLER_MANAGER].controller == controller
|
||||
assert hass.data[DOMAIN][MEDIA_PLAYER_DOMAIN] == controller.players
|
||||
assert hass.data[DOMAIN][DATA_SOURCE_MANAGER].favorites == {}
|
||||
assert hass.data[DOMAIN][DATA_SOURCE_MANAGER].inputs == input_sources
|
||||
|
@ -139,12 +140,13 @@ async def test_async_setup_entry_player_failure(
|
|||
|
||||
async def test_unload_entry(hass, config_entry, controller):
|
||||
"""Test entries are unloaded correctly."""
|
||||
hass.data[DOMAIN] = {DATA_CONTROLLER: controller}
|
||||
controller_manager = Mock(ControllerManager)
|
||||
hass.data[DOMAIN] = {DATA_CONTROLLER_MANAGER: controller_manager}
|
||||
with patch.object(hass.config_entries, 'async_forward_entry_unload',
|
||||
return_value=True) as unload:
|
||||
assert await async_unload_entry(hass, config_entry)
|
||||
await hass.async_block_till_done()
|
||||
assert controller.disconnect.call_count == 1
|
||||
assert controller_manager.disconnect.call_count == 1
|
||||
assert unload.call_count == 1
|
||||
assert DOMAIN not in hass.data
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from pyheos import CommandError, const
|
|||
|
||||
from homeassistant.components.heos import media_player
|
||||
from homeassistant.components.heos.const import (
|
||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_SOURCES_UPDATED)
|
||||
DATA_SOURCE_MANAGER, DOMAIN, SIGNAL_HEOS_UPDATED)
|
||||
from homeassistant.components.media_player.const import (
|
||||
ATTR_INPUT_SOURCE, ATTR_INPUT_SOURCE_LIST, ATTR_MEDIA_ALBUM_NAME,
|
||||
ATTR_MEDIA_ARTIST, ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE,
|
||||
|
@ -66,7 +66,7 @@ async def test_state_attributes(hass, config_entry, config, controller):
|
|||
hass.data[DOMAIN][DATA_SOURCE_MANAGER].source_list
|
||||
|
||||
|
||||
async def test_updates_start_from_signals(
|
||||
async def test_updates_from_signals(
|
||||
hass, config_entry, config, controller, favorites):
|
||||
"""Tests dispatched signals update player."""
|
||||
await setup_platform(hass, config_entry, config)
|
||||
|
@ -102,48 +102,53 @@ async def test_updates_start_from_signals(
|
|||
assert state.attributes[ATTR_MEDIA_DURATION] == 360
|
||||
assert state.attributes[ATTR_MEDIA_POSITION] == 1
|
||||
|
||||
# Test controller player change updates
|
||||
player.available = False
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_CONTROLLER_EVENT, const.EVENT_PLAYERS_CHANGED, {})
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get('media_player.test_player')
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_updates_from_connection_event(
|
||||
hass, config_entry, config, controller, input_sources, caplog):
|
||||
hass, config_entry, config, controller, caplog):
|
||||
"""Tests player updates from connection event after connection failure."""
|
||||
# Connected
|
||||
await setup_platform(hass, config_entry, config)
|
||||
player = controller.players[1]
|
||||
event = asyncio.Event()
|
||||
|
||||
async def set_signal():
|
||||
event.set()
|
||||
hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_UPDATED, set_signal)
|
||||
|
||||
# Connected
|
||||
player.available = True
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED)
|
||||
await hass.async_block_till_done()
|
||||
await event.wait()
|
||||
state = hass.states.get('media_player.test_player')
|
||||
assert state.state == STATE_IDLE
|
||||
assert player.refresh.call_count == 1
|
||||
|
||||
# Connected handles refresh failure
|
||||
player.reset_mock()
|
||||
player.refresh.side_effect = CommandError(None, "Failure", 1)
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED)
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get('media_player.test_player')
|
||||
assert player.refresh.call_count == 1
|
||||
assert "Unable to refresh player" in caplog.text
|
||||
assert controller.load_players.call_count == 1
|
||||
|
||||
# Disconnected
|
||||
event.clear()
|
||||
player.reset_mock()
|
||||
controller.load_players.reset_mock()
|
||||
player.available = False
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_HEOS_EVENT, const.EVENT_DISCONNECTED)
|
||||
await hass.async_block_till_done()
|
||||
await event.wait()
|
||||
state = hass.states.get('media_player.test_player')
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
assert player.refresh.call_count == 0
|
||||
assert controller.load_players.call_count == 0
|
||||
|
||||
# Connected handles refresh failure
|
||||
event.clear()
|
||||
player.reset_mock()
|
||||
controller.load_players.reset_mock()
|
||||
controller.load_players.side_effect = CommandError(None, "Failure", 1)
|
||||
player.available = True
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_HEOS_EVENT, const.EVENT_CONNECTED)
|
||||
await event.wait()
|
||||
state = hass.states.get('media_player.test_player')
|
||||
assert state.state == STATE_IDLE
|
||||
assert controller.load_players.call_count == 1
|
||||
assert "Unable to refresh players" in caplog.text
|
||||
|
||||
|
||||
async def test_updates_from_sources_updated(
|
||||
|
@ -156,7 +161,7 @@ async def test_updates_from_sources_updated(
|
|||
async def set_signal():
|
||||
event.set()
|
||||
hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_SOURCES_UPDATED, set_signal)
|
||||
SIGNAL_HEOS_UPDATED, set_signal)
|
||||
|
||||
input_sources.clear()
|
||||
player.heos.dispatcher.send(
|
||||
|
@ -168,6 +173,65 @@ async def test_updates_from_sources_updated(
|
|||
assert state.attributes[ATTR_INPUT_SOURCE_LIST] == source_list
|
||||
|
||||
|
||||
async def test_updates_from_players_changed(
|
||||
hass, config_entry, config, controller, change_data,
|
||||
caplog):
|
||||
"""Test player updates from changes to available players."""
|
||||
await setup_platform(hass, config_entry, config)
|
||||
player = controller.players[1]
|
||||
event = asyncio.Event()
|
||||
|
||||
async def set_signal():
|
||||
event.set()
|
||||
hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_UPDATED, set_signal)
|
||||
|
||||
assert hass.states.get('media_player.test_player').state == STATE_IDLE
|
||||
player.state = const.PLAY_STATE_PLAY
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_CONTROLLER_EVENT, const.EVENT_PLAYERS_CHANGED,
|
||||
change_data)
|
||||
await event.wait()
|
||||
assert hass.states.get('media_player.test_player').state == STATE_PLAYING
|
||||
|
||||
|
||||
async def test_updates_from_players_changed_new_ids(
|
||||
hass, config_entry, config, controller, change_data_mapped_ids,
|
||||
caplog):
|
||||
"""Test player updates from changes to available players."""
|
||||
await setup_platform(hass, config_entry, config)
|
||||
device_registry = await hass.helpers.device_registry.async_get_registry()
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
player = controller.players[1]
|
||||
event = asyncio.Event()
|
||||
|
||||
# Assert device registry matches current id
|
||||
assert device_registry.async_get_device(
|
||||
{(DOMAIN, 1)}, [])
|
||||
# Assert entity registry matches current id
|
||||
assert entity_registry.async_get_entity_id(
|
||||
MEDIA_PLAYER_DOMAIN, DOMAIN, '1') == "media_player.test_player"
|
||||
|
||||
# Trigger update
|
||||
async def set_signal():
|
||||
event.set()
|
||||
hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_UPDATED, set_signal)
|
||||
player.heos.dispatcher.send(
|
||||
const.SIGNAL_CONTROLLER_EVENT, const.EVENT_PLAYERS_CHANGED,
|
||||
change_data_mapped_ids)
|
||||
await event.wait()
|
||||
|
||||
# Assert device registry identifiers were updated
|
||||
assert len(device_registry.devices) == 1
|
||||
assert device_registry.async_get_device(
|
||||
{(DOMAIN, 101)}, [])
|
||||
# Assert entity registry unique id was updated
|
||||
assert len(entity_registry.entities) == 1
|
||||
assert entity_registry.async_get_entity_id(
|
||||
MEDIA_PLAYER_DOMAIN, DOMAIN, '101') == "media_player.test_player"
|
||||
|
||||
|
||||
async def test_updates_from_user_changed(
|
||||
hass, config_entry, config, controller):
|
||||
"""Tests player updates from changes in user."""
|
||||
|
@ -178,7 +242,7 @@ async def test_updates_from_user_changed(
|
|||
async def set_signal():
|
||||
event.set()
|
||||
hass.helpers.dispatcher.async_dispatcher_connect(
|
||||
SIGNAL_HEOS_SOURCES_UPDATED, set_signal)
|
||||
SIGNAL_HEOS_UPDATED, set_signal)
|
||||
|
||||
controller.is_signed_in = False
|
||||
controller.signed_in_username = None
|
||||
|
|
Loading…
Reference in New Issue