Handle missing mpd capabilities (#15945)

* Handle missing mpd capabilities

It is possible to configure mpd without volume or playlist support.
Gracefully degrade when either of these features appears to be missing.

Resolves: #14459, #15927

* Use longer name for exception

* Only return support flags post-connection

* Small consistency fixes to mpd.py for review.
This commit is contained in:
Ed Marshall 2018-08-18 00:54:23 -07:00 committed by Martin Hjelmare
parent ec2e94425e
commit e782e2c0f3

View File

@ -32,9 +32,8 @@ DEFAULT_PORT = 6600
PLAYLIST_UPDATE_INTERVAL = timedelta(seconds=120)
SUPPORT_MPD = SUPPORT_PAUSE | SUPPORT_VOLUME_SET | SUPPORT_VOLUME_STEP | \
SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | SUPPORT_VOLUME_MUTE | \
SUPPORT_PLAY_MEDIA | SUPPORT_PLAY | SUPPORT_SELECT_SOURCE | \
SUPPORT_MPD = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | \
SUPPORT_NEXT_TRACK | SUPPORT_PLAY_MEDIA | SUPPORT_PLAY | \
SUPPORT_CLEAR_PLAYLIST | SUPPORT_SHUFFLE_SET | SUPPORT_SEEK | \
SUPPORT_STOP | SUPPORT_TURN_OFF | SUPPORT_TURN_ON
@ -72,7 +71,7 @@ class MpdDevice(MediaPlayerDevice):
self._status = None
self._currentsong = None
self._playlists = []
self._playlists = None
self._currentplaylist = None
self._is_connected = False
self._muted = False
@ -202,12 +201,24 @@ class MpdDevice(MediaPlayerDevice):
@property
def volume_level(self):
"""Return the volume level."""
return int(self._status['volume'])/100
if 'volume' in self._status:
return int(self._status['volume'])/100
return None
@property
def supported_features(self):
"""Flag media player features that are supported."""
return SUPPORT_MPD
if self._status is None:
return None
supported = SUPPORT_MPD
if 'volume' in self._status:
supported |= \
SUPPORT_VOLUME_SET | SUPPORT_VOLUME_STEP | SUPPORT_VOLUME_MUTE
if self._playlists is not None:
supported |= SUPPORT_SELECT_SOURCE
return supported
@property
def source(self):
@ -226,27 +237,36 @@ class MpdDevice(MediaPlayerDevice):
@Throttle(PLAYLIST_UPDATE_INTERVAL)
def _update_playlists(self, **kwargs):
"""Update available MPD playlists."""
self._playlists = []
for playlist_data in self._client.listplaylists():
self._playlists.append(playlist_data['playlist'])
import mpd
try:
self._playlists = []
for playlist_data in self._client.listplaylists():
self._playlists.append(playlist_data['playlist'])
except mpd.CommandError as error:
self._playlists = None
_LOGGER.warning("Playlists could not be updated: %s:", error)
def set_volume_level(self, volume):
"""Set volume of media player."""
self._client.setvol(int(volume * 100))
if 'volume' in self._status:
self._client.setvol(int(volume * 100))
def volume_up(self):
"""Service to send the MPD the command for volume up."""
current_volume = int(self._status['volume'])
if 'volume' in self._status:
current_volume = int(self._status['volume'])
if current_volume <= 100:
self._client.setvol(current_volume + 5)
if current_volume <= 100:
self._client.setvol(current_volume + 5)
def volume_down(self):
"""Service to send the MPD the command for volume down."""
current_volume = int(self._status['volume'])
if 'volume' in self._status:
current_volume = int(self._status['volume'])
if current_volume >= 0:
self._client.setvol(current_volume - 5)
if current_volume >= 0:
self._client.setvol(current_volume - 5)
def media_play(self):
"""Service to send the MPD the command for play/pause."""
@ -270,12 +290,13 @@ class MpdDevice(MediaPlayerDevice):
def mute_volume(self, mute):
"""Mute. Emulated with set_volume_level."""
if mute is True:
self._muted_volume = self.volume_level
self.set_volume_level(0)
elif mute is False:
self.set_volume_level(self._muted_volume)
self._muted = mute
if 'volume' in self._status:
if mute:
self._muted_volume = self.volume_level
self.set_volume_level(0)
else:
self.set_volume_level(self._muted_volume)
self._muted = mute
def play_media(self, media_type, media_id, **kwargs):
"""Send the media player the command for playing a playlist."""