Add media_player.sonos_group_players service (#2087)
Sonos platform supports a `party mode` feature that groups all available players into a single group, of which the calling player will be the coordinator.pull/2052/merge
parent
6b724f7da4
commit
7eeb623b8f
|
@ -145,3 +145,11 @@ select_source:
|
||||||
source:
|
source:
|
||||||
description: Name of the source to switch to. Platform dependent.
|
description: Name of the source to switch to. Platform dependent.
|
||||||
example: 'video1'
|
example: 'video1'
|
||||||
|
|
||||||
|
sonos_group_players:
|
||||||
|
description: Send Sonos media player the command for grouping all players into one (party mode).
|
||||||
|
|
||||||
|
fields:
|
||||||
|
entity_id:
|
||||||
|
description: Name(s) of entites that will coordinate the grouping. Platform dependent.
|
||||||
|
example: 'media_player.living_room_sonos'
|
||||||
|
|
|
@ -7,13 +7,15 @@ https://home-assistant.io/components/media_player.sonos/
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import socket
|
import socket
|
||||||
|
from os import path
|
||||||
|
|
||||||
from homeassistant.components.media_player import (
|
from homeassistant.components.media_player import (
|
||||||
ATTR_MEDIA_ENQUEUE, MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE,
|
ATTR_MEDIA_ENQUEUE, DOMAIN, MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK,
|
||||||
SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
|
SUPPORT_PAUSE, SUPPORT_PLAY_MEDIA, SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK,
|
||||||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, MediaPlayerDevice)
|
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, MediaPlayerDevice)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, STATE_OFF)
|
STATE_IDLE, STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, STATE_OFF)
|
||||||
|
from homeassistant.config import load_yaml_config_file
|
||||||
|
|
||||||
REQUIREMENTS = ['SoCo==0.11.1']
|
REQUIREMENTS = ['SoCo==0.11.1']
|
||||||
|
|
||||||
|
@ -31,6 +33,8 @@ SUPPORT_SONOS = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_MUTE |\
|
||||||
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA |\
|
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA |\
|
||||||
SUPPORT_SEEK
|
SUPPORT_SEEK
|
||||||
|
|
||||||
|
SERVICE_GROUP_PLAYERS = 'sonos_group_players'
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
|
@ -62,9 +66,31 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||||
_LOGGER.warning('No Sonos speakers found.')
|
_LOGGER.warning('No Sonos speakers found.')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
add_devices(SonosDevice(hass, p) for p in players)
|
devices = [SonosDevice(hass, p) for p in players]
|
||||||
|
add_devices(devices)
|
||||||
_LOGGER.info('Added %s Sonos speakers', len(players))
|
_LOGGER.info('Added %s Sonos speakers', len(players))
|
||||||
|
|
||||||
|
def group_players_service(service):
|
||||||
|
"""Group media players, use player as coordinator."""
|
||||||
|
entity_id = service.data.get('entity_id')
|
||||||
|
|
||||||
|
if entity_id:
|
||||||
|
_devices = [device for device in devices
|
||||||
|
if device.entity_id == entity_id]
|
||||||
|
else:
|
||||||
|
_devices = devices
|
||||||
|
|
||||||
|
for device in _devices:
|
||||||
|
device.group_players()
|
||||||
|
device.update_ha_state(True)
|
||||||
|
|
||||||
|
descriptions = load_yaml_config_file(
|
||||||
|
path.join(path.dirname(__file__), 'services.yaml'))
|
||||||
|
|
||||||
|
hass.services.register(DOMAIN, SERVICE_GROUP_PLAYERS,
|
||||||
|
group_players_service,
|
||||||
|
descriptions.get(SERVICE_GROUP_PLAYERS))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +139,7 @@ class SonosDevice(MediaPlayerDevice):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def should_poll(self):
|
def should_poll(self):
|
||||||
"""No polling needed."""
|
"""Polling needed."""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_sonos(self, now):
|
def update_sonos(self, now):
|
||||||
|
@ -284,6 +310,11 @@ class SonosDevice(MediaPlayerDevice):
|
||||||
else:
|
else:
|
||||||
self._player.play_uri(media_id)
|
self._player.play_uri(media_id)
|
||||||
|
|
||||||
|
@only_if_coordinator
|
||||||
|
def group_players(self):
|
||||||
|
"""Group all players under this coordinator."""
|
||||||
|
self._player.partymode()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self):
|
def available(self):
|
||||||
"""Return True if player is reachable, False otherwise."""
|
"""Return True if player is reachable, False otherwise."""
|
||||||
|
|
Loading…
Reference in New Issue