Use Wake-on-LAN to turn on LG webOS TV (#4808)

This commit is contained in:
Albert Lee 2016-12-17 01:24:35 -06:00 committed by Paulus Schoutsen
parent 6c524594c1
commit 831cad4220
2 changed files with 54 additions and 28 deletions

View file

@ -1,5 +1,5 @@
""" """
Support for interface with an LG WebOS TV. Support for interface with an LG webOS Smart TV.
For more details about this platform, please refer to the documentation at For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/media_player.webostv/ https://home-assistant.io/components/media_player.webostv/
@ -12,30 +12,34 @@ import voluptuous as vol
import homeassistant.util as util import homeassistant.util as util
from homeassistant.components.media_player import ( from homeassistant.components.media_player import (
SUPPORT_TURN_ON, SUPPORT_TURN_OFF,
SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK, SUPPORT_NEXT_TRACK, SUPPORT_PAUSE, SUPPORT_PREVIOUS_TRACK,
SUPPORT_TURN_OFF, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP, SUPPORT_VOLUME_MUTE, SUPPORT_VOLUME_STEP,
SUPPORT_SELECT_SOURCE, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL, SUPPORT_SELECT_SOURCE, SUPPORT_PLAY_MEDIA, MEDIA_TYPE_CHANNEL,
MediaPlayerDevice, PLATFORM_SCHEMA) MediaPlayerDevice, PLATFORM_SCHEMA)
from homeassistant.const import ( from homeassistant.const import (
CONF_HOST, CONF_CUSTOMIZE, STATE_OFF, STATE_PLAYING, STATE_PAUSED, CONF_HOST, CONF_MAC, CONF_CUSTOMIZE, STATE_OFF,
STATE_PLAYING, STATE_PAUSED,
STATE_UNKNOWN, CONF_NAME) STATE_UNKNOWN, CONF_NAME)
from homeassistant.loader import get_component from homeassistant.loader import get_component
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
REQUIREMENTS = ['https://github.com/TheRealLink/pylgtv' REQUIREMENTS = ['https://github.com/TheRealLink/pylgtv'
'/archive/v0.1.2.zip' '/archive/v0.1.2.zip'
'#pylgtv==0.1.2'] '#pylgtv==0.1.2',
'websockets==3.2',
'wakeonlan==0.2.2']
_CONFIGURING = {} _CONFIGURING = {} # type: Dict[str, str]
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
CONF_SOURCES = 'sources' CONF_SOURCES = 'sources'
DEFAULT_NAME = 'LG WebOS Smart TV' DEFAULT_NAME = 'LG webOS Smart TV'
SUPPORT_WEBOSTV = SUPPORT_PAUSE | SUPPORT_VOLUME_STEP | \ SUPPORT_WEBOSTV = SUPPORT_TURN_OFF | \
SUPPORT_VOLUME_MUTE | SUPPORT_PREVIOUS_TRACK | \ SUPPORT_NEXT_TRACK | SUPPORT_PAUSE | SUPPORT_PREVIOUS_TRACK | \
SUPPORT_NEXT_TRACK | SUPPORT_TURN_OFF | \ SUPPORT_VOLUME_MUTE | SUPPORT_VOLUME_STEP | \
SUPPORT_SELECT_SOURCE | SUPPORT_PLAY_MEDIA SUPPORT_SELECT_SOURCE | SUPPORT_PLAY_MEDIA
MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
@ -49,6 +53,7 @@ CUSTOMIZE_SCHEMA = vol.Schema({
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_HOST): cv.string, vol.Optional(CONF_HOST): cv.string,
vol.Optional(CONF_MAC): cv.string,
vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA, vol.Optional(CONF_CUSTOMIZE, default={}): CUSTOMIZE_SCHEMA,
}) })
@ -69,15 +74,17 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
if host in _CONFIGURING: if host in _CONFIGURING:
return return
mac = config.get(CONF_MAC)
name = config.get(CONF_NAME) name = config.get(CONF_NAME)
customize = config.get(CONF_CUSTOMIZE) customize = config.get(CONF_CUSTOMIZE)
setup_tv(host, name, customize, hass, add_devices) setup_tv(host, mac, name, customize, hass, add_devices)
def setup_tv(host, name, customize, hass, add_devices): def setup_tv(host, mac, name, customize, hass, add_devices):
"""Setup a phue bridge based on host parameter.""" """Setup a LG WebOS TV based on host parameter."""
from pylgtv import WebOsClient from pylgtv import WebOsClient
from pylgtv import PyLGTVPairException from pylgtv import PyLGTVPairException
from websockets.exceptions import ConnectionClosed
client = WebOsClient(host) client = WebOsClient(host)
@ -88,15 +95,16 @@ def setup_tv(host, name, customize, hass, add_devices):
client.register() client.register()
except PyLGTVPairException: except PyLGTVPairException:
_LOGGER.warning( _LOGGER.warning(
"Connected to LG WebOS TV %s but not paired", host) "Connected to LG webOS TV %s but not paired", host)
return return
except OSError: except (OSError, ConnectionClosed):
_LOGGER.error("Unable to connect to host %s", host) _LOGGER.error("Unable to connect to host %s", host)
return return
else: else:
# Not registered, request configuration. # Not registered, request configuration.
_LOGGER.warning("LG WebOS TV %s needs to be paired", host) _LOGGER.warning("LG webOS TV %s needs to be paired", host)
request_configuration(host, name, customize, hass, add_devices) request_configuration(
host, mac, name, customize, hass, add_devices)
return return
# If we came here and configuring this host, mark as done. # If we came here and configuring this host, mark as done.
@ -105,10 +113,11 @@ def setup_tv(host, name, customize, hass, add_devices):
configurator = get_component('configurator') configurator = get_component('configurator')
configurator.request_done(request_id) configurator.request_done(request_id)
add_devices([LgWebOSDevice(host, name, customize)]) add_devices([LgWebOSDevice(host, mac, name, customize)], True)
def request_configuration(host, name, customize, hass, add_devices): def request_configuration(
host, mac, name, customize, hass, add_devices):
"""Request configuration steps from the user.""" """Request configuration steps from the user."""
configurator = get_component('configurator') configurator = get_component('configurator')
@ -121,10 +130,10 @@ def request_configuration(host, name, customize, hass, add_devices):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def lgtv_configuration_callback(data): def lgtv_configuration_callback(data):
"""The actions to do when our configuration callback is called.""" """The actions to do when our configuration callback is called."""
setup_tv(host, name, customize, hass, add_devices) setup_tv(host, mac, name, customize, hass, add_devices)
_CONFIGURING[host] = configurator.request_config( _CONFIGURING[host] = configurator.request_config(
hass, 'LG WebOS TV', lgtv_configuration_callback, hass, name, lgtv_configuration_callback,
description='Click start and accept the pairing request on your TV.', description='Click start and accept the pairing request on your TV.',
description_image='/static/images/config_webos.png', description_image='/static/images/config_webos.png',
submit_caption='Start pairing request' submit_caption='Start pairing request'
@ -134,10 +143,13 @@ def request_configuration(host, name, customize, hass, add_devices):
class LgWebOSDevice(MediaPlayerDevice): class LgWebOSDevice(MediaPlayerDevice):
"""Representation of a LG WebOS TV.""" """Representation of a LG WebOS TV."""
def __init__(self, host, name, customize): def __init__(self, host, mac, name, customize):
"""Initialize the webos device.""" """Initialize the webos device."""
from pylgtv import WebOsClient from pylgtv import WebOsClient
from wakeonlan import wol
self._client = WebOsClient(host) self._client = WebOsClient(host)
self._wol = wol
self._mac = mac
self._customize = customize self._customize = customize
self._name = name self._name = name
@ -148,15 +160,14 @@ class LgWebOSDevice(MediaPlayerDevice):
self._volume = 0 self._volume = 0
self._current_source = None self._current_source = None
self._current_source_id = None self._current_source_id = None
self._source_list = None
self._state = STATE_UNKNOWN self._state = STATE_UNKNOWN
self._app_list = None self._source_list = {}
self._app_list = {}
self.update()
@util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
def update(self): def update(self):
"""Retrieve the latest data.""" """Retrieve the latest data."""
from websockets.exceptions import ConnectionClosed
try: try:
self._state = STATE_PLAYING self._state = STATE_PLAYING
self._muted = self._client.get_muted() self._muted = self._client.get_muted()
@ -183,7 +194,7 @@ class LgWebOSDevice(MediaPlayerDevice):
app = self._app_list[source['appId']] app = self._app_list[source['appId']]
self._source_list[app['title']] = app self._source_list[app['title']] = app
except OSError: except (OSError, ConnectionClosed):
self._state = STATE_OFF self._state = STATE_OFF
@property @property
@ -231,12 +242,23 @@ class LgWebOSDevice(MediaPlayerDevice):
@property @property
def supported_media_commands(self): def supported_media_commands(self):
"""Flag of media commands that are supported.""" """Flag of media commands that are supported."""
if self._mac:
return SUPPORT_WEBOSTV | SUPPORT_TURN_ON
return SUPPORT_WEBOSTV return SUPPORT_WEBOSTV
def turn_off(self): def turn_off(self):
"""Turn off media player.""" """Turn off media player."""
from websockets.exceptions import ConnectionClosed
self._state = STATE_OFF self._state = STATE_OFF
try:
self._client.power_off() self._client.power_off()
except (OSError, ConnectionClosed):
pass
def turn_on(self):
"""Turn on the media player."""
if self._mac:
self._wol.send_magic_packet(self._mac)
def volume_up(self): def volume_up(self):
"""Volume up the media player.""" """Volume up the media player."""

View file

@ -605,12 +605,16 @@ vsure==0.11.1
vtjp==0.1.11 vtjp==0.1.11
# homeassistant.components.media_player.panasonic_viera # homeassistant.components.media_player.panasonic_viera
# homeassistant.components.media_player.webostv
# homeassistant.components.switch.wake_on_lan # homeassistant.components.switch.wake_on_lan
wakeonlan==0.2.2 wakeonlan==0.2.2
# homeassistant.components.media_player.gpmdp # homeassistant.components.media_player.gpmdp
websocket-client==0.37.0 websocket-client==0.37.0
# homeassistant.components.media_player.webostv
websockets==3.2
# homeassistant.components.zigbee # homeassistant.components.zigbee
xbee-helper==0.0.7 xbee-helper==0.0.7