mirror of
https://github.com/home-assistant/core.git
synced 2025-07-18 02:37:08 +00:00
Don't hang forever if manually added cast is down (#21565)
* Don't hang forever if manually added cast is down * Adapt to pychromecast * Do not set available until connected * Update __init__.py * Update requirements * Lint, tests * Fix tests
This commit is contained in:
parent
fe1840f901
commit
fc85b3fc5f
@ -2,7 +2,7 @@
|
|||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
from homeassistant.helpers import config_entry_flow
|
from homeassistant.helpers import config_entry_flow
|
||||||
|
|
||||||
REQUIREMENTS = ['pychromecast==2.5.2']
|
REQUIREMENTS = ['pychromecast==3.0.0']
|
||||||
|
|
||||||
DOMAIN = 'cast'
|
DOMAIN = 'cast'
|
||||||
|
|
||||||
|
@ -257,6 +257,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
_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]):
|
if any([task.exception() for task in done]):
|
||||||
|
exceptions = [task.exception() for task in done]
|
||||||
|
for exception in exceptions:
|
||||||
|
_LOGGER.debug("Failed to setup chromecast", exc_info=exception)
|
||||||
raise PlatformNotReady
|
raise PlatformNotReady
|
||||||
|
|
||||||
|
|
||||||
@ -289,7 +292,7 @@ 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])
|
||||||
|
|
||||||
remove_handler = async_dispatcher_connect(
|
async_dispatcher_connect(
|
||||||
hass, SIGNAL_CAST_DISCOVERED, 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.
|
||||||
@ -306,8 +309,6 @@ async def _async_setup_platform(hass: HomeAssistantType, config: ConfigType,
|
|||||||
if info.friendly_name is None:
|
if info.friendly_name is None:
|
||||||
_LOGGER.debug("Cannot retrieve detail information for chromecast"
|
_LOGGER.debug("Cannot retrieve detail information for chromecast"
|
||||||
" %s, the device may not be online", info)
|
" %s, the device may not be online", info)
|
||||||
remove_handler()
|
|
||||||
raise PlatformNotReady
|
|
||||||
|
|
||||||
hass.async_add_job(_discover_chromecast, hass, info)
|
hass.async_add_job(_discover_chromecast, hass, info)
|
||||||
|
|
||||||
@ -477,16 +478,10 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
))
|
))
|
||||||
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
|
self._available = False
|
||||||
# register the connection listener *after* the initial connection
|
|
||||||
# attempt. If the initial connection failed, we would never reach
|
|
||||||
# this code anyway.
|
|
||||||
self._available = True
|
|
||||||
self.cast_status = chromecast.status
|
self.cast_status = chromecast.status
|
||||||
self.media_status = chromecast.media_controller.status
|
self.media_status = chromecast.media_controller.status
|
||||||
_LOGGER.debug("[%s %s (%s:%s)] Connection successful!",
|
self._chromecast.start()
|
||||||
self.entity_id, self._cast_info.friendly_name,
|
|
||||||
self._cast_info.host, self._cast_info.port)
|
|
||||||
self.async_schedule_update_ha_state()
|
self.async_schedule_update_ha_state()
|
||||||
|
|
||||||
async def async_del_cast_info(self, cast_info):
|
async def async_del_cast_info(self, cast_info):
|
||||||
@ -562,6 +557,10 @@ class CastDevice(MediaPlayerDevice):
|
|||||||
self.entity_id, self._cast_info.friendly_name,
|
self.entity_id, self._cast_info.friendly_name,
|
||||||
self._cast_info.host, self._cast_info.port,
|
self._cast_info.host, self._cast_info.port,
|
||||||
connection_status.status)
|
connection_status.status)
|
||||||
|
info = self._cast_info
|
||||||
|
if info.friendly_name is None and not info.is_audio_group:
|
||||||
|
# We couldn't find friendly_name when the cast was added, retry
|
||||||
|
self._cast_info = _fill_out_missing_chromecast_info(info)
|
||||||
self._available = new_available
|
self._available = new_available
|
||||||
self.schedule_update_ha_state()
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
@ -977,7 +977,7 @@ pycfdns==0.0.1
|
|||||||
pychannels==1.0.0
|
pychannels==1.0.0
|
||||||
|
|
||||||
# homeassistant.components.cast
|
# homeassistant.components.cast
|
||||||
pychromecast==2.5.2
|
pychromecast==3.0.0
|
||||||
|
|
||||||
# homeassistant.components.media_player.cmus
|
# homeassistant.components.media_player.cmus
|
||||||
pycmus==0.1.1
|
pycmus==0.1.1
|
||||||
|
@ -222,13 +222,6 @@ async def test_normal_chromecast_not_starting_discovery(hass):
|
|||||||
assert setup_discovery.call_count == 1
|
assert setup_discovery.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
async def test_normal_raises_platform_not_ready(hass):
|
|
||||||
"""Test cast platform raises PlatformNotReady if HTTP dial fails."""
|
|
||||||
with patch('pychromecast.dial.get_device_status', return_value=None):
|
|
||||||
with pytest.raises(PlatformNotReady):
|
|
||||||
await async_setup_cast(hass, {'host': 'host1'})
|
|
||||||
|
|
||||||
|
|
||||||
async def test_replay_past_chromecasts(hass):
|
async def test_replay_past_chromecasts(hass):
|
||||||
"""Test cast platform re-playing past chromecasts when adding new one."""
|
"""Test cast platform re-playing past chromecasts when adding new one."""
|
||||||
cast_group1 = get_fake_chromecast_info(host='host1', port=42)
|
cast_group1 = get_fake_chromecast_info(host='host1', port=42)
|
||||||
@ -262,6 +255,10 @@ async def test_entity_media_states(hass: HomeAssistantType):
|
|||||||
return_value=full_info):
|
return_value=full_info):
|
||||||
chromecast, entity = await async_setup_media_player_cast(hass, info)
|
chromecast, entity = await async_setup_media_player_cast(hass, info)
|
||||||
|
|
||||||
|
entity._available = True
|
||||||
|
entity.schedule_update_ha_state()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = hass.states.get('media_player.speaker')
|
state = hass.states.get('media_player.speaker')
|
||||||
assert state is not None
|
assert state is not None
|
||||||
assert state.name == 'Speaker'
|
assert state.name == 'Speaker'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user