From 2d337fd29aa80207afafb54a07c5a92920cba7f7 Mon Sep 17 00:00:00 2001 From: Adam Mills Date: Wed, 8 Mar 2017 15:54:51 -0500 Subject: [PATCH] Catch exceptions on kodi commands --- homeassistant/components/media_player/kodi.py | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/media_player/kodi.py b/homeassistant/components/media_player/kodi.py index 071b5068884..a1e658a8122 100644 --- a/homeassistant/components/media_player/kodi.py +++ b/homeassistant/components/media_player/kodi.py @@ -86,6 +86,25 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None): async_add_devices([entity], update_before_add=True) +def cmd(func): + """Decorator to catch command exceptions.""" + @asyncio.coroutine + def wrapper(obj, *args, **kwargs): + """Wrapper for all command methods.""" + import jsonrpc_base + try: + yield from func(obj, *args, **kwargs) + except jsonrpc_base.jsonrpc.TransportError as exc: + # If Kodi is off, we expect calls to fail. + if obj.state == STATE_OFF: + log_function = _LOGGER.info + else: + log_function = _LOGGER.error + log_function("Error calling %s on entity %s: %r", + func.__name__, obj.entity_id, exc) + return wrapper + + class KodiDevice(MediaPlayerDevice): """Representation of a XBMC/Kodi device.""" @@ -371,6 +390,7 @@ class KodiDevice(MediaPlayerDevice): return supported_features + @cmd @asyncio.coroutine def async_turn_off(self): """Execute turn_off_action to turn off media player.""" @@ -387,18 +407,21 @@ class KodiDevice(MediaPlayerDevice): else: _LOGGER.warning('turn_off requested but turn_off_action is none') + @cmd @asyncio.coroutine def async_volume_up(self): """Volume up the media player.""" assert ( yield from self.server.Input.ExecuteAction('volumeup')) == 'OK' + @cmd @asyncio.coroutine def async_volume_down(self): """Volume down the media player.""" assert ( yield from self.server.Input.ExecuteAction('volumedown')) == 'OK' + @cmd def async_set_volume_level(self, volume): """Set volume level, range 0..1. @@ -406,6 +429,7 @@ class KodiDevice(MediaPlayerDevice): """ return self.server.Application.SetVolume(int(volume * 100)) + @cmd def async_mute_volume(self, mute): """Mute (true) or unmute (false) media player. @@ -418,10 +442,11 @@ class KodiDevice(MediaPlayerDevice): """Helper method for play/pause/toggle.""" players = yield from self._get_players() - if len(players) != 0: + if players is not None and len(players) != 0: yield from self.server.Player.PlayPause( players[0]['playerid'], state) + @cmd def async_media_play_pause(self): """Pause media on media player. @@ -429,6 +454,7 @@ class KodiDevice(MediaPlayerDevice): """ return self.async_set_play_state('toggle') + @cmd def async_media_play(self): """Play media. @@ -436,6 +462,7 @@ class KodiDevice(MediaPlayerDevice): """ return self.async_set_play_state(True) + @cmd def async_media_pause(self): """Pause the media player. @@ -443,6 +470,7 @@ class KodiDevice(MediaPlayerDevice): """ return self.async_set_play_state(False) + @cmd @asyncio.coroutine def async_media_stop(self): """Stop the media player.""" @@ -465,6 +493,7 @@ class KodiDevice(MediaPlayerDevice): yield from self.server.Player.GoTo( players[0]['playerid'], direction) + @cmd def async_media_next_track(self): """Send next track command. @@ -472,6 +501,7 @@ class KodiDevice(MediaPlayerDevice): """ return self._goto('next') + @cmd def async_media_previous_track(self): """Send next track command. @@ -479,6 +509,7 @@ class KodiDevice(MediaPlayerDevice): """ return self._goto('previous') + @cmd @asyncio.coroutine def async_media_seek(self, position): """Send seek command.""" @@ -500,6 +531,7 @@ class KodiDevice(MediaPlayerDevice): if len(players) != 0: yield from self.server.Player.Seek(players[0]['playerid'], time) + @cmd def async_play_media(self, media_type, media_id, **kwargs): """Send the play_media command to the media player.