mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 22:37:11 +00:00
Add sonos alarm clock update service (#7521)
* Add sonos alarm clock update service * Add tests and break lines * Fix style errors * Make test work with python<3.6 * Fix last two pylint errors * fix new line to long errors
This commit is contained in:
parent
5c4a21efac
commit
4da91d6a8b
@ -51,6 +51,7 @@ SERVICE_SNAPSHOT = 'sonos_snapshot'
|
||||
SERVICE_RESTORE = 'sonos_restore'
|
||||
SERVICE_SET_TIMER = 'sonos_set_sleep_timer'
|
||||
SERVICE_CLEAR_TIMER = 'sonos_clear_sleep_timer'
|
||||
SERVICE_UPDATE_ALARM = 'sonos_update_alarm'
|
||||
|
||||
DATA_SONOS = 'sonos'
|
||||
|
||||
@ -62,6 +63,11 @@ CONF_INTERFACE_ADDR = 'interface_addr'
|
||||
|
||||
# Service call validation schemas
|
||||
ATTR_SLEEP_TIME = 'sleep_time'
|
||||
ATTR_ALARM_ID = 'alarm_id'
|
||||
ATTR_VOLUME = 'volume'
|
||||
ATTR_ENABLED = 'enabled'
|
||||
ATTR_INCLUDE_LINKED_ZONES = 'include_linked_zones'
|
||||
ATTR_TIME = 'time'
|
||||
ATTR_MASTER = 'master'
|
||||
ATTR_WITH_GROUP = 'with_group'
|
||||
|
||||
@ -90,6 +96,14 @@ SONOS_SET_TIMER_SCHEMA = SONOS_SCHEMA.extend({
|
||||
vol.All(vol.Coerce(int), vol.Range(min=0, max=86399))
|
||||
})
|
||||
|
||||
SONOS_UPDATE_ALARM_SCHEMA = SONOS_SCHEMA.extend({
|
||||
vol.Required(ATTR_ALARM_ID): cv.positive_int,
|
||||
vol.Optional(ATTR_TIME): cv.time,
|
||||
vol.Optional(ATTR_VOLUME): cv.small_float,
|
||||
vol.Optional(ATTR_ENABLED): cv.boolean,
|
||||
vol.Optional(ATTR_INCLUDE_LINKED_ZONES): cv.boolean,
|
||||
})
|
||||
|
||||
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""Set up the Sonos platform."""
|
||||
@ -166,6 +180,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
device.set_sleep_timer(service.data[ATTR_SLEEP_TIME])
|
||||
elif service.service == SERVICE_CLEAR_TIMER:
|
||||
device.clear_sleep_timer()
|
||||
elif service.service == SERVICE_UPDATE_ALARM:
|
||||
device.update_alarm(**service.data)
|
||||
|
||||
device.schedule_update_ha_state(True)
|
||||
|
||||
@ -193,6 +209,11 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
DOMAIN, SERVICE_CLEAR_TIMER, service_handle,
|
||||
descriptions.get(SERVICE_CLEAR_TIMER), schema=SONOS_SCHEMA)
|
||||
|
||||
hass.services.register(
|
||||
DOMAIN, SERVICE_UPDATE_ALARM, service_handle,
|
||||
descriptions.get(SERVICE_UPDATE_ALARM),
|
||||
schema=SONOS_UPDATE_ALARM_SCHEMA)
|
||||
|
||||
|
||||
def _parse_timespan(timespan):
|
||||
"""Parse a time-span into number of seconds."""
|
||||
@ -1034,6 +1055,30 @@ class SonosDevice(MediaPlayerDevice):
|
||||
"""Clear the timer on the player."""
|
||||
self._player.set_sleep_timer(None)
|
||||
|
||||
@soco_error
|
||||
@soco_coordinator
|
||||
def update_alarm(self, **data):
|
||||
"""Set the alarm clock on the player."""
|
||||
from soco import alarms
|
||||
a = None
|
||||
for alarm in alarms.get_alarms(self.soco):
|
||||
# pylint: disable=protected-access
|
||||
if alarm._alarm_id == str(data[ATTR_ALARM_ID]):
|
||||
a = alarm
|
||||
if a is None:
|
||||
_LOGGER.warning("did not find alarm with id %s",
|
||||
data[ATTR_ALARM_ID])
|
||||
return
|
||||
if ATTR_TIME in data:
|
||||
a.start_time = data[ATTR_TIME]
|
||||
if ATTR_VOLUME in data:
|
||||
a.volume = int(data[ATTR_VOLUME] * 100)
|
||||
if ATTR_ENABLED in data:
|
||||
a.enabled = data[ATTR_ENABLED]
|
||||
if ATTR_INCLUDE_LINKED_ZONES in data:
|
||||
a.include_linked_zones = data[ATTR_INCLUDE_LINKED_ZONES]
|
||||
a.save()
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return device specific state attributes."""
|
||||
|
@ -1,9 +1,11 @@
|
||||
"""The tests for the Demo Media player platform."""
|
||||
import datetime
|
||||
import socket
|
||||
import unittest
|
||||
import soco.snapshot
|
||||
from unittest import mock
|
||||
import soco
|
||||
from soco import alarms
|
||||
|
||||
from homeassistant.setup import setup_component
|
||||
from homeassistant.components.media_player import sonos, DOMAIN
|
||||
@ -307,6 +309,36 @@ class TestSonosMediaPlayer(unittest.TestCase):
|
||||
device.set_sleep_timer(None)
|
||||
set_sleep_timerMock.assert_called_once_with(None)
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('soco.alarms.Alarm')
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
def test_update_alarm(self, soco_mock, alarm_mock, *args):
|
||||
"""Ensuring soco methods called for sonos_set_sleep_timer service."""
|
||||
sonos.setup_platform(self.hass, {}, fake_add_device, {
|
||||
'host': '192.0.2.1'
|
||||
})
|
||||
device = self.hass.data[sonos.DATA_SONOS][-1]
|
||||
device.hass = self.hass
|
||||
alarm1 = alarms.Alarm(soco_mock)
|
||||
alarm1.configure_mock(_alarm_id="1", start_time=None, enabled=False,
|
||||
include_linked_zones=False, volume=100)
|
||||
with mock.patch('soco.alarms.get_alarms', return_value=[alarm1]):
|
||||
attrs = {
|
||||
'time': datetime.time(12, 00),
|
||||
'enabled': True,
|
||||
'include_linked_zones': True,
|
||||
'volume': 0.30,
|
||||
}
|
||||
device.update_alarm(alarm_id=2)
|
||||
alarm1.save.assert_not_called()
|
||||
device.update_alarm(alarm_id=1, **attrs)
|
||||
self.assertEqual(alarm1.enabled, attrs['enabled'])
|
||||
self.assertEqual(alarm1.start_time, attrs['time'])
|
||||
self.assertEqual(alarm1.include_linked_zones,
|
||||
attrs['include_linked_zones'])
|
||||
self.assertEqual(alarm1.volume, 30)
|
||||
alarm1.save.assert_called_once_with()
|
||||
|
||||
@mock.patch('soco.SoCo', new=SoCoMock)
|
||||
@mock.patch('socket.create_connection', side_effect=socket.error())
|
||||
@mock.patch.object(soco.snapshot.Snapshot, 'snapshot')
|
||||
|
Loading…
x
Reference in New Issue
Block a user