mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Do not use pychromecast.Chromecast for Cast Groups (#8786)
* Do not use pychromecast.Chromecast for Cast Groups pychromecast.Chromecast creates Chromecast instance with friendly_name and cast_type of the device and not of a group. Which leads to collisions * Update cast.py * using hass.data * Fixed and extended tests * Line length in tests * Lint in tests
This commit is contained in:
parent
99a20c845c
commit
c49cce7243
@ -33,7 +33,7 @@ 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 | \
|
||||||
SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA | SUPPORT_STOP | SUPPORT_PLAY
|
SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA | SUPPORT_STOP | SUPPORT_PLAY
|
||||||
|
|
||||||
KNOWN_HOSTS = []
|
KNOWN_HOSTS_KEY = 'cast_known_hosts'
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||||
vol.Optional(CONF_HOST): cv.string,
|
vol.Optional(CONF_HOST): cv.string,
|
||||||
@ -49,22 +49,29 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
# Import CEC IGNORE attributes
|
# Import CEC IGNORE attributes
|
||||||
pychromecast.IGNORE_CEC += config.get(CONF_IGNORE_CEC, [])
|
pychromecast.IGNORE_CEC += config.get(CONF_IGNORE_CEC, [])
|
||||||
|
|
||||||
hosts = []
|
known_hosts = hass.data.get(KNOWN_HOSTS_KEY)
|
||||||
|
if known_hosts is None:
|
||||||
|
known_hosts = hass.data[KNOWN_HOSTS_KEY] = []
|
||||||
|
|
||||||
if discovery_info:
|
if discovery_info:
|
||||||
host = (discovery_info.get('host'), discovery_info.get('port'))
|
host = (discovery_info.get('host'), discovery_info.get('port'))
|
||||||
|
|
||||||
if host in KNOWN_HOSTS:
|
if host in known_hosts:
|
||||||
return
|
return
|
||||||
|
|
||||||
hosts = [host]
|
hosts = [host]
|
||||||
|
|
||||||
elif CONF_HOST in config:
|
elif CONF_HOST in config:
|
||||||
hosts = [(config.get(CONF_HOST), DEFAULT_PORT)]
|
host = (config.get(CONF_HOST), DEFAULT_PORT)
|
||||||
|
|
||||||
|
if host in known_hosts:
|
||||||
|
return
|
||||||
|
|
||||||
|
hosts = [host]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
hosts = [tuple(dev[:2]) for dev in pychromecast.discover_chromecasts()
|
hosts = [tuple(dev[:2]) for dev in pychromecast.discover_chromecasts()
|
||||||
if tuple(dev[:2]) not in KNOWN_HOSTS]
|
if tuple(dev[:2]) not in known_hosts]
|
||||||
|
|
||||||
casts = []
|
casts = []
|
||||||
|
|
||||||
@ -73,19 +80,24 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
all_chromecasts = pychromecast.get_chromecasts()
|
all_chromecasts = pychromecast.get_chromecasts()
|
||||||
|
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
|
(_, port) = host
|
||||||
found = [device for device in all_chromecasts
|
found = [device for device in all_chromecasts
|
||||||
if (device.host, device.port) == host]
|
if (device.host, device.port) == host]
|
||||||
if found:
|
if found:
|
||||||
try:
|
try:
|
||||||
casts.append(CastDevice(found[0]))
|
casts.append(CastDevice(found[0]))
|
||||||
KNOWN_HOSTS.append(host)
|
known_hosts.append(host)
|
||||||
except pychromecast.ChromecastConnectionError:
|
except pychromecast.ChromecastConnectionError:
|
||||||
pass
|
pass
|
||||||
else:
|
|
||||||
|
# do not add groups using pychromecast.Chromecast as it leads to names
|
||||||
|
# collision since pychromecast.Chromecast will get device name instead
|
||||||
|
# of group name
|
||||||
|
elif port == DEFAULT_PORT:
|
||||||
try:
|
try:
|
||||||
# add the device anyway, get_chromecasts couldn't find it
|
# add the device anyway, get_chromecasts couldn't find it
|
||||||
casts.append(CastDevice(pychromecast.Chromecast(*host)))
|
casts.append(CastDevice(pychromecast.Chromecast(*host)))
|
||||||
KNOWN_HOSTS.append(host)
|
known_hosts.append(host)
|
||||||
except pychromecast.ChromecastConnectionError:
|
except pychromecast.ChromecastConnectionError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from unittest.mock import patch, MagicMock
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.media_player import cast
|
from homeassistant.components.media_player import cast
|
||||||
|
from tests.common import get_test_home_assistant
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
@ -29,6 +30,14 @@ class FakeChromeCast(object):
|
|||||||
class TestCastMediaPlayer(unittest.TestCase):
|
class TestCastMediaPlayer(unittest.TestCase):
|
||||||
"""Test the media_player module."""
|
"""Test the media_player module."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Setup things to be run when tests are started."""
|
||||||
|
self.hass = get_test_home_assistant()
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
"""Stop everything that was started."""
|
||||||
|
self.hass.stop()
|
||||||
|
|
||||||
@patch('homeassistant.components.media_player.cast.CastDevice')
|
@patch('homeassistant.components.media_player.cast.CastDevice')
|
||||||
@patch('pychromecast.get_chromecasts')
|
@patch('pychromecast.get_chromecasts')
|
||||||
def test_filter_duplicates(self, mock_get_chromecasts, mock_device):
|
def test_filter_duplicates(self, mock_get_chromecasts, mock_device):
|
||||||
@ -38,7 +47,7 @@ class TestCastMediaPlayer(unittest.TestCase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Test chromecasts as if they were hardcoded in configuration.yaml
|
# Test chromecasts as if they were hardcoded in configuration.yaml
|
||||||
cast.setup_platform(None, {
|
cast.setup_platform(self.hass, {
|
||||||
'host': 'some_host'
|
'host': 'some_host'
|
||||||
}, lambda _: _)
|
}, lambda _: _)
|
||||||
|
|
||||||
@ -48,8 +57,44 @@ class TestCastMediaPlayer(unittest.TestCase):
|
|||||||
assert not mock_device.called
|
assert not mock_device.called
|
||||||
|
|
||||||
# Test chromecasts as if they were automatically discovered
|
# Test chromecasts as if they were automatically discovered
|
||||||
cast.setup_platform(None, {}, lambda _: _, {
|
cast.setup_platform(self.hass, {}, lambda _: _, {
|
||||||
'host': 'some_host',
|
'host': 'some_host',
|
||||||
'port': cast.DEFAULT_PORT,
|
'port': cast.DEFAULT_PORT,
|
||||||
})
|
})
|
||||||
assert not mock_device.called
|
assert not mock_device.called
|
||||||
|
|
||||||
|
@patch('homeassistant.components.media_player.cast.CastDevice')
|
||||||
|
@patch('pychromecast.get_chromecasts')
|
||||||
|
@patch('pychromecast.Chromecast')
|
||||||
|
def test_fallback_cast(self, mock_chromecast, mock_get_chromecasts,
|
||||||
|
mock_device):
|
||||||
|
"""Test falling back to creating Chromecast when not discovered."""
|
||||||
|
mock_get_chromecasts.return_value = [
|
||||||
|
FakeChromeCast('some_host', cast.DEFAULT_PORT)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Test chromecasts as if they were hardcoded in configuration.yaml
|
||||||
|
cast.setup_platform(self.hass, {
|
||||||
|
'host': 'some_other_host'
|
||||||
|
}, lambda _: _)
|
||||||
|
|
||||||
|
assert mock_chromecast.called
|
||||||
|
assert mock_device.called
|
||||||
|
|
||||||
|
@patch('homeassistant.components.media_player.cast.CastDevice')
|
||||||
|
@patch('pychromecast.get_chromecasts')
|
||||||
|
@patch('pychromecast.Chromecast')
|
||||||
|
def test_fallback_cast_group(self, mock_chromecast, mock_get_chromecasts,
|
||||||
|
mock_device):
|
||||||
|
"""Test not creating Cast Group when not discovered."""
|
||||||
|
mock_get_chromecasts.return_value = [
|
||||||
|
FakeChromeCast('some_host', cast.DEFAULT_PORT)
|
||||||
|
]
|
||||||
|
|
||||||
|
# Test chromecasts as if they were automatically discovered
|
||||||
|
cast.setup_platform(self.hass, {}, lambda _: _, {
|
||||||
|
'host': 'some_other_host',
|
||||||
|
'port': 43546,
|
||||||
|
})
|
||||||
|
assert not mock_chromecast.called
|
||||||
|
assert not mock_device.called
|
||||||
|
Loading…
x
Reference in New Issue
Block a user