Kodi specific service to call Kodi API methods (#7603)
* Kodi specific services to call Kodi API methods - new service: `kodi_execute_addon` to run a Kodi Addon with optional parameters. Results of the Kodi API call, if any, are redirected in a Home Assistant event: `kodi_execute_addon_result`. - new service: `kodi_run_method` to run a Kodi JSONRPC API method with optional parameters. Results of the Kodi API call are redirected in a Home Assistant event: `kodi_run_method_result`. - Add descriptions in services.yaml. - Add `timeout` parameter to yaml config (needed to make slow queries to the JSONRPC API, default timeout is set to 5s). - Trigger events with the results of the Kodi API calls, with: ``` event_data = { 'result': api_call_results, 'result_ok': boolean, 'input': api_call_parameters, 'entity_id': 'media_player.kodi'} ``` * no need to clean OrderedDicts; no need for the `kodi_execute_addon` service * no need for the `kodi_execute_addon` service * unused import * naming changes
This commit is contained in:
parent
0e9728d94a
commit
f7d25396a4
2 changed files with 51 additions and 4 deletions
homeassistant/components/media_player
|
@ -24,7 +24,7 @@ from homeassistant.components.media_player import (
|
|||
from homeassistant.const import (
|
||||
STATE_IDLE, STATE_OFF, STATE_PAUSED, STATE_PLAYING, CONF_HOST, CONF_NAME,
|
||||
CONF_PORT, CONF_SSL, CONF_PROXY_SSL, CONF_USERNAME, CONF_PASSWORD,
|
||||
EVENT_HOMEASSISTANT_STOP)
|
||||
CONF_TIMEOUT, EVENT_HOMEASSISTANT_STOP)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
@ -34,6 +34,8 @@ REQUIREMENTS = ['jsonrpc-async==0.6', 'jsonrpc-websocket==0.5']
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
EVENT_KODI_CALL_METHOD_RESULT = 'kodi_call_method_result'
|
||||
|
||||
CONF_TCP_PORT = 'tcp_port'
|
||||
CONF_TURN_OFF_ACTION = 'turn_off_action'
|
||||
CONF_ENABLE_WEBSOCKET = 'enable_websocket'
|
||||
|
@ -74,6 +76,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
vol.Optional(CONF_TCP_PORT, default=DEFAULT_TCP_PORT): cv.port,
|
||||
vol.Optional(CONF_PROXY_SSL, default=DEFAULT_PROXY_SSL): cv.boolean,
|
||||
vol.Optional(CONF_TURN_OFF_ACTION, default=None): vol.In(TURN_OFF_ACTION),
|
||||
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
||||
vol.Inclusive(CONF_USERNAME, 'auth'): cv.string,
|
||||
vol.Inclusive(CONF_PASSWORD, 'auth'): cv.string,
|
||||
vol.Optional(CONF_ENABLE_WEBSOCKET, default=DEFAULT_ENABLE_WEBSOCKET):
|
||||
|
@ -81,6 +84,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|||
})
|
||||
|
||||
SERVICE_ADD_MEDIA = 'kodi_add_to_playlist'
|
||||
SERVICE_CALL_METHOD = 'kodi_call_method'
|
||||
|
||||
DATA_KODI = 'kodi'
|
||||
|
||||
|
@ -88,6 +92,7 @@ ATTR_MEDIA_TYPE = 'media_type'
|
|||
ATTR_MEDIA_NAME = 'media_name'
|
||||
ATTR_MEDIA_ARTIST_NAME = 'artist_name'
|
||||
ATTR_MEDIA_ID = 'media_id'
|
||||
ATTR_METHOD = 'method'
|
||||
|
||||
MEDIA_PLAYER_ADD_MEDIA_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
||||
vol.Required(ATTR_MEDIA_TYPE): cv.string,
|
||||
|
@ -95,11 +100,17 @@ MEDIA_PLAYER_ADD_MEDIA_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
|||
vol.Optional(ATTR_MEDIA_NAME): cv.string,
|
||||
vol.Optional(ATTR_MEDIA_ARTIST_NAME): cv.string,
|
||||
})
|
||||
MEDIA_PLAYER_CALL_METHOD_SCHEMA = MEDIA_PLAYER_SCHEMA.extend({
|
||||
vol.Required(ATTR_METHOD): cv.string,
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
SERVICE_TO_METHOD = {
|
||||
SERVICE_ADD_MEDIA: {
|
||||
'method': 'async_add_media_to_playlist',
|
||||
'schema': MEDIA_PLAYER_ADD_MEDIA_SCHEMA},
|
||||
SERVICE_CALL_METHOD: {
|
||||
'method': 'async_call_method',
|
||||
'schema': MEDIA_PLAYER_CALL_METHOD_SCHEMA},
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,7 +138,8 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
|||
host=host, port=port, tcp_port=tcp_port, encryption=encryption,
|
||||
username=config.get(CONF_USERNAME),
|
||||
password=config.get(CONF_PASSWORD),
|
||||
turn_off_action=config.get(CONF_TURN_OFF_ACTION), websocket=websocket)
|
||||
turn_off_action=config.get(CONF_TURN_OFF_ACTION),
|
||||
timeout=config.get(CONF_TIMEOUT), websocket=websocket)
|
||||
|
||||
hass.data[DATA_KODI].append(entity)
|
||||
async_add_devices([entity], update_before_add=True)
|
||||
|
@ -199,7 +211,7 @@ class KodiDevice(MediaPlayerDevice):
|
|||
|
||||
def __init__(self, hass, name, host, port, tcp_port, encryption=False,
|
||||
username=None, password=None, turn_off_action=None,
|
||||
websocket=True):
|
||||
timeout=DEFAULT_TIMEOUT, websocket=True):
|
||||
"""Initialize the Kodi device."""
|
||||
import jsonrpc_async
|
||||
import jsonrpc_websocket
|
||||
|
@ -207,7 +219,7 @@ class KodiDevice(MediaPlayerDevice):
|
|||
self._name = name
|
||||
|
||||
kwargs = {
|
||||
'timeout': DEFAULT_TIMEOUT,
|
||||
'timeout': timeout,
|
||||
'session': async_get_clientsession(hass),
|
||||
}
|
||||
|
||||
|
@ -678,6 +690,30 @@ class KodiDevice(MediaPlayerDevice):
|
|||
yield from self.server.Player.SetShuffle(
|
||||
{"playerid": self._players[0]['playerid'], "shuffle": shuffle})
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_call_method(self, method, **kwargs):
|
||||
"""Run Kodi JSONRPC API method with params."""
|
||||
import jsonrpc_base
|
||||
_LOGGER.debug('Run API method "%s", kwargs=%s', method, kwargs)
|
||||
result_ok = False
|
||||
try:
|
||||
result = yield from getattr(self.server, method)(**kwargs)
|
||||
result_ok = True
|
||||
except jsonrpc_base.jsonrpc.ProtocolError as exc:
|
||||
result = exc.args[2]['error']
|
||||
_LOGGER.error('Run API method %s.%s(%s) error: %s',
|
||||
self.entity_id, method, kwargs, result)
|
||||
|
||||
if isinstance(result, dict):
|
||||
event_data = {'entity_id': self.entity_id,
|
||||
'result': result,
|
||||
'result_ok': result_ok,
|
||||
'input': {'method': method, 'params': kwargs}}
|
||||
_LOGGER.debug('EVENT kodi_call_method_result: %s', event_data)
|
||||
self.hass.bus.async_fire(EVENT_KODI_CALL_METHOD_RESULT,
|
||||
event_data=event_data)
|
||||
return result
|
||||
|
||||
@asyncio.coroutine
|
||||
def async_add_media_to_playlist(
|
||||
self, media_type, media_id=None, media_name='ALL', artist_name=''):
|
||||
|
|
|
@ -289,3 +289,14 @@ kodi_add_to_playlist:
|
|||
artist_name:
|
||||
description: Optional artist name for filtering media.
|
||||
example: 'AC/DC'
|
||||
|
||||
kodi_call_method:
|
||||
description: 'Call a Kodi JSONRPC API method with optional parameters. Results of the Kodi API call will be redirected in a Home Assistant event: `kodi_call_method_result`.'
|
||||
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name(s) of the Kodi entities where to run the API method.
|
||||
example: 'media_player.living_room_kodi'
|
||||
method:
|
||||
description: Name of the Kodi JSONRPC API method to be called.
|
||||
example: 'VideoLibrary.GetRecentlyAddedEpisodes'
|
||||
|
|
Loading…
Add table
Reference in a new issue