mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 13:17:32 +00:00
Add volume and seek control to gpmdp (#2953)
This commit is contained in:
parent
52acb2e6f0
commit
61ef2683c5
@ -11,17 +11,22 @@ import socket
|
|||||||
|
|
||||||
from homeassistant.components.media_player import (
|
from homeassistant.components.media_player import (
|
||||||
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK,
|
MEDIA_TYPE_MUSIC, SUPPORT_NEXT_TRACK, SUPPORT_PREVIOUS_TRACK,
|
||||||
SUPPORT_PAUSE, MediaPlayerDevice)
|
SUPPORT_PAUSE, SUPPORT_VOLUME_SET, SUPPORT_SEEK, MediaPlayerDevice)
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
STATE_PLAYING, STATE_PAUSED, STATE_OFF)
|
STATE_PLAYING, STATE_PAUSED, STATE_OFF)
|
||||||
from homeassistant.loader import get_component
|
from homeassistant.loader import get_component
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
REQUIREMENTS = ['websocket-client==0.37.0']
|
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'
|
GPMDP_CONFIG_FILE = 'gpmpd.conf'
|
||||||
_CONFIGURING = {}
|
_CONFIGURING = {}
|
||||||
|
|
||||||
|
PLAYBACK_DICT = {'0': STATE_PAUSED, # Stopped
|
||||||
|
'1': STATE_PAUSED,
|
||||||
|
'2': STATE_PLAYING}
|
||||||
|
|
||||||
|
|
||||||
def request_configuration(hass, config, url, add_devices_callback):
|
def request_configuration(hass, config, url, add_devices_callback):
|
||||||
"""Request configuration steps from the user."""
|
"""Request configuration steps from the user."""
|
||||||
@ -162,6 +167,7 @@ class GPMDP(MediaPlayerDevice):
|
|||||||
self._albumart = None
|
self._albumart = None
|
||||||
self._seek_position = None
|
self._seek_position = None
|
||||||
self._duration = None
|
self._duration = None
|
||||||
|
self._volume = None
|
||||||
self._request_id = 0
|
self._request_id = 0
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
@ -180,7 +186,7 @@ class GPMDP(MediaPlayerDevice):
|
|||||||
self._ws = None
|
self._ws = None
|
||||||
return self._ws
|
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."""
|
"""Send ws messages to GPMDP and verify request id in response."""
|
||||||
from websocket import _exceptions
|
from websocket import _exceptions
|
||||||
try:
|
try:
|
||||||
@ -188,38 +194,42 @@ class GPMDP(MediaPlayerDevice):
|
|||||||
if websocket is None:
|
if websocket is None:
|
||||||
self._status = STATE_OFF
|
self._status = STATE_OFF
|
||||||
return
|
return
|
||||||
else:
|
self._request_id += 1
|
||||||
self._request_id += 1
|
websocket.send(json.dumps({'namespace': namespace,
|
||||||
websocket.send(json.dumps({'namespace': 'playback',
|
'method': method,
|
||||||
'method': method,
|
'requestID': self._request_id}))
|
||||||
'requestID': self._request_id}))
|
if not with_id:
|
||||||
while True:
|
return
|
||||||
msg = json.loads(websocket.recv())
|
while True:
|
||||||
if 'requestID' in msg:
|
msg = json.loads(websocket.recv())
|
||||||
if msg['requestID'] == self._request_id:
|
if 'requestID' in msg:
|
||||||
return msg
|
if msg['requestID'] == self._request_id:
|
||||||
except (_exceptions.WebSocketTimeoutException,
|
return msg
|
||||||
|
except (ConnectionRefusedError, ConnectionResetError,
|
||||||
|
_exceptions.WebSocketTimeoutException,
|
||||||
_exceptions.WebSocketProtocolException,
|
_exceptions.WebSocketProtocolException,
|
||||||
_exceptions.WebSocketPayloadException):
|
_exceptions.WebSocketPayloadException,
|
||||||
return
|
_exceptions.WebSocketConnectionClosedException):
|
||||||
|
self._ws = None
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
"""Get the latest details from the player."""
|
"""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:
|
if playstate is None:
|
||||||
return
|
return
|
||||||
self._status = STATE_PLAYING if playstate['value'] else STATE_PAUSED
|
self._status = PLAYBACK_DICT[str(playstate['value'])]
|
||||||
time_data = self.send_msg_with_req_id('getCurrentTime')
|
time_data = self.send_gpmdp_msg('playback', 'getCurrentTime')
|
||||||
if time_data is None:
|
if time_data is not None:
|
||||||
return
|
self._seek_position = int(time_data['value'] / 1000)
|
||||||
self._seek_position = int(time_data['value'] / 1000)
|
track_data = self.send_gpmdp_msg('playback', 'getCurrentTrack')
|
||||||
track_data = self.send_msg_with_req_id('getCurrentTrack')
|
if track_data is not None:
|
||||||
if track_data is None:
|
self._title = track_data['value']['title']
|
||||||
return
|
self._artist = track_data['value']['artist']
|
||||||
self._title = track_data['value']['title']
|
self._albumart = track_data['value']['albumArt']
|
||||||
self._artist = track_data['value']['artist']
|
self._duration = int(track_data['value']['duration'] / 1000)
|
||||||
self._albumart = track_data['value']['albumArt']
|
volume_data = self.send_gpmdp_msg('volume', 'getVolume')
|
||||||
self._duration = int(track_data['value']['duration'] / 1000)
|
if volume_data is not None:
|
||||||
|
self._volume = volume_data['value'] / 100
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def media_content_type(self):
|
def media_content_type(self):
|
||||||
@ -256,6 +266,11 @@ class GPMDP(MediaPlayerDevice):
|
|||||||
"""Time in seconds of current song duration."""
|
"""Time in seconds of current song duration."""
|
||||||
return self._duration
|
return self._duration
|
||||||
|
|
||||||
|
@property
|
||||||
|
def volume_level(self):
|
||||||
|
"""Volume level of the media player (0..1)."""
|
||||||
|
return self._volume
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Return the name of the device."""
|
"""Return the name of the device."""
|
||||||
@ -268,32 +283,56 @@ class GPMDP(MediaPlayerDevice):
|
|||||||
|
|
||||||
def media_next_track(self):
|
def media_next_track(self):
|
||||||
"""Send media_next command to media player."""
|
"""Send media_next command to media player."""
|
||||||
websocket = self.get_ws()
|
self.send_gpmdp_msg('playback', 'forward', False)
|
||||||
if websocket is None:
|
|
||||||
return
|
|
||||||
websocket.send('{"namespace": "playback", "method": "forward"}')
|
|
||||||
|
|
||||||
def media_previous_track(self):
|
def media_previous_track(self):
|
||||||
"""Send media_previous command to media player."""
|
"""Send media_previous command to media player."""
|
||||||
websocket = self.get_ws()
|
self.send_gpmdp_msg('playback', 'rewind', False)
|
||||||
if websocket is None:
|
|
||||||
return
|
|
||||||
websocket.send('{"namespace": "playback", "method": "rewind"}')
|
|
||||||
|
|
||||||
def media_play(self):
|
def media_play(self):
|
||||||
"""Send media_play command to media player."""
|
"""Send media_play command to media player."""
|
||||||
websocket = self.get_ws()
|
self.send_gpmdp_msg('playback', 'playPause', False)
|
||||||
if websocket is None:
|
|
||||||
return
|
|
||||||
websocket.send('{"namespace": "playback", "method": "playPause"}')
|
|
||||||
self._status = STATE_PLAYING
|
self._status = STATE_PLAYING
|
||||||
self.update_ha_state()
|
self.update_ha_state()
|
||||||
|
|
||||||
def media_pause(self):
|
def media_pause(self):
|
||||||
"""Send media_pause command to media player."""
|
"""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()
|
websocket = self.get_ws()
|
||||||
if websocket is None:
|
if websocket is None:
|
||||||
return
|
return
|
||||||
websocket.send('{"namespace": "playback", "method": "playPause"}')
|
websocket.send(json.dumps({"namespace": "playback",
|
||||||
self._status = STATE_PAUSED
|
"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()
|
self.update_ha_state()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user