Add volume and seek control to gpmdp (#2953)
This commit is contained in:
parent
52acb2e6f0
commit
61ef2683c5
1 changed files with 82 additions and 43 deletions
|
@ -11,17 +11,22 @@ import socket
|
|||
|
||||
from homeassistant.components.media_player import (
|
||||
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK,
|
||||
SUPPORT_PAUSE, MediaPlayerDevice)
|
||||
SUPPORT_PAUSE, SUPPORT_VOLUME_SET, SUPPORT_SEEK, MediaPlayerDevice)
|
||||
from homeassistant.const import (
|
||||
STATE_PLAYING, STATE_PAUSED, STATE_OFF)
|
||||
from homeassistant.loader import get_component
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
REQUIREMENTS = ['websocket-client==0.37.0']
|
||||
SUPPORT_GPMDP = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK
|
||||
SUPPORT_GPMDP = SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | SUPPORT_NEXT_TRACK | \
|
||||
SUPPORT_SEEK | SUPPORT_VOLUME_SET
|
||||
GPMDP_CONFIG_FILE = 'gpmpd.conf'
|
||||
_CONFIGURING = {}
|
||||
|
||||
PLAYBACK_DICT = {'0': STATE_PAUSED, # Stopped
|
||||
'1': STATE_PAUSED,
|
||||
'2': STATE_PLAYING}
|
||||
|
||||
|
||||
def request_configuration(hass, config, url, add_devices_callback):
|
||||
"""Request configuration steps from the user."""
|
||||
|
@ -162,6 +167,7 @@ class GPMDP(MediaPlayerDevice):
|
|||
self._albumart = None
|
||||
self._seek_position = None
|
||||
self._duration = None
|
||||
self._volume = None
|
||||
self._request_id = 0
|
||||
self.update()
|
||||
|
||||
|
@ -180,7 +186,7 @@ class GPMDP(MediaPlayerDevice):
|
|||
self._ws = None
|
||||
return self._ws
|
||||
|
||||
def send_msg_with_req_id(self, method):
|
||||
def send_gpmdp_msg(self, namespace, method, with_id=True):
|
||||
"""Send ws messages to GPMDP and verify request id in response."""
|
||||
from websocket import _exceptions
|
||||
try:
|
||||
|
@ -188,38 +194,42 @@ class GPMDP(MediaPlayerDevice):
|
|||
if websocket is None:
|
||||
self._status = STATE_OFF
|
||||
return
|
||||
else:
|
||||
self._request_id += 1
|
||||
websocket.send(json.dumps({'namespace': 'playback',
|
||||
'method': method,
|
||||
'requestID': self._request_id}))
|
||||
while True:
|
||||
msg = json.loads(websocket.recv())
|
||||
if 'requestID' in msg:
|
||||
if msg['requestID'] == self._request_id:
|
||||
return msg
|
||||
except (_exceptions.WebSocketTimeoutException,
|
||||
self._request_id += 1
|
||||
websocket.send(json.dumps({'namespace': namespace,
|
||||
'method': method,
|
||||
'requestID': self._request_id}))
|
||||
if not with_id:
|
||||
return
|
||||
while True:
|
||||
msg = json.loads(websocket.recv())
|
||||
if 'requestID' in msg:
|
||||
if msg['requestID'] == self._request_id:
|
||||
return msg
|
||||
except (ConnectionRefusedError, ConnectionResetError,
|
||||
_exceptions.WebSocketTimeoutException,
|
||||
_exceptions.WebSocketProtocolException,
|
||||
_exceptions.WebSocketPayloadException):
|
||||
return
|
||||
_exceptions.WebSocketPayloadException,
|
||||
_exceptions.WebSocketConnectionClosedException):
|
||||
self._ws = None
|
||||
|
||||
def update(self):
|
||||
"""Get the latest details from the player."""
|
||||
playstate = self.send_msg_with_req_id('isPlaying')
|
||||
playstate = self.send_gpmdp_msg('playback', 'getPlaybackState')
|
||||
if playstate is None:
|
||||
return
|
||||
self._status = STATE_PLAYING if playstate['value'] else STATE_PAUSED
|
||||
time_data = self.send_msg_with_req_id('getCurrentTime')
|
||||
if time_data is None:
|
||||
return
|
||||
self._seek_position = int(time_data['value'] / 1000)
|
||||
track_data = self.send_msg_with_req_id('getCurrentTrack')
|
||||
if track_data is None:
|
||||
return
|
||||
self._title = track_data['value']['title']
|
||||
self._artist = track_data['value']['artist']
|
||||
self._albumart = track_data['value']['albumArt']
|
||||
self._duration = int(track_data['value']['duration'] / 1000)
|
||||
self._status = PLAYBACK_DICT[str(playstate['value'])]
|
||||
time_data = self.send_gpmdp_msg('playback', 'getCurrentTime')
|
||||
if time_data is not None:
|
||||
self._seek_position = int(time_data['value'] / 1000)
|
||||
track_data = self.send_gpmdp_msg('playback', 'getCurrentTrack')
|
||||
if track_data is not None:
|
||||
self._title = track_data['value']['title']
|
||||
self._artist = track_data['value']['artist']
|
||||
self._albumart = track_data['value']['albumArt']
|
||||
self._duration = int(track_data['value']['duration'] / 1000)
|
||||
volume_data = self.send_gpmdp_msg('volume', 'getVolume')
|
||||
if volume_data is not None:
|
||||
self._volume = volume_data['value'] / 100
|
||||
|
||||
@property
|
||||
def media_content_type(self):
|
||||
|
@ -256,6 +266,11 @@ class GPMDP(MediaPlayerDevice):
|
|||
"""Time in seconds of current song duration."""
|
||||
return self._duration
|
||||
|
||||
@property
|
||||
def volume_level(self):
|
||||
"""Volume level of the media player (0..1)."""
|
||||
return self._volume
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the device."""
|
||||
|
@ -268,32 +283,56 @@ class GPMDP(MediaPlayerDevice):
|
|||
|
||||
def media_next_track(self):
|
||||
"""Send media_next command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "playback", "method": "forward"}')
|
||||
self.send_gpmdp_msg('playback', 'forward', False)
|
||||
|
||||
def media_previous_track(self):
|
||||
"""Send media_previous command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "playback", "method": "rewind"}')
|
||||
self.send_gpmdp_msg('playback', 'rewind', False)
|
||||
|
||||
def media_play(self):
|
||||
"""Send media_play command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "playback", "method": "playPause"}')
|
||||
self.send_gpmdp_msg('playback', 'playPause', False)
|
||||
self._status = STATE_PLAYING
|
||||
self.update_ha_state()
|
||||
|
||||
def media_pause(self):
|
||||
"""Send media_pause command to media player."""
|
||||
self.send_gpmdp_msg('playback', 'playPause', False)
|
||||
self._status = STATE_PAUSED
|
||||
self.update_ha_state()
|
||||
|
||||
def media_seek(self, position):
|
||||
"""Send media_seek command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "playback", "method": "playPause"}')
|
||||
self._status = STATE_PAUSED
|
||||
websocket.send(json.dumps({"namespace": "playback",
|
||||
"method": "setCurrentTime",
|
||||
"arguments": [position*1000]}))
|
||||
self.update_ha_state()
|
||||
|
||||
def volume_up(self):
|
||||
"""Send volume_up command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "volume", "method": "increaseVolume"}')
|
||||
self.update_ha_state()
|
||||
|
||||
def volume_down(self):
|
||||
"""Send volume_down command to media player."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send('{"namespace": "volume", "method": "decreaseVolume"}')
|
||||
self.update_ha_state()
|
||||
|
||||
def set_volume_level(self, volume):
|
||||
"""Set volume on media player, range(0..1)."""
|
||||
websocket = self.get_ws()
|
||||
if websocket is None:
|
||||
return
|
||||
websocket.send(json.dumps({"namespace": "volume",
|
||||
"method": "setVolume",
|
||||
"arguments": [volume*100]}))
|
||||
self.update_ha_state()
|
||||
|
|
Loading…
Add table
Reference in a new issue