Cast automatically drop connection (#12635)

This commit is contained in:
Otto Winter 2018-02-24 19:27:44 +01:00 committed by Paulus Schoutsen
parent 3713dfe139
commit 2821820281
2 changed files with 22 additions and 7 deletions

View File

@ -8,9 +8,11 @@ https://home-assistant.io/components/media_player.cast/
import asyncio import asyncio
import logging import logging
import threading import threading
import functools
import voluptuous as vol import voluptuous as vol
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.typing import HomeAssistantType, ConfigType from homeassistant.helpers.typing import HomeAssistantType, ConfigType
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import (dispatcher_send, from homeassistant.helpers.dispatcher import (dispatcher_send,
@ -34,6 +36,7 @@ CONF_IGNORE_CEC = 'ignore_cec'
CAST_SPLASH = 'https://home-assistant.io/images/cast/splash.png' CAST_SPLASH = 'https://home-assistant.io/images/cast/splash.png'
DEFAULT_PORT = 8009 DEFAULT_PORT = 8009
SOCKET_CLIENT_RETRIES = 10
SUPPORT_CAST = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \ SUPPORT_CAST = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE | \
SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PREVIOUS_TRACK | \ SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PREVIOUS_TRACK | \
@ -76,7 +79,7 @@ def _setup_internal_discovery(hass: HomeAssistantType) -> None:
try: try:
# pylint: disable=protected-access # pylint: disable=protected-access
chromecast = pychromecast._get_chromecast_from_host( chromecast = pychromecast._get_chromecast_from_host(
mdns, blocking=True) mdns, blocking=True, tries=SOCKET_CLIENT_RETRIES)
except pychromecast.ChromecastConnectionError: except pychromecast.ChromecastConnectionError:
_LOGGER.debug("Can't set up cast with mDNS info %s. " _LOGGER.debug("Can't set up cast with mDNS info %s. "
"Assuming it's not a Chromecast", mdns) "Assuming it's not a Chromecast", mdns)
@ -182,11 +185,13 @@ def async_setup_platform(hass: HomeAssistantType, config: ConfigType,
else: else:
# Manually add a "normal" Chromecast, we can do that without discovery. # Manually add a "normal" Chromecast, we can do that without discovery.
try: try:
chromecast = yield from hass.async_add_job( func = functools.partial(pychromecast.Chromecast, *want_host,
pychromecast.Chromecast, *want_host) tries=SOCKET_CLIENT_RETRIES)
except pychromecast.ChromecastConnectionError: chromecast = yield from hass.async_add_job(func)
_LOGGER.warning("Can't set up chromecast on %s", want_host[0]) except pychromecast.ChromecastConnectionError as err:
raise _LOGGER.warning("Can't set up chromecast on %s: %s",
want_host[0], err)
raise PlatformNotReady
key = (chromecast.host, chromecast.port, chromecast.uuid) key = (chromecast.host, chromecast.port, chromecast.uuid)
cast_device = _async_create_cast_device(hass, chromecast) cast_device = _async_create_cast_device(hass, chromecast)
if cast_device is not None: if cast_device is not None:

View File

@ -7,6 +7,7 @@ from uuid import UUID
import pytest import pytest
from homeassistant.exceptions import PlatformNotReady
from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.const import EVENT_HOMEASSISTANT_STOP
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.components.media_player import cast from homeassistant.components.media_player import cast
@ -122,7 +123,7 @@ def test_internal_discovery_callback_only_generates_once(hass):
return_value=chromecast) as gen_chromecast: return_value=chromecast) as gen_chromecast:
discover_cast('the-service', chromecast) discover_cast('the-service', chromecast)
mdns = (chromecast.host, chromecast.port, chromecast.uuid, None, None) mdns = (chromecast.host, chromecast.port, chromecast.uuid, None, None)
gen_chromecast.assert_called_once_with(mdns, blocking=True) gen_chromecast.assert_called_once_with(mdns, blocking=True, tries=10)
discover_cast('the-service', chromecast) discover_cast('the-service', chromecast)
gen_chromecast.reset_mock() gen_chromecast.reset_mock()
@ -196,6 +197,10 @@ def test_create_cast_device_with_uuid(hass):
@asyncio.coroutine @asyncio.coroutine
def test_normal_chromecast_not_starting_discovery(hass): def test_normal_chromecast_not_starting_discovery(hass):
"""Test cast platform not starting discovery when not required.""" """Test cast platform not starting discovery when not required."""
import pychromecast # imports mock pychromecast
pychromecast.ChromecastConnectionError = IOError
chromecast = get_fake_chromecast() chromecast = get_fake_chromecast()
with patch('pychromecast.Chromecast', return_value=chromecast): with patch('pychromecast.Chromecast', return_value=chromecast):
@ -216,6 +221,11 @@ def test_normal_chromecast_not_starting_discovery(hass):
hass, discovery_info={'host': 'host1', 'port': 42}) hass, discovery_info={'host': 'host1', 'port': 42})
assert add_devices.call_count == 0 assert add_devices.call_count == 0
with patch('pychromecast.Chromecast',
side_effect=pychromecast.ChromecastConnectionError):
with pytest.raises(PlatformNotReady):
yield from async_setup_cast(hass, {'host': 'host3'})
@asyncio.coroutine @asyncio.coroutine
def test_replay_past_chromecasts(hass): def test_replay_past_chromecasts(hass):