mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 01:38:02 +00:00
Add generic command/button functionality to webostv (#30379)
* add generic command/button functionality to webostv * update codeowners
This commit is contained in:
parent
9064058a03
commit
c1936f6fe4
@ -365,6 +365,7 @@ homeassistant/components/waqi/* @andrey-git
|
||||
homeassistant/components/watson_tts/* @rutkai
|
||||
homeassistant/components/weather/* @fabaff
|
||||
homeassistant/components/weblink/* @home-assistant/core
|
||||
homeassistant/components/webostv/* @bendavid
|
||||
homeassistant/components/websocket_api/* @home-assistant/core
|
||||
homeassistant/components/wemo/* @sqldiablo
|
||||
homeassistant/components/withings/* @vangorra
|
||||
|
@ -7,6 +7,7 @@ import voluptuous as vol
|
||||
from websockets.exceptions import ConnectionClosed
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_CUSTOMIZE,
|
||||
CONF_HOST,
|
||||
CONF_ICON,
|
||||
@ -14,6 +15,7 @@ from homeassistant.const import (
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||
|
||||
DOMAIN = "webostv"
|
||||
|
||||
@ -23,6 +25,12 @@ CONF_STANDBY_CONNECTION = "standby_connection"
|
||||
DEFAULT_NAME = "LG webOS Smart TV"
|
||||
WEBOSTV_CONFIG_FILE = "webostv.conf"
|
||||
|
||||
SERVICE_BUTTON = "button"
|
||||
ATTR_BUTTON = "button"
|
||||
|
||||
SERVICE_COMMAND = "command"
|
||||
ATTR_COMMAND = "command"
|
||||
|
||||
CUSTOMIZE_SCHEMA = vol.Schema(
|
||||
{vol.Optional(CONF_SOURCES, default=[]): vol.All(cv.ensure_list, [cv.string])}
|
||||
)
|
||||
@ -50,6 +58,17 @@ CONFIG_SCHEMA = vol.Schema(
|
||||
extra=vol.ALLOW_EXTRA,
|
||||
)
|
||||
|
||||
CALL_SCHEMA = vol.Schema({vol.Required(ATTR_ENTITY_ID): cv.comp_entity_ids})
|
||||
|
||||
BUTTON_SCHEMA = CALL_SCHEMA.extend({vol.Required(ATTR_BUTTON): cv.string})
|
||||
|
||||
COMMAND_SCHEMA = CALL_SCHEMA.extend({vol.Required(ATTR_COMMAND): cv.string})
|
||||
|
||||
SERVICE_TO_METHOD = {
|
||||
SERVICE_BUTTON: {"method": "async_button", "schema": BUTTON_SCHEMA},
|
||||
SERVICE_COMMAND: {"method": "async_command", "schema": COMMAND_SCHEMA},
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -57,6 +76,18 @@ async def async_setup(hass, config):
|
||||
"""Set up the LG WebOS TV platform."""
|
||||
hass.data[DOMAIN] = {}
|
||||
|
||||
async def async_service_handler(service):
|
||||
method = SERVICE_TO_METHOD.get(service.service)
|
||||
data = service.data.copy()
|
||||
data["method"] = method["method"]
|
||||
async_dispatcher_send(hass, DOMAIN, data)
|
||||
|
||||
for service in SERVICE_TO_METHOD:
|
||||
schema = SERVICE_TO_METHOD[service]["schema"]
|
||||
hass.services.async_register(
|
||||
DOMAIN, service, async_service_handler, schema=schema
|
||||
)
|
||||
|
||||
tasks = [async_setup_tv(hass, config, conf) for conf in config[DOMAIN]]
|
||||
if tasks:
|
||||
await asyncio.gather(*tasks)
|
||||
|
@ -6,5 +6,5 @@
|
||||
"aiopylgtv==0.2.4"
|
||||
],
|
||||
"dependencies": ["configurator"],
|
||||
"codeowners": []
|
||||
"codeowners": ["@bendavid"]
|
||||
}
|
||||
|
@ -24,13 +24,16 @@ from homeassistant.components.media_player.const import (
|
||||
SUPPORT_VOLUME_STEP,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_CUSTOMIZE,
|
||||
CONF_HOST,
|
||||
CONF_NAME,
|
||||
ENTITY_MATCH_ALL,
|
||||
STATE_OFF,
|
||||
STATE_PAUSED,
|
||||
STATE_PLAYING,
|
||||
)
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.script import Script
|
||||
|
||||
from . import CONF_ON_ACTION, CONF_SOURCES, DOMAIN
|
||||
@ -131,7 +134,9 @@ class LgWebOSMediaPlayerEntity(MediaPlayerDevice):
|
||||
self._last_icon = None
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Connect and subscribe to state updates."""
|
||||
"""Connect and subscribe to dispatcher signals and state updates."""
|
||||
async_dispatcher_connect(self.hass, DOMAIN, self.async_signal_handler)
|
||||
|
||||
await self._client.register_state_update_callback(
|
||||
self.async_handle_state_update
|
||||
)
|
||||
@ -144,6 +149,17 @@ class LgWebOSMediaPlayerEntity(MediaPlayerDevice):
|
||||
"""Call disconnect on removal."""
|
||||
self._client.unregister_state_update_callback(self.async_handle_state_update)
|
||||
|
||||
async def async_signal_handler(self, data):
|
||||
"""Handle domain-specific signal by calling appropriate method."""
|
||||
entity_ids = data[ATTR_ENTITY_ID]
|
||||
if entity_ids == ENTITY_MATCH_ALL or self.entity_id in entity_ids:
|
||||
params = {
|
||||
key: value
|
||||
for key, value in data.items()
|
||||
if key not in ["entity_id", "method"]
|
||||
}
|
||||
await getattr(self, data["method"])(**params)
|
||||
|
||||
async def async_handle_state_update(self):
|
||||
"""Update state from WebOsClient."""
|
||||
self._current_source_id = self._client.current_appId
|
||||
@ -406,3 +422,13 @@ class LgWebOSMediaPlayerEntity(MediaPlayerDevice):
|
||||
await self._client.channel_down()
|
||||
else:
|
||||
await self._client.rewind()
|
||||
|
||||
@cmd
|
||||
async def async_button(self, button):
|
||||
"""Send a button press."""
|
||||
await self._client.button(button)
|
||||
|
||||
@cmd
|
||||
async def async_command(self, command):
|
||||
"""Send a command."""
|
||||
await self._client.request(command)
|
||||
|
26
homeassistant/components/webostv/services.yaml
Normal file
26
homeassistant/components/webostv/services.yaml
Normal file
@ -0,0 +1,26 @@
|
||||
# Describes the format for available webostv services
|
||||
|
||||
button:
|
||||
description: 'Send a button press command.'
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name(s) of the webostv entities where to run the API method.
|
||||
example: 'media_player.living_room_tv'
|
||||
button:
|
||||
description: Name of the button to press. Known possible values are
|
||||
LEFT, RIGHT, DOWN, UP, HOME, BACK, ENTER, DASH, INFO, ASTERISK, CC, EXIT,
|
||||
MUTE, RED, GREEN, BLUE, VOLUMEUP, VOLUMEDOWN, CHANNELUP, CHANNELDOWN,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
|
||||
example: 'LEFT'
|
||||
|
||||
command:
|
||||
description: 'Send a command.'
|
||||
fields:
|
||||
entity_id:
|
||||
description: Name(s) of the webostv entities where to run the API method.
|
||||
example: 'media_player.living_room_tv'
|
||||
command:
|
||||
description: Endpoint of the command. Known valid endpoints are listed in
|
||||
https://github.com/TheRealLink/pylgtv/blob/master/pylgtv/endpoints.py
|
||||
example: 'media.controls/rewind'
|
||||
|
@ -9,7 +9,13 @@ from homeassistant.components.media_player.const import (
|
||||
ATTR_MEDIA_VOLUME_MUTED,
|
||||
SERVICE_SELECT_SOURCE,
|
||||
)
|
||||
from homeassistant.components.webostv import DOMAIN
|
||||
from homeassistant.components.webostv import (
|
||||
ATTR_BUTTON,
|
||||
ATTR_COMMAND,
|
||||
DOMAIN,
|
||||
SERVICE_BUTTON,
|
||||
SERVICE_COMMAND,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_HOST,
|
||||
@ -75,3 +81,34 @@ async def test_select_source_with_empty_source_list(hass, client):
|
||||
assert hass.states.is_state(ENTITY_ID, "playing")
|
||||
client.launch_app.assert_not_called()
|
||||
client.set_input.assert_not_called()
|
||||
|
||||
|
||||
async def test_button(hass, client):
|
||||
"""Test generic button functionality."""
|
||||
|
||||
await setup_webostv(hass)
|
||||
|
||||
data = {
|
||||
ATTR_ENTITY_ID: ENTITY_ID,
|
||||
ATTR_BUTTON: "test",
|
||||
}
|
||||
await hass.services.async_call(DOMAIN, SERVICE_BUTTON, data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
client.button.assert_called_once()
|
||||
client.button.assert_called_with("test")
|
||||
|
||||
|
||||
async def test_command(hass, client):
|
||||
"""Test generic button functionality."""
|
||||
|
||||
await setup_webostv(hass)
|
||||
|
||||
data = {
|
||||
ATTR_ENTITY_ID: ENTITY_ID,
|
||||
ATTR_COMMAND: "test",
|
||||
}
|
||||
await hass.services.async_call(DOMAIN, SERVICE_COMMAND, data)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
client.request.assert_called_with("test")
|
||||
|
Loading…
x
Reference in New Issue
Block a user