Add 2 media_player services and 1 custom service to Squeezebox platform (#10969)
* Add 2 media_player services and 1 custom service to Squeezebox platform * Fix pylint error * Remove apostrophe in example * Split method into command and parameters * Fix Lint error
This commit is contained in:
parent
cba55402b1
commit
92014bf1d1
2 changed files with 103 additions and 3 deletions
|
@ -307,3 +307,16 @@ kodi_call_method:
|
|||
method:
|
||||
description: Name of the Kodi JSONRPC API method to be called.
|
||||
example: 'VideoLibrary.GetRecentlyAddedEpisodes'
|
||||
|
||||
squeezebox_call_method:
|
||||
description: 'Call a Squeezebox JSON/RPC API method.'
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name(s) of the Squeexebox entities where to run the API method.
|
||||
example: 'media_player.squeezebox_radio'
|
||||
command:
|
||||
description: Name of the Squeezebox command.
|
||||
example: 'playlist'
|
||||
parameters:
|
||||
description: Optional array of parameters to be appended to the command. See 'Command Line Interface' official help page from Logitech for details.
|
||||
example: '["loadtracks", "track.titlesearch=highway to hell"]'
|
||||
|
|
|
@ -8,19 +8,22 @@ import logging
|
|||
import asyncio
|
||||
import urllib.parse
|
||||
import json
|
||||
import os
|
||||
import aiohttp
|
||||
import async_timeout
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
from homeassistant.components.media_player import (
|
||||
ATTR_MEDIA_ENQUEUE, SUPPORT_PLAY_MEDIA,
|
||||
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, PLATFORM_SCHEMA,
|
||||
SUPPORT_PREVIOUS_TRACK, SUPPORT_SEEK, SUPPORT_TURN_OFF, SUPPORT_TURN_ON,
|
||||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_PLAY, MediaPlayerDevice)
|
||||
SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_SET, SUPPORT_PLAY, MediaPlayerDevice,
|
||||
MEDIA_PLAYER_SCHEMA, DOMAIN, SUPPORT_SHUFFLE_SET, SUPPORT_CLEAR_PLAYLIST)
|
||||
from homeassistant.const import (
|
||||
CONF_HOST, CONF_PASSWORD, CONF_USERNAME, STATE_IDLE, STATE_OFF,
|
||||
STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, CONF_PORT)
|
||||
STATE_PAUSED, STATE_PLAYING, STATE_UNKNOWN, CONF_PORT, ATTR_COMMAND)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
@ -33,7 +36,7 @@ TIMEOUT = 10
|
|||
SUPPORT_SQUEEZEBOX = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | \
|
||||
SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | \
|
||||
SUPPORT_SEEK | SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_PLAY_MEDIA | \
|
||||
SUPPORT_PLAY
|
||||
SUPPORT_PLAY | SUPPORT_SHUFFLE_SET | SUPPORT_CLEAR_PLAYLIST
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
||||
vol.Required(CONF_HOST): cv.string,
|
||||
|
@ -42,12 +45,33 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
vol.Optional(CONF_USERNAME): cv.string,
|
||||
})
|
||||
|
||||
SERVICE_CALL_METHOD = 'squeezebox_call_method'
|
||||
|
||||
DATA_SQUEEZEBOX = 'squeexebox'
|
||||
|
||||
ATTR_PARAMETERS = 'parameters'
|
||||
|
||||
SQUEEZEBOX_CALL_METHOD_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
||||
vol.Required(ATTR_COMMAND): cv.string,
|
||||
vol.Optional(ATTR_PARAMETERS):
|
||||
vol.All(cv.ensure_list, vol.Length(min=1), [cv.string]),
|
||||
})
|
||||
|
||||
SERVICE_TO_METHOD = {
|
||||
SERVICE_CALL_METHOD: {
|
||||
'method': 'async_call_method',
|
||||
'schema': SQUEEZEBOX_CALL_METHOD_SCHEMA},
|
||||
}
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Set up the squeezebox platform."""
|
||||
import socket
|
||||
|
||||
if DATA_SQUEEZEBOX not in hass.data:
|
||||
hass.data[DATA_SQUEEZEBOX] = []
|
||||
|
||||
username = config.get(CONF_USERNAME)
|
||||
password = config.get(CONF_PASSWORD)
|
||||
|
||||
|
@ -74,8 +98,44 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
lms = LogitechMediaServer(hass, host, port, username, password)
|
||||
|
||||
players = yield from lms.create_players()
|
||||
|
||||
hass.data[DATA_SQUEEZEBOX].extend(players)
|
||||
async_add_devices(players)
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_service_handler(service):
|
||||
"""Map services to methods on MediaPlayerDevice."""
|
||||
method = SERVICE_TO_METHOD.get(service.service)
|
||||
if not method:
|
||||
return
|
||||
|
||||
params = {key: value for key, value in service.data.items()
|
||||
if key != 'entity_id'}
|
||||
entity_ids = service.data.get('entity_id')
|
||||
if entity_ids:
|
||||
target_players = [player for player in hass.data[DATA_SQUEEZEBOX]
|
||||
if player.entity_id in entity_ids]
|
||||
else:
|
||||
target_players = hass.data[DATA_SQUEEZEBOX]
|
||||
|
||||
update_tasks = []
|
||||
for player in target_players:
|
||||
yield from getattr(player, method['method'])(**params)
|
||||
update_tasks.append(player.async_update_ha_state(True))
|
||||
|
||||
if update_tasks:
|
||||
yield from asyncio.wait(update_tasks, loop=hass.loop)
|
||||
|
||||
descriptions = yield from hass.async_add_job(
|
||||
load_yaml_config_file, os.path.join(
|
||||
os.path.dirname(__file__), 'services.yaml'))
|
||||
|
||||
for service in SERVICE_TO_METHOD:
|
||||
schema = SERVICE_TO_METHOD[service]['schema']
|
||||
hass.services.async_register(
|
||||
DOMAIN, service, async_service_handler,
|
||||
description=descriptions.get(service), schema=schema)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
@ -305,6 +365,12 @@ class SqueezeBoxDevice(MediaPlayerDevice):
|
|||
if 'album' in self._status:
|
||||
return self._status['album']
|
||||
|
||||
@property
|
||||
def shuffle(self):
|
||||
"""Boolean if shuffle is enabled."""
|
||||
if 'playlist_shuffle' in self._status:
|
||||
return self._status['playlist_shuffle'] == 1
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Flag media player features that are supported."""
|
||||
|
@ -415,3 +481,24 @@ class SqueezeBoxDevice(MediaPlayerDevice):
|
|||
def _add_uri_to_playlist(self, media_id):
|
||||
"""Add a items to the existing playlist."""
|
||||
return self.async_query('playlist', 'add', media_id)
|
||||
|
||||
def async_set_shuffle(self, shuffle):
|
||||
"""Enable/disable shuffle mode."""
|
||||
return self.async_query('playlist', 'shuffle', int(shuffle))
|
||||
|
||||
def async_clear_playlist(self):
|
||||
"""Send the media player the command for clear playlist."""
|
||||
return self.async_query('playlist', 'clear')
|
||||
|
||||
def async_call_method(self, command, parameters=None):
|
||||
"""
|
||||
Call Squeezebox JSON/RPC method.
|
||||
|
||||
Escaped optional parameters are added to the command to form the list
|
||||
of positional parameters (p0, p1..., pN) passed to JSON/RPC server.
|
||||
"""
|
||||
all_params = [command]
|
||||
if parameters:
|
||||
for parameter in parameters:
|
||||
all_params.append(urllib.parse.quote(parameter, safe=':='))
|
||||
return self.async_query(*all_params)
|
||||
|
|
Loading…
Add table
Reference in a new issue