* fix gpmdp

* fix balloobs comments

* move create_connection
This commit is contained in:
Nolan Gilley 2016-08-18 03:08:58 -04:00 committed by Paulus Schoutsen
parent 053a55bc5f
commit 09d531b3b9

View file

@ -6,6 +6,7 @@ https://home-assistant.io/components/media_player.gpmdp/
"""
import logging
import json
import os
import socket
from homeassistant.components.media_player import (
@ -13,24 +14,132 @@ from homeassistant.components.media_player import (
SUPPORT_PAUSE, 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
GPMDP_CONFIG_FILE = 'gpmpd.conf'
_CONFIGURING = {}
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the GPMDP platform."""
def request_configuration(hass, config, url, add_devices_callback):
"""Request configuration steps from the user."""
configurator = get_component('configurator')
if 'gpmdp' in _CONFIGURING:
configurator.notify_errors(
_CONFIGURING['gpmdp'], "Failed to register, please try again.")
return
from websocket import create_connection
websocket = create_connection((url), timeout=1)
websocket.send('{"namespace": "connect", "method": "connect",'
'"arguments": ["Home Assistant"]}')
# pylint: disable=unused-argument
def gpmdp_configuration_callback(callback_data):
"""The actions to do when our configuration callback is called."""
while True:
from websocket import _exceptions
try:
msg = json.loads(websocket.recv())
except _exceptions.WebSocketConnectionClosedException:
continue
if msg['channel'] != 'connect':
continue
if msg['payload'] != "CODE_REQUIRED":
continue
websocket.send('{"namespace": "connect",'
'"method": "connect",'
'"arguments": ["Home Assistant",'
' "' + callback_data.get('pin') + '"]}')
tmpmsg = json.loads(websocket.recv())
if tmpmsg['channel'] == 'time':
_LOGGER.error('Error setting up GPMDP. Please pause'
'the desktop player and try again.')
break
code = tmpmsg['payload']
if code == 'CODE_REQUIRED':
continue
setup_gpmdp(hass, config, code,
add_devices_callback)
_save_config(hass.config.path(GPMDP_CONFIG_FILE),
{"CODE": code})
websocket.send('{"namespace": "connect",'
'"method": "connect",'
'"arguments": ["Home Assistant",'
' "' + code + '"]}')
websocket.close()
_CONFIGURING['gpmdp'] = configurator.request_config(
hass, "GPM Desktop Player", gpmdp_configuration_callback,
description=(
'Enter the pin that is displayed in the '
'Google Play Music Desktop Player.'),
submit_caption="Submit",
fields=[{'id': 'pin', 'name': 'Pin Code', 'type': 'number'}]
)
def setup_gpmdp(hass, config, code, add_devices_callback):
"""Setup gpmdp."""
name = config.get("name", "GPM Desktop Player")
address = config.get("address")
url = "ws://" + address + ":5672"
if address is None:
_LOGGER.error("Missing address in config")
if not code:
request_configuration(hass, config, url, add_devices_callback)
return
if 'gpmdp' in _CONFIGURING:
configurator = get_component('configurator')
configurator.request_done(_CONFIGURING.pop('gpmdp'))
add_devices_callback([GPMDP(name, url, code)])
def _load_config(filename):
"""Load configuration."""
if not os.path.isfile(filename):
return {}
try:
with open(filename, "r") as fdesc:
inp = fdesc.read()
# In case empty file
if not inp:
return {}
return json.loads(inp)
except (IOError, ValueError) as error:
_LOGGER.error("Reading config file %s failed: %s", filename, error)
return None
def _save_config(filename, config):
"""Save configuration."""
try:
with open(filename, "w") as fdesc:
fdesc.write(json.dumps(config, indent=4, sort_keys=True))
except (IOError, TypeError) as error:
_LOGGER.error("Saving config file failed: %s", error)
return False
return True
add_devices([GPMDP(name, address, create_connection)])
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup the GPMDP platform."""
codeconfig = _load_config(hass.config.path(GPMDP_CONFIG_FILE))
if len(codeconfig):
code = codeconfig.get("CODE")
elif discovery_info is not None:
if 'gpmdp' in _CONFIGURING:
return
code = None
else:
code = None
setup_gpmdp(hass, config, code, add_devices_callback)
class GPMDP(MediaPlayerDevice):
@ -38,10 +147,12 @@ class GPMDP(MediaPlayerDevice):
# pylint: disable=too-many-public-methods, abstract-method
# pylint: disable=too-many-instance-attributes
def __init__(self, name, address, create_connection):
def __init__(self, name, url, code):
"""Initialize the media player."""
from websocket import create_connection
self._connection = create_connection
self._address = address
self._url = url
self._authorization_code = code
self._name = name
self._status = STATE_OFF
self._ws = None
@ -54,16 +165,12 @@ class GPMDP(MediaPlayerDevice):
"""Check if the websocket is setup and connected."""
if self._ws is None:
try:
self._ws = self._connection(("ws://" + self._address +
":5672"), timeout=1)
except (socket.timeout, ConnectionRefusedError,
ConnectionResetError):
self._ws = None
elif self._ws.connected is True:
self._ws.close()
try:
self._ws = self._connection(("ws://" + self._address +
":5672"), timeout=1)
self._ws = self._connection((self._url), timeout=1)
msg = json.dumps({'namespace': 'connect',
'method': 'connect',
'arguments': ['Home Assistant',
self._authorization_code]})
self._ws.send(msg)
except (socket.timeout, ConnectionRefusedError,
ConnectionResetError):
self._ws = None
@ -76,19 +183,26 @@ class GPMDP(MediaPlayerDevice):
self._status = STATE_OFF
return
else:
state = websocket.recv()
state = ((json.loads(state))['payload'])
if state is True:
websocket.recv()
websocket.recv()
song = websocket.recv()
song = json.loads(song)
self._title = (song['payload']['title'])
self._artist = (song['payload']['artist'])
self._albumart = (song['payload']['albumArt'])
self._status = STATE_PLAYING
elif state is False:
self._status = STATE_PAUSED
receiving = True
while receiving:
from websocket import _exceptions
try:
msg = json.loads(websocket.recv())
if msg['channel'] == 'lyrics':
receiving = False # end of now playing data
elif msg['channel'] == 'playState':
if msg['payload'] is True:
self._status = STATE_PLAYING
else:
self._status = STATE_PAUSED
elif msg['channel'] == 'track':
self._title = (msg['payload']['title'])
self._artist = (msg['payload']['artist'])
self._albumart = (msg['payload']['albumArt'])
except (_exceptions.WebSocketTimeoutException,
_exceptions.WebSocketProtocolException,
_exceptions.WebSocketPayloadException):
return
@property
def media_content_type(self):
@ -145,7 +259,7 @@ class GPMDP(MediaPlayerDevice):
if websocket is None:
return
websocket.send('{"namespace": "playback", "method": "playPause"}')
self._status = STATE_PAUSED
self._status = STATE_PLAYING
self.update_ha_state()
def media_pause(self):