Sonos specify IP for event subscription (#4177)
parent
b0a800cc6d
commit
83a108b20a
|
@ -15,9 +15,10 @@ from homeassistant.components.media_player import (
|
|||
ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK,
|
||||
SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
|
||||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_CLEAR_PLAYLIST,
|
||||
SUPPORT_SELECT_SOURCE, MediaPlayerDevice)
|
||||
SUPPORT_SELECT_SOURCE, MediaPlayerDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.const import (
|
||||
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_OFF, ATTR_ENTITY_ID)
|
||||
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_OFF, ATTR_ENTITY_ID,
|
||||
CONF_HOSTS)
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
@ -49,9 +50,18 @@ SERVICE_CLEAR_TIMER = 'sonos_clear_sleep_timer'
|
|||
SUPPORT_SOURCE_LINEIN = 'Line-in'
|
||||
SUPPORT_SOURCE_TV = 'TV'
|
||||
|
||||
CONF_ADVERTISE_ADDR = 'advertise_addr'
|
||||
CONF_INTERFACE_ADDR = 'interface_addr'
|
||||
|
||||
# Service call validation schemas
|
||||
ATTR_SLEEP_TIME = 'sleep_time'
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Optional(CONF_ADVERTISE_ADDR): cv.string,
|
||||
vol.Optional(CONF_INTERFACE_ADDR): cv.string,
|
||||
vol.Optional(CONF_HOSTS): cv.ensure_list(cv.string),
|
||||
})
|
||||
|
||||
SONOS_SCHEMA = vol.Schema({
|
||||
ATTR_ENTITY_ID: cv.entity_ids,
|
||||
})
|
||||
|
@ -70,6 +80,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
import soco
|
||||
global DEVICES
|
||||
|
||||
advertise_addr = config.get(CONF_ADVERTISE_ADDR, None)
|
||||
if advertise_addr:
|
||||
soco.config.EVENT_ADVERTISE_IP = advertise_addr
|
||||
|
||||
if discovery_info:
|
||||
player = soco.SoCo(discovery_info)
|
||||
|
||||
|
@ -87,18 +101,18 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
return False
|
||||
|
||||
players = None
|
||||
hosts = config.get('hosts', None)
|
||||
hosts = config.get(CONF_HOSTS, None)
|
||||
if hosts:
|
||||
# Support retro compatibility with comma separated list of hosts
|
||||
# from config
|
||||
hosts = hosts[0] if len(hosts) == 1 else hosts
|
||||
hosts = hosts.split(',') if isinstance(hosts, str) else hosts
|
||||
players = []
|
||||
for host in hosts:
|
||||
players.append(soco.SoCo(socket.gethostbyname(host)))
|
||||
|
||||
if not players:
|
||||
players = soco.discover(interface_addr=config.get('interface_addr',
|
||||
None))
|
||||
players = soco.discover(interface_addr=config.get(CONF_INTERFACE_ADDR))
|
||||
|
||||
if not players:
|
||||
_LOGGER.warning('No Sonos speakers found.')
|
||||
|
|
|
@ -5,7 +5,11 @@ import soco.snapshot
|
|||
from unittest import mock
|
||||
import soco
|
||||
|
||||
from homeassistant.components.media_player import sonos
|
||||
from homeassistant.bootstrap import setup_component
|
||||
from homeassistant.components.media_player import sonos, DOMAIN
|
||||
from homeassistant.components.media_player.sonos import CONF_INTERFACE_ADDR, \
|
||||
CONF_ADVERTISE_ADDR
|
||||
from homeassistant.const import CONF_HOSTS, CONF_PLATFORM
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
@ -134,20 +138,95 @@ class TestSonosMediaPlayer(unittest.TestCase):
|
|||
"""Test a single device using the autodiscovery provided by HASS."""
|
||||
sonos.setup_platform(self.hass, {}, fake_add_device, '192.0.2.1')
|
||||
|
||||
# Ensure registration took place (#2558)
|
||||
self.assertEqual(len(sonos.DEVICES), 1)
|
||||
self.assertEqual(sonos.DEVICES[0].name, 'Kitchen')
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
def test_ensure_setup_config(self, *args):
|
||||
"""Test a single address config'd by the HASS config file."""
|
||||
sonos.setup_platform(self.hass,
|
||||
{'hosts': '192.0.2.1'},
|
||||
fake_add_device)
|
||||
@mock.patch('soco.discover')
|
||||
def test_ensure_setup_config_interface_addr(self, discover_mock, *args):
|
||||
"""Test a interface address config'd by the HASS config file."""
|
||||
discover_mock.return_value = {SoCoMock('192.0.2.1')}
|
||||
|
||||
config = {
|
||||
DOMAIN: {
|
||||
CONF_PLATFORM: 'sonos',
|
||||
CONF_INTERFACE_ADDR: '192.0.1.1',
|
||||
}
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, DOMAIN, config)
|
||||
|
||||
# Ensure registration took place (#2558)
|
||||
self.assertEqual(len(sonos.DEVICES), 1)
|
||||
self.assertEqual(discover_mock.call_count, 1)
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
@mock.patch('soco.discover')
|
||||
def test_ensure_setup_config_advertise_addr(self, discover_mock,
|
||||
*args):
|
||||
"""Test a advertise address config'd by the HASS config file."""
|
||||
discover_mock.return_value = {SoCoMock('192.0.2.1')}
|
||||
|
||||
config = {
|
||||
DOMAIN: {
|
||||
CONF_PLATFORM: 'sonos',
|
||||
CONF_ADVERTISE_ADDR: '192.0.1.1',
|
||||
}
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, DOMAIN, config)
|
||||
|
||||
self.assertEqual(len(sonos.DEVICES), 1)
|
||||
self.assertEqual(discover_mock.call_count, 1)
|
||||
self.assertEqual(soco.config.EVENT_ADVERTISE_IP, '192.0.1.1')
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
def test_ensure_setup_config_hosts_string_single(self, *args):
|
||||
"""Test a single address config'd by the HASS config file."""
|
||||
config = {
|
||||
DOMAIN: {
|
||||
CONF_PLATFORM: 'sonos',
|
||||
CONF_HOSTS: ['192.0.2.1'],
|
||||
}
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, DOMAIN, config)
|
||||
|
||||
self.assertEqual(len(sonos.DEVICES), 1)
|
||||
self.assertEqual(sonos.DEVICES[0].name, 'Kitchen')
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
def test_ensure_setup_config_hosts_string_multiple(self, *args):
|
||||
"""Test multiple address string config'd by the HASS config file."""
|
||||
config = {
|
||||
DOMAIN: {
|
||||
CONF_PLATFORM: 'sonos',
|
||||
CONF_HOSTS: ['192.0.2.1,192.168.2.2'],
|
||||
}
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, DOMAIN, config)
|
||||
|
||||
self.assertEqual(len(sonos.DEVICES), 2)
|
||||
self.assertEqual(sonos.DEVICES[0].name, 'Kitchen')
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
def test_ensure_setup_config_hosts_list(self, *args):
|
||||
"""Test a multiple address list config'd by the HASS config file."""
|
||||
config = {
|
||||
DOMAIN: {
|
||||
CONF_PLATFORM: 'sonos',
|
||||
CONF_HOSTS: ['192.0.2.1', '192.168.2.2'],
|
||||
}
|
||||
}
|
||||
|
||||
assert setup_component(self.hass, DOMAIN, config)
|
||||
|
||||
self.assertEqual(len(sonos.DEVICES), 2)
|
||||
self.assertEqual(sonos.DEVICES[0].name, 'Kitchen')
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
|
|
Loading…
Reference in New Issue