mirror of
https://github.com/home-assistant/core.git
synced 2025-04-30 04:07:51 +00:00
Rework chromecast fix (#16804)
* Revert changes of #16471, and fix the platform setup issue * Fix unit test * Fix * Fix comment * Fix test * Address review comment * Address review comment
This commit is contained in:
parent
329d9dfc06
commit
564ad7e22a
@ -61,10 +61,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||||||
vol.All(cv.ensure_list, [cv.string]),
|
vol.All(cv.ensure_list, [cv.string]),
|
||||||
})
|
})
|
||||||
|
|
||||||
CONNECTION_RETRY = 3
|
|
||||||
CONNECTION_RETRY_WAIT = 2
|
|
||||||
CONNECTION_TIMEOUT = 10
|
|
||||||
|
|
||||||
|
|
||||||
@attr.s(slots=True, frozen=True)
|
@attr.s(slots=True, frozen=True)
|
||||||
class ChromecastInfo:
|
class ChromecastInfo:
|
||||||
@ -216,9 +212,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
if not isinstance(config, list):
|
if not isinstance(config, list):
|
||||||
config = [config]
|
config = [config]
|
||||||
|
|
||||||
await asyncio.wait([
|
# no pending task
|
||||||
|
done, _ = await asyncio.wait([
|
||||||
_async_setup_platform(hass, cfg, async_add_entities, None)
|
_async_setup_platform(hass, cfg, async_add_entities, None)
|
||||||
for cfg in config])
|
for cfg in config])
|
||||||
|
if any([task.exception() for task in done]):
|
||||||
|
raise PlatformNotReady
|
||||||
|
|
||||||
|
|
||||||
async def _async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
async def _async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
||||||
@ -250,8 +249,8 @@ async def _async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
|||||||
if cast_device is not None:
|
if cast_device is not None:
|
||||||
async_add_entities([cast_device])
|
async_add_entities([cast_device])
|
||||||
|
|
||||||
async_dispatcher_connect(hass, SIGNAL_CAST_DISCOVERED,
|
remove_handler = async_dispatcher_connect(
|
||||||
async_cast_discovered)
|
hass, SIGNAL_CAST_DISCOVERED, async_cast_discovered)
|
||||||
# Re-play the callback for all past chromecasts, store the objects in
|
# Re-play the callback for all past chromecasts, store the objects in
|
||||||
# a list to avoid concurrent modification resulting in exception.
|
# a list to avoid concurrent modification resulting in exception.
|
||||||
for chromecast in list(hass.data[KNOWN_CHROMECAST_INFO_KEY]):
|
for chromecast in list(hass.data[KNOWN_CHROMECAST_INFO_KEY]):
|
||||||
@ -265,8 +264,11 @@ async def _async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
|||||||
info = await hass.async_add_job(_fill_out_missing_chromecast_info,
|
info = await hass.async_add_job(_fill_out_missing_chromecast_info,
|
||||||
info)
|
info)
|
||||||
if info.friendly_name is None:
|
if info.friendly_name is None:
|
||||||
# HTTP dial failed, so we won't be able to connect.
|
_LOGGER.debug("Cannot retrieve detail information for chromecast"
|
||||||
|
" %s, the device may not be online", info)
|
||||||
|
remove_handler()
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady
|
||||||
|
|
||||||
hass.async_add_job(_discover_chromecast, hass, info)
|
hass.async_add_job(_discover_chromecast, hass, info)
|
||||||
|
|
||||||
|
|
||||||
@ -379,7 +381,7 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
pychromecast._get_chromecast_from_host, (
|
pychromecast._get_chromecast_from_host, (
|
||||||
cast_info.host, cast_info.port, cast_info.uuid,
|
cast_info.host, cast_info.port, cast_info.uuid,
|
||||||
cast_info.model_name, cast_info.friendly_name
|
cast_info.model_name, cast_info.friendly_name
|
||||||
), CONNECTION_RETRY, CONNECTION_RETRY_WAIT, CONNECTION_TIMEOUT)
|
))
|
||||||
self._chromecast = chromecast
|
self._chromecast = chromecast
|
||||||
self._status_listener = CastStatusListener(self, chromecast)
|
self._status_listener = CastStatusListener(self, chromecast)
|
||||||
# Initialise connection status as connected because we can only
|
# Initialise connection status as connected because we can only
|
||||||
|
@ -609,16 +609,18 @@ def patch_yaml_files(files_dict, endswith=True):
|
|||||||
return patch.object(yaml, 'open', mock_open_f, create=True)
|
return patch.object(yaml, 'open', mock_open_f, create=True)
|
||||||
|
|
||||||
|
|
||||||
def mock_coro(return_value=None):
|
def mock_coro(return_value=None, exception=None):
|
||||||
"""Return a coro that returns a value."""
|
"""Return a coro that returns a value or raise an exception."""
|
||||||
return mock_coro_func(return_value)()
|
return mock_coro_func(return_value, exception)()
|
||||||
|
|
||||||
|
|
||||||
def mock_coro_func(return_value=None):
|
def mock_coro_func(return_value=None, exception=None):
|
||||||
"""Return a method to create a coro function that returns a value."""
|
"""Return a method to create a coro function that returns a value."""
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def coro(*args, **kwargs):
|
def coro(*args, **kwargs):
|
||||||
"""Fake coroutine."""
|
"""Fake coroutine."""
|
||||||
|
if exception:
|
||||||
|
raise exception
|
||||||
return return_value
|
return return_value
|
||||||
|
|
||||||
return coro
|
return coro
|
||||||
|
@ -415,3 +415,23 @@ async def test_entry_setup_list_config(hass: HomeAssistantType):
|
|||||||
assert len(mock_setup.mock_calls) == 2
|
assert len(mock_setup.mock_calls) == 2
|
||||||
assert mock_setup.mock_calls[0][1][1] == {'host': 'bla'}
|
assert mock_setup.mock_calls[0][1][1] == {'host': 'bla'}
|
||||||
assert mock_setup.mock_calls[1][1][1] == {'host': 'blu'}
|
assert mock_setup.mock_calls[1][1][1] == {'host': 'blu'}
|
||||||
|
|
||||||
|
|
||||||
|
async def test_entry_setup_platform_not_ready(hass: HomeAssistantType):
|
||||||
|
"""Test failed setting up entry will raise PlatformNotReady."""
|
||||||
|
await async_setup_component(hass, 'cast', {
|
||||||
|
'cast': {
|
||||||
|
'media_player': {
|
||||||
|
'host': 'bla'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
'homeassistant.components.media_player.cast._async_setup_platform',
|
||||||
|
return_value=mock_coro(exception=Exception)) as mock_setup:
|
||||||
|
with pytest.raises(PlatformNotReady):
|
||||||
|
await cast.async_setup_entry(hass, MockConfigEntry(), None)
|
||||||
|
|
||||||
|
assert len(mock_setup.mock_calls) == 1
|
||||||
|
assert mock_setup.mock_calls[0][1][1] == {'host': 'bla'}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user