mirror of
https://github.com/home-assistant/core.git
synced 2025-06-25 01:21:51 +02:00
Add Bose SoundTouch device support - v2 (#4523)
* Add Bose SoundTouch device support * Update soundtouch.py
This commit is contained in:
committed by
Paulus Schoutsen
parent
64cfc4ff02
commit
c9b353f7a7
@ -204,3 +204,36 @@ sonos_clear_sleep_timer:
|
||||
entity_id:
|
||||
description: Name(s) of entites that will have the timer cleared.
|
||||
example: 'media_player.living_room_sonos'
|
||||
|
||||
|
||||
soundtouch_play_everywhere:
|
||||
description: Play on all Bose Soundtouch devices
|
||||
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of entites that will coordinate the grouping. Platform dependent. It is a shortcut for creating a multi-room zone with all devices
|
||||
example: 'media_player.soundtouch_home'
|
||||
|
||||
soundtouch_create_zone:
|
||||
description: Create a multi-room zone
|
||||
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of entites that will coordinate the multi-room zone. Platform dependent.
|
||||
example: 'media_player.soundtouch_home'
|
||||
|
||||
soundtouch_add_zone_slave:
|
||||
description: Add a slave to a multi-room zone
|
||||
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of entites that will be added to the multi-room zone. Platform dependent.
|
||||
example: 'media_player.soundtouch_home'
|
||||
|
||||
soundtouch_remove_zone_slave:
|
||||
description: Remove a slave from the multi-room zone
|
||||
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name of entites that will be remove from the multi-room zone. Platform dependent.
|
||||
example: 'media_player.soundtouch_home'
|
393
homeassistant/components/media_player/soundtouch.py
Normal file
393
homeassistant/components/media_player/soundtouch.py
Normal file
@ -0,0 +1,393 @@
|
||||
"""Support for interface with a Bose Soundtouch."""
|
||||
import logging
|
||||
|
||||
from os import path
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.components.media_player import (
|
||||
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK,
|
||||
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP,
|
||||
SUPPORT_VOLUME_SET, SUPPORT_TURN_ON, MediaPlayerDevice, PLATFORM_SCHEMA)
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
from homeassistant.const import (CONF_HOST, CONF_NAME, STATE_OFF, CONF_PORT,
|
||||
STATE_PAUSED, STATE_PLAYING,
|
||||
STATE_UNAVAILABLE)
|
||||
|
||||
REQUIREMENTS = ['libsoundtouch==0.1.0']
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DOMAIN = 'media_player'
|
||||
SERVICE_PLAY_EVERYWHERE = 'soundtouch_play_everywhere'
|
||||
SERVICE_CREATE_ZONE = 'soundtouch_create_zone'
|
||||
SERVICE_ADD_ZONE_SLAVE = 'soundtouch_add_zone_slave'
|
||||
SERVICE_REMOVE_ZONE_SLAVE = 'soundtouch_remove_zone_slave'
|
||||
|
||||
MAP_STATUS = {
|
||||
"PLAY_STATE": STATE_PLAYING,
|
||||
"BUFFERING_STATE": STATE_PLAYING,
|
||||
"PAUSE_STATE": STATE_PAUSED,
|
||||
"STOp_STATE": STATE_OFF
|
||||
}
|
||||
|
||||
SOUNDTOUCH_PLAY_EVERYWHERE = vol.Schema({
|
||||
'master': cv.entity_id,
|
||||
})
|
||||
|
||||
SOUNDTOUCH_CREATE_ZONE_SCHEMA = vol.Schema({
|
||||
'master': cv.entity_id,
|
||||
'slaves': cv.entity_ids
|
||||
})
|
||||
|
||||
SOUNDTOUCH_ADD_ZONE_SCHEMA = vol.Schema({
|
||||
'master': cv.entity_id,
|
||||
'slaves': cv.entity_ids
|
||||
})
|
||||
|
||||
SOUNDTOUCH_REMOVE_ZONE_SCHEMA = vol.Schema({
|
||||
'master': cv.entity_id,
|
||||
'slaves': cv.entity_ids
|
||||
})
|
||||
|
||||
DEFAULT_NAME = 'Bose Soundtouch'
|
||||
DEFAULT_PORT = 8090
|
||||
|
||||
DEVICES = []
|
||||
|
||||
SUPPORT_SOUNDTOUCH = SUPPORT_PAUSE | SUPPORT_VOLUME_STEP | \
|
||||
SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | \
|
||||
SUPPORT_NEXT_TRACK | SUPPORT_TURN_OFF | \
|
||||
SUPPORT_VOLUME_SET | SUPPORT_TURN_ON
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||
vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Setup the Bose Soundtouch platform."""
|
||||
name = config.get(CONF_NAME)
|
||||
|
||||
remote_config = {
|
||||
'name': 'HomeAssistant',
|
||||
'description': config.get(CONF_NAME),
|
||||
'id': 'ha.component.soundtouch',
|
||||
'port': config.get(CONF_PORT),
|
||||
'host': config.get(CONF_HOST)
|
||||
}
|
||||
|
||||
soundtouch_device = SoundTouchDevice(name, remote_config)
|
||||
DEVICES.append(soundtouch_device)
|
||||
add_devices([soundtouch_device])
|
||||
|
||||
descriptions = load_yaml_config_file(
|
||||
path.join(path.dirname(__file__), 'services.yaml'))
|
||||
|
||||
hass.services.register(DOMAIN, SERVICE_PLAY_EVERYWHERE,
|
||||
play_everywhere_service,
|
||||
descriptions.get(SERVICE_PLAY_EVERYWHERE),
|
||||
schema=SOUNDTOUCH_PLAY_EVERYWHERE)
|
||||
hass.services.register(DOMAIN, SERVICE_CREATE_ZONE,
|
||||
create_zone_service,
|
||||
descriptions.get(SERVICE_CREATE_ZONE),
|
||||
schema=SOUNDTOUCH_CREATE_ZONE_SCHEMA)
|
||||
hass.services.register(DOMAIN, SERVICE_REMOVE_ZONE_SLAVE,
|
||||
remove_zone_slave,
|
||||
descriptions.get(SERVICE_REMOVE_ZONE_SLAVE),
|
||||
schema=SOUNDTOUCH_REMOVE_ZONE_SCHEMA)
|
||||
hass.services.register(DOMAIN, SERVICE_ADD_ZONE_SLAVE,
|
||||
add_zone_slave,
|
||||
descriptions.get(SERVICE_ADD_ZONE_SLAVE),
|
||||
schema=SOUNDTOUCH_ADD_ZONE_SCHEMA)
|
||||
|
||||
|
||||
def play_everywhere_service(service):
|
||||
"""
|
||||
Create a zone (multi-room) and play on all devices.
|
||||
|
||||
:param service: Home Assistant service with 'master' data set
|
||||
|
||||
:Example:
|
||||
|
||||
- service: media_player.soundtouch_play_everywhere
|
||||
data:
|
||||
master: media_player.soundtouch_living_room
|
||||
|
||||
"""
|
||||
master_device_id = service.data.get('master')
|
||||
slaves = [d for d in DEVICES if d.entity_id != master_device_id]
|
||||
master = next([device for device in DEVICES if
|
||||
device.entity_id == master_device_id].__iter__(), None)
|
||||
if master is None:
|
||||
_LOGGER.warning(
|
||||
"Unable to find master with entity_id:" + str(master_device_id))
|
||||
elif not slaves:
|
||||
_LOGGER.warning("Unable to create zone without slaves")
|
||||
else:
|
||||
_LOGGER.info(
|
||||
"Creating zone with master " + str(master.device.config.name))
|
||||
master.device.create_zone([slave.device for slave in slaves])
|
||||
|
||||
|
||||
def create_zone_service(service):
|
||||
"""
|
||||
Create a zone (multi-room) on a master and play on specified slaves.
|
||||
|
||||
At least one master and one slave must be specified
|
||||
|
||||
:param service: Home Assistant service with 'master' and 'slaves' data set
|
||||
|
||||
:Example:
|
||||
|
||||
- service: media_player.soundtouch_create_zone
|
||||
data:
|
||||
master: media_player.soundtouch_living_room
|
||||
slaves:
|
||||
- media_player.soundtouch_room
|
||||
- media_player.soundtouch_kitchen
|
||||
|
||||
"""
|
||||
master_device_id = service.data.get('master')
|
||||
slaves_ids = service.data.get('slaves')
|
||||
slaves = [device for device in DEVICES if device.entity_id in slaves_ids]
|
||||
master = next([device for device in DEVICES if
|
||||
device.entity_id == master_device_id].__iter__(), None)
|
||||
if master is None:
|
||||
_LOGGER.warning(
|
||||
"Unable to find master with entity_id:" + master_device_id)
|
||||
elif not slaves:
|
||||
_LOGGER.warning("Unable to create zone without slaves")
|
||||
else:
|
||||
_LOGGER.info(
|
||||
"Creating zone with master " + str(master.device.config.name))
|
||||
master.device.create_zone([slave.device for slave in slaves])
|
||||
|
||||
|
||||
def add_zone_slave(service):
|
||||
"""
|
||||
Add slave(s) to and existing zone (multi-room).
|
||||
|
||||
Zone must already exist and slaves array can not be empty.
|
||||
|
||||
:param service: Home Assistant service with 'master' and 'slaves' data set
|
||||
|
||||
:Example:
|
||||
|
||||
- service: media_player.soundtouch_add_zone_slave
|
||||
data:
|
||||
master: media_player.soundtouch_living_room
|
||||
slaves:
|
||||
- media_player.soundtouch_room
|
||||
|
||||
"""
|
||||
master_device_id = service.data.get('master')
|
||||
slaves_ids = service.data.get('slaves')
|
||||
slaves = [device for device in DEVICES if device.entity_id in slaves_ids]
|
||||
master = next([device for device in DEVICES if
|
||||
device.entity_id == master_device_id].__iter__(), None)
|
||||
if master is None:
|
||||
_LOGGER.warning(
|
||||
"Unable to find master with entity_id:" + str(master_device_id))
|
||||
elif not slaves:
|
||||
_LOGGER.warning("Unable to find slaves to add")
|
||||
else:
|
||||
_LOGGER.info(
|
||||
"Adding slaves to zone with master " + str(
|
||||
master.device.config.name))
|
||||
master.device.add_zone_slave([slave.device for slave in slaves])
|
||||
|
||||
|
||||
def remove_zone_slave(service):
|
||||
"""
|
||||
Remove slave(s) from and existing zone (multi-room).
|
||||
|
||||
Zone must already exist and slaves array can not be empty.
|
||||
Note: If removing last slave, the zone will be deleted and you'll have to
|
||||
create a new one. You will not be able to add a new slave anymore
|
||||
|
||||
:param service: Home Assistant service with 'master' and 'slaves' data set
|
||||
|
||||
:Example:
|
||||
|
||||
- service: media_player.soundtouch_remove_zone_slave
|
||||
data:
|
||||
master: media_player.soundtouch_living_room
|
||||
slaves:
|
||||
- media_player.soundtouch_room
|
||||
|
||||
"""
|
||||
master_device_id = service.data.get('master')
|
||||
slaves_ids = service.data.get('slaves')
|
||||
slaves = [device for device in DEVICES if device.entity_id in slaves_ids]
|
||||
master = next([device for device in DEVICES if
|
||||
device.entity_id == master_device_id].__iter__(), None)
|
||||
if master is None:
|
||||
_LOGGER.warning(
|
||||
"Unable to find master with entity_id:" + master_device_id)
|
||||
elif not slaves:
|
||||
_LOGGER.warning("Unable to find slaves to remove")
|
||||
else:
|
||||
_LOGGER.info("Removing slaves from zone with master " +
|
||||
str(master.device.config.name))
|
||||
master.device.remove_zone_slave([slave.device for slave in slaves])
|
||||
|
||||
|
||||
class SoundTouchDevice(MediaPlayerDevice):
|
||||
"""Representation of a SoundTouch Bose device."""
|
||||
|
||||
def __init__(self, name, config):
|
||||
"""Create Soundtouch Entity."""
|
||||
from libsoundtouch import soundtouch_device
|
||||
self._name = name
|
||||
self._device = soundtouch_device(config['host'], config['port'])
|
||||
self._status = self._device.status()
|
||||
self._volume = self._device.volume()
|
||||
self._config = config
|
||||
|
||||
@property
|
||||
def config(self):
|
||||
"""Return specific soundtouch configuration."""
|
||||
return self._config
|
||||
|
||||
@property
|
||||
def device(self):
|
||||
"""Return Soundtouch device."""
|
||||
return self._device
|
||||
|
||||
def update(self):
|
||||
"""Retrieve the latest data."""
|
||||
self._status = self._device.status()
|
||||
self._volume = self._device.volume()
|
||||
|
||||
@property
|
||||
def volume_level(self):
|
||||
"""Volume level of the media player (0..1)."""
|
||||
return self._volume.actual / 100
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the device."""
|
||||
if self._status.source == 'STANDBY':
|
||||
return STATE_OFF
|
||||
else:
|
||||
return MAP_STATUS.get(self._status.play_status, STATE_UNAVAILABLE)
|
||||
|
||||
@property
|
||||
def is_volume_muted(self):
|
||||
"""Boolean if volume is currently muted."""
|
||||
return self._volume.muted
|
||||
|
||||
@property
|
||||
def supported_media_commands(self):
|
||||
"""Flag of media commands that are supported."""
|
||||
return SUPPORT_SOUNDTOUCH
|
||||
|
||||
def turn_off(self):
|
||||
"""Turn off media player."""
|
||||
self._device.power_off()
|
||||
self._status = self._device.status()
|
||||
|
||||
def turn_on(self):
|
||||
"""Turn the media player on."""
|
||||
self._device.power_on()
|
||||
self._status = self._device.status()
|
||||
|
||||
def volume_up(self):
|
||||
"""Volume up the media player."""
|
||||
self._device.volume_up()
|
||||
self._volume = self._device.volume()
|
||||
|
||||
def volume_down(self):
|
||||
"""Volume down media player."""
|
||||
self._device.volume_down()
|
||||
self._volume = self._device.volume()
|
||||
|
||||
def set_volume_level(self, volume):
|
||||
"""Set volume level, range 0..1."""
|
||||
self._device.set_volume(int(volume * 100))
|
||||
self._volume = self._device.volume()
|
||||
|
||||
def mute_volume(self, mute):
|
||||
"""Send mute command."""
|
||||
self._device.mute()
|
||||
self._volume = self._device.volume()
|
||||
|
||||
def media_play_pause(self):
|
||||
"""Simulate play pause media player."""
|
||||
self._device.play_pause()
|
||||
self._status = self._device.status()
|
||||
|
||||
def media_play(self):
|
||||
"""Send play command."""
|
||||
self._device.play()
|
||||
self._status = self._device.status()
|
||||
|
||||
def media_pause(self):
|
||||
"""Send media pause command to media player."""
|
||||
self._device.pause()
|
||||
self._status = self._device.status()
|
||||
|
||||
def media_next_track(self):
|
||||
"""Send next track command."""
|
||||
self._device.next_track()
|
||||
self._status = self._device.status()
|
||||
|
||||
def media_previous_track(self):
|
||||
"""Send the previous track command."""
|
||||
self._device.previous_track()
|
||||
self._status = self._device.status()
|
||||
|
||||
@property
|
||||
def media_image_url(self):
|
||||
"""Image url of current playing media."""
|
||||
return self._status.image
|
||||
|
||||
@property
|
||||
def media_title(self):
|
||||
"""Title of current playing media."""
|
||||
if self._status.station_name is not None:
|
||||
return self._status.station_name
|
||||
elif self._status.artist is not None:
|
||||
return self._status.artist + " - " + self._status.track
|
||||
else:
|
||||
return None
|
||||
|
||||
@property
|
||||
def media_duration(self):
|
||||
"""Duration of current playing media in seconds."""
|
||||
return self._status.duration
|
||||
|
||||
@property
|
||||
def media_artist(self):
|
||||
"""Artist of current playing media."""
|
||||
return self._status.artist
|
||||
|
||||
@property
|
||||
def media_track(self):
|
||||
"""Artist of current playing media."""
|
||||
return self._status.track
|
||||
|
||||
@property
|
||||
def media_album_name(self):
|
||||
"""Album name of current playing media."""
|
||||
return self._status.album
|
||||
|
||||
def play_media(self, media_type, media_id, **kwargs):
|
||||
"""Play a piece of media."""
|
||||
_LOGGER.info("Starting media with media_id:" + str(media_id))
|
||||
presets = self._device.presets()
|
||||
preset = next([preset for preset in presets if
|
||||
preset.preset_id == str(media_id)].__iter__(), None)
|
||||
if preset is not None:
|
||||
_LOGGER.info("Playing preset: " + preset.name)
|
||||
self._device.select_preset(preset)
|
||||
else:
|
||||
_LOGGER.warning("Unable to find preset with id " + str(media_id))
|
@ -261,6 +261,9 @@ knxip==0.3.3
|
||||
# homeassistant.components.device_tracker.owntracks
|
||||
libnacl==1.5.0
|
||||
|
||||
# homeassistant.components.media_player.soundtouch
|
||||
libsoundtouch==0.1.0
|
||||
|
||||
# homeassistant.components.light.lifx
|
||||
liffylights==0.9.4
|
||||
|
||||
|
652
tests/components/media_player/test_soundtouch.py
Normal file
652
tests/components/media_player/test_soundtouch.py
Normal file
@ -0,0 +1,652 @@
|
||||
"""Test the Soundtouch component."""
|
||||
import logging
|
||||
import unittest
|
||||
from unittest import mock
|
||||
from libsoundtouch.device import SoundTouchDevice as STD, Status, Volume, \
|
||||
Preset, Config
|
||||
|
||||
from homeassistant.components.media_player import soundtouch
|
||||
from homeassistant.const import (
|
||||
STATE_OFF, STATE_PAUSED, STATE_PLAYING)
|
||||
from tests.common import get_test_home_assistant
|
||||
|
||||
|
||||
class MockService:
|
||||
"""Mock Soundtouch service."""
|
||||
|
||||
def __init__(self, master, slaves):
|
||||
"""Create a new service."""
|
||||
self.data = {
|
||||
"master": master,
|
||||
"slaves": slaves
|
||||
}
|
||||
|
||||
|
||||
def _mock_soundtouch_device(*args, **kwargs):
|
||||
return MockDevice()
|
||||
|
||||
|
||||
class MockDevice(STD):
|
||||
"""Mock device."""
|
||||
|
||||
def __init__(self):
|
||||
self._config = MockConfig
|
||||
|
||||
|
||||
class MockConfig(Config):
|
||||
"""Mock config."""
|
||||
|
||||
def __init__(self):
|
||||
self._name = "name"
|
||||
|
||||
|
||||
def _mocked_presets(*args, **kwargs):
|
||||
"""Return a list of mocked presets."""
|
||||
return [MockPreset("1")]
|
||||
|
||||
|
||||
class MockPreset(Preset):
|
||||
"""Mock preset."""
|
||||
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
self._name = "preset"
|
||||
|
||||
|
||||
class MockVolume(Volume):
|
||||
"""Mock volume with value."""
|
||||
|
||||
def __init__(self):
|
||||
self._actual = 12
|
||||
|
||||
|
||||
class MockVolumeMuted(Volume):
|
||||
"""Mock volume muted."""
|
||||
|
||||
def __init__(self):
|
||||
self._actual = 12
|
||||
self._muted = True
|
||||
|
||||
|
||||
class MockStatusStandby(Status):
|
||||
"""Mock status standby."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = "STANDBY"
|
||||
|
||||
|
||||
class MockStatusPlaying(Status):
|
||||
"""Mock status playing media."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = ""
|
||||
self._play_status = "PLAY_STATE"
|
||||
self._image = "image.url"
|
||||
self._artist = "artist"
|
||||
self._track = "track"
|
||||
self._album = "album"
|
||||
self._duration = 1
|
||||
self._station_name = None
|
||||
|
||||
|
||||
class MockStatusPlayingRadio(Status):
|
||||
"""Mock status radio."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = ""
|
||||
self._play_status = "PLAY_STATE"
|
||||
self._image = "image.url"
|
||||
self._artist = None
|
||||
self._track = None
|
||||
self._album = None
|
||||
self._duration = None
|
||||
self._station_name = "station"
|
||||
|
||||
|
||||
class MockStatusUnknown(Status):
|
||||
"""Mock status unknown media."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = ""
|
||||
self._play_status = "PLAY_STATE"
|
||||
self._image = "image.url"
|
||||
self._artist = None
|
||||
self._track = None
|
||||
self._album = None
|
||||
self._duration = None
|
||||
self._station_name = None
|
||||
|
||||
|
||||
class MockStatusPause(Status):
|
||||
"""Mock status pause."""
|
||||
|
||||
def __init__(self):
|
||||
self._source = ""
|
||||
self._play_status = "PAUSE_STATE"
|
||||
|
||||
|
||||
def default_component():
|
||||
"""Return a default component."""
|
||||
return {
|
||||
'host': '192.168.0.1',
|
||||
'port': 8090,
|
||||
'name': 'soundtouch'
|
||||
}
|
||||
|
||||
|
||||
class TestSoundtouchMediaPlayer(unittest.TestCase):
|
||||
"""Bose Soundtouch test class."""
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
"""Setup things to be run when tests are started."""
|
||||
self.hass = get_test_home_assistant()
|
||||
logging.disable(logging.CRITICAL)
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
logging.disable(logging.NOTSET)
|
||||
soundtouch.DEVICES = []
|
||||
self.hass.stop()
|
||||
|
||||
@mock.patch('libsoundtouch.soundtouch_device', side_effect=None)
|
||||
def test_ensure_setup_config(self, mocked_sountouch_device):
|
||||
"""Test setup OK."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
# soundtouch.DEVICES[0].entity_id = 'entity_1'
|
||||
self.assertEqual(len(soundtouch.DEVICES), 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].name, 'soundtouch')
|
||||
self.assertEqual(soundtouch.DEVICES[0].config['port'], 8090)
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_update(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test update device state."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
soundtouch.DEVICES[0].update()
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status',
|
||||
side_effect=MockStatusPlaying)
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_playing_media(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test playing media info."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].state, STATE_PLAYING)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_image_url, "image.url")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_title, "artist - track")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_track, "track")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_artist, "artist")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_album_name, "album")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_duration, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status',
|
||||
side_effect=MockStatusUnknown)
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_playing_unknown_media(self, mocked_sountouch_device,
|
||||
mocked_status, mocked_volume):
|
||||
"""Test playing media info."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_title, None)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status',
|
||||
side_effect=MockStatusPlayingRadio)
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_playing_radio(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test playing radio info."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].state, STATE_PLAYING)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_image_url, "image.url")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_title, "station")
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_track, None)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_artist, None)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_album_name, None)
|
||||
self.assertEqual(soundtouch.DEVICES[0].media_duration, None)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume',
|
||||
side_effect=MockVolume)
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_get_volume_level(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test volume level."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].volume_level, 0.12)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status',
|
||||
side_effect=MockStatusStandby)
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_get_state_off(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test state device is off."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].state, STATE_OFF)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status',
|
||||
side_effect=MockStatusPause)
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_get_state_pause(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test state device is paused."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].state, STATE_PAUSED)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume',
|
||||
side_effect=MockVolumeMuted)
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_is_muted(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume):
|
||||
"""Test device volume is muted."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].is_volume_muted, True)
|
||||
|
||||
@mock.patch('libsoundtouch.soundtouch_device')
|
||||
def test_media_commands(self, mocked_sountouch_device):
|
||||
"""Test supported media commands."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(soundtouch.DEVICES[0].supported_media_commands, 1469)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.power_off')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_should_turn_off(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_power_off):
|
||||
"""Test device is turned off."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].turn_off()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(mocked_power_off.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.power_on')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_should_turn_on(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_power_on):
|
||||
"""Test device is turned on."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].turn_on()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(mocked_power_on.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume_up')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_volume_up(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_volume_up):
|
||||
"""Test volume up."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].volume_up()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
self.assertEqual(mocked_volume_up.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume_down')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_volume_down(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_volume_down):
|
||||
"""Test volume down."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].volume_down()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
self.assertEqual(mocked_volume_down.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.set_volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_set_volume_level(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_set_volume):
|
||||
"""Test set volume level."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].set_volume_level(0.17)
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
mocked_set_volume.assert_called_with(17)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.mute')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_mute(self, mocked_sountouch_device, mocked_status, mocked_volume,
|
||||
mocked_mute):
|
||||
"""Test mute volume."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].mute_volume(None)
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
self.assertEqual(mocked_mute.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.play')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_play(self, mocked_sountouch_device, mocked_status, mocked_volume,
|
||||
mocked_play):
|
||||
"""Test play command."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].media_play()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(mocked_play.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.pause')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_pause(self, mocked_sountouch_device, mocked_status, mocked_volume,
|
||||
mocked_pause):
|
||||
"""Test pause command."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].media_pause()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(mocked_pause.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.play_pause')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_play_pause_play(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_play_pause):
|
||||
"""Test play/pause."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].media_play_pause()
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
self.assertEqual(mocked_play_pause.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.previous_track')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.next_track')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_next_previous_track(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_next_track,
|
||||
mocked_previous_track):
|
||||
"""Test next/previous track."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
soundtouch.DEVICES[0].media_next_track()
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_next_track.call_count, 1)
|
||||
soundtouch.DEVICES[0].media_previous_track()
|
||||
self.assertEqual(mocked_status.call_count, 3)
|
||||
self.assertEqual(mocked_previous_track.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.select_preset')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.presets',
|
||||
side_effect=_mocked_presets)
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_play_media(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_presets, mocked_select_preset):
|
||||
"""Test play preset 1."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 1)
|
||||
self.assertEqual(mocked_status.call_count, 1)
|
||||
self.assertEqual(mocked_volume.call_count, 1)
|
||||
soundtouch.DEVICES[0].play_media('PLAYLIST', 1)
|
||||
self.assertEqual(mocked_presets.call_count, 1)
|
||||
self.assertEqual(mocked_select_preset.call_count, 1)
|
||||
soundtouch.DEVICES[0].play_media('PLAYLIST', 2)
|
||||
self.assertEqual(mocked_presets.call_count, 2)
|
||||
self.assertEqual(mocked_select_preset.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.create_zone')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_play_everywhere(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_create_zone):
|
||||
"""Test play everywhere."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].entity_id = "entity_1"
|
||||
soundtouch.DEVICES[1].entity_id = "entity_2"
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 2)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
|
||||
# one master, one slave => create zone
|
||||
service = MockService("entity_1", [])
|
||||
soundtouch.play_everywhere_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
# unknown master. create zone is must not be called
|
||||
service = MockService("entity_X", [])
|
||||
soundtouch.play_everywhere_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
# no slaves, create zone must not be called
|
||||
soundtouch.DEVICES.pop(1)
|
||||
service = MockService("entity_1", [])
|
||||
soundtouch.play_everywhere_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.create_zone')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_create_zone(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_create_zone):
|
||||
"""Test creating a zone."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].entity_id = "entity_1"
|
||||
soundtouch.DEVICES[1].entity_id = "entity_2"
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 2)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
|
||||
# one master, one slave => create zone
|
||||
service = MockService("entity_1", ["entity_2"])
|
||||
soundtouch.create_zone_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
# unknown master. create zone is must not be called
|
||||
service = MockService("entity_X", [])
|
||||
soundtouch.create_zone_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
# no slaves, create zone must not be called
|
||||
soundtouch.DEVICES.pop(1)
|
||||
service = MockService("entity_1", [])
|
||||
soundtouch.create_zone_service(service)
|
||||
self.assertEqual(mocked_create_zone.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.add_zone_slave')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_add_zone_slave(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_add_zone_slave):
|
||||
"""Test adding a slave to an existing zone."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].entity_id = "entity_1"
|
||||
soundtouch.DEVICES[1].entity_id = "entity_2"
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 2)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
|
||||
# remove one slave
|
||||
service = MockService("entity_1", ["entity_2"])
|
||||
soundtouch.add_zone_slave(service)
|
||||
self.assertEqual(mocked_add_zone_slave.call_count, 1)
|
||||
|
||||
# unknown master. add zone slave is not called
|
||||
service = MockService("entity_X", ["entity_2"])
|
||||
soundtouch.add_zone_slave(service)
|
||||
self.assertEqual(mocked_add_zone_slave.call_count, 1)
|
||||
|
||||
# no slave to add, add zone slave is not called
|
||||
service = MockService("entity_1", [])
|
||||
soundtouch.add_zone_slave(service)
|
||||
self.assertEqual(mocked_add_zone_slave.call_count, 1)
|
||||
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.remove_zone_slave')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.volume')
|
||||
@mock.patch('libsoundtouch.device.SoundTouchDevice.status')
|
||||
@mock.patch('libsoundtouch.soundtouch_device',
|
||||
side_effect=_mock_soundtouch_device)
|
||||
def test_remove_zone_slave(self, mocked_sountouch_device, mocked_status,
|
||||
mocked_volume, mocked_remove_zone_slave):
|
||||
"""Test removing a slave from a zone."""
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.setup_platform(self.hass,
|
||||
default_component(),
|
||||
mock.MagicMock())
|
||||
soundtouch.DEVICES[0].entity_id = "entity_1"
|
||||
soundtouch.DEVICES[1].entity_id = "entity_2"
|
||||
self.assertEqual(mocked_sountouch_device.call_count, 2)
|
||||
self.assertEqual(mocked_status.call_count, 2)
|
||||
self.assertEqual(mocked_volume.call_count, 2)
|
||||
|
||||
# remove one slave
|
||||
service = MockService("entity_1", ["entity_2"])
|
||||
soundtouch.remove_zone_slave(service)
|
||||
self.assertEqual(mocked_remove_zone_slave.call_count, 1)
|
||||
|
||||
# unknown master. remove zone slave is not called
|
||||
service = MockService("entity_X", ["entity_2"])
|
||||
soundtouch.remove_zone_slave(service)
|
||||
self.assertEqual(mocked_remove_zone_slave.call_count, 1)
|
||||
|
||||
# no slave to add, add zone slave is not called
|
||||
service = MockService("entity_1", [])
|
||||
soundtouch.remove_zone_slave(service)
|
||||
self.assertEqual(mocked_remove_zone_slave.call_count, 1)
|
Reference in New Issue
Block a user