Discover manually added casts (#33922)

* Discover manually added casts
This commit is contained in:
Erik Montnemery 2020-04-10 17:19:44 +02:00 committed by GitHub
parent bc036351f6
commit a0b3a9e50b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 53 deletions

View file

@ -55,7 +55,7 @@ from .const import (
SIGNAL_CAST_REMOVED,
SIGNAL_HASS_CAST_SHOW_VIEW,
)
from .discovery import discover_chromecast, setup_internal_discovery
from .discovery import setup_internal_discovery
from .helpers import (
CastStatusListener,
ChromecastInfo,
@ -178,20 +178,7 @@ async def _async_setup_platform(
for chromecast in list(hass.data[KNOWN_CHROMECAST_INFO_KEY]):
async_cast_discovered(chromecast)
if info is None or info.is_audio_group:
# If we were a) explicitly told to enable discovery or
# b) have an audio group cast device, we need internal discovery.
hass.async_add_executor_job(setup_internal_discovery, hass)
else:
info = await hass.async_add_executor_job(info.fill_out_missing_chromecast_info)
if info.friendly_name is None:
_LOGGER.debug(
"Cannot retrieve detail information for chromecast"
" %s, the device may not be online",
info,
)
hass.async_add_executor_job(discover_chromecast, hass, info)
hass.async_add_executor_job(setup_internal_discovery, hass)
class CastDevice(MediaPlayerDevice):

View file

@ -22,6 +22,7 @@ from tests.common import MockConfigEntry, mock_coro
def cast_mock():
"""Mock pychromecast."""
pycast_mock = MagicMock()
pycast_mock.start_discovery.return_value = (None, Mock())
dial_mock = MagicMock(name="XXX")
dial_mock.get_device_status.return_value.uuid = "fake_uuid"
dial_mock.get_device_status.return_value.manufacturer = "fake_manufacturer"
@ -42,6 +43,7 @@ def cast_mock():
# pylint: disable=invalid-name
FakeUUID = UUID("57355bce-9364-4aa6-ac1e-eb849dccf9e2")
FakeUUID2 = UUID("57355bce-9364-4aa6-ac1e-eb849dccf9e4")
FakeGroupUUID = UUID("57355bce-9364-4aa6-ac1e-eb849dccf9e3")
@ -108,19 +110,42 @@ async def async_setup_cast_internal_discovery(hass, config=None, discovery_info=
async def async_setup_media_player_cast(hass: HomeAssistantType, info: ChromecastInfo):
"""Set up the cast platform with async_setup_component."""
listener = MagicMock(services={})
browser = MagicMock(zc={})
chromecast = get_fake_chromecast(info)
cast.CastStatusListener = MagicMock()
with patch(
"homeassistant.components.cast.discovery.pychromecast._get_chromecast_from_host",
"homeassistant.components.cast.discovery.pychromecast._get_chromecast_from_service",
return_value=chromecast,
) as get_chromecast:
) as get_chromecast, patch(
"homeassistant.components.cast.discovery.pychromecast.start_discovery",
return_value=(listener, browser),
) as start_discovery:
await async_setup_component(
hass,
"media_player",
{"media_player": {"platform": "cast", "host": info.host}},
)
await hass.async_block_till_done()
discovery_callback = start_discovery.call_args[0][0]
def discover_chromecast(service_name: str, info: ChromecastInfo) -> None:
"""Discover a chromecast device."""
listener.services[service_name] = (
info.host,
info.port,
info.uuid,
info.model_name,
info.friendly_name,
)
discovery_callback(service_name)
discover_chromecast("the-service", info)
await hass.async_block_till_done()
await hass.async_block_till_done()
assert get_chromecast.call_count == 1
assert cast.CastStatusListener.call_count == 1
@ -220,42 +245,6 @@ async def test_create_cast_device_with_uuid(hass):
assert cast_device is None
async def test_normal_chromecast_not_starting_discovery(hass):
"""Test cast platform not starting discovery when not required."""
# pylint: disable=no-member
with patch(
"homeassistant.components.cast.media_player.setup_internal_discovery"
) as setup_discovery:
# normal (non-group) chromecast shouldn't start discovery.
add_entities = await async_setup_cast(hass, {"host": "host1"})
await hass.async_block_till_done()
assert add_entities.call_count == 1
assert setup_discovery.call_count == 0
# Same entity twice
add_entities = await async_setup_cast(hass, {"host": "host1"})
await hass.async_block_till_done()
assert add_entities.call_count == 0
assert setup_discovery.call_count == 0
hass.data[cast.ADDED_CAST_DEVICES_KEY] = set()
add_entities = await async_setup_cast(
hass, discovery_info={"host": "host1", "port": 8009}
)
await hass.async_block_till_done()
assert add_entities.call_count == 1
assert setup_discovery.call_count == 0
# group should start discovery.
hass.data[cast.ADDED_CAST_DEVICES_KEY] = set()
add_entities = await async_setup_cast(
hass, discovery_info={"host": "host1", "port": 42}
)
await hass.async_block_till_done()
assert add_entities.call_count == 0
assert setup_discovery.call_count == 1
async def test_replay_past_chromecasts(hass):
"""Test cast platform re-playing past chromecasts when adding new one."""
cast_group1 = get_fake_chromecast_info(host="host1", port=42)
@ -282,6 +271,62 @@ async def test_replay_past_chromecasts(hass):
assert add_dev2.call_count == 1
async def test_manual_cast_chromecasts(hass):
"""Test only wanted casts are added for manual configuration."""
cast_1 = get_fake_chromecast_info(host="configured_host")
cast_2 = get_fake_chromecast_info(host="other_host", uuid=FakeUUID2)
# Manual configuration of media player with host "configured_host"
discover_cast, add_dev1 = await async_setup_cast_internal_discovery(
hass, config={"host": "configured_host"}
)
discover_cast("service2", cast_2)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 0
discover_cast("service1", cast_1)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 1
async def test_auto_cast_chromecasts(hass):
"""Test all discovered casts are added for default configuration."""
cast_1 = get_fake_chromecast_info(host="some_host")
cast_2 = get_fake_chromecast_info(host="other_host", uuid=FakeUUID2)
# Manual configuration of media player with host "configured_host"
discover_cast, add_dev1 = await async_setup_cast_internal_discovery(hass)
discover_cast("service2", cast_2)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 1
discover_cast("service1", cast_1)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 2
async def test_update_cast_chromecasts(hass):
"""Test discovery of same UUID twice only adds one cast."""
cast_1 = get_fake_chromecast_info(host="old_host")
cast_2 = get_fake_chromecast_info(host="new_host")
# Manual configuration of media player with host "configured_host"
discover_cast, add_dev1 = await async_setup_cast_internal_discovery(hass)
discover_cast("service1", cast_1)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 1
discover_cast("service2", cast_2)
await hass.async_block_till_done()
await hass.async_block_till_done() # having tasks that add jobs
assert add_dev1.call_count == 1
async def test_entity_media_states(hass: HomeAssistantType):
"""Test various entity media states."""
info = get_fake_chromecast_info()