1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00
ha-core/homeassistant/components/lovelace/websocket.py
2020-03-31 11:43:21 +02:00

116 lines
3.3 KiB
Python

"""Websocket API for Lovelace."""
from functools import wraps
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.core import callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv
from .const import CONF_URL_PATH, DOMAIN, ConfigNotFound
def _handle_errors(func):
"""Handle error with WebSocket calls."""
@wraps(func)
async def send_with_error_handling(hass, connection, msg):
url_path = msg.get(CONF_URL_PATH)
config = hass.data[DOMAIN]["dashboards"].get(url_path)
if config is None:
connection.send_error(
msg["id"], "config_not_found", f"Unknown config specified: {url_path}"
)
return
error = None
try:
result = await func(hass, connection, msg, config)
except ConfigNotFound:
error = "config_not_found", "No config found."
except HomeAssistantError as err:
error = "error", str(err)
if error is not None:
connection.send_error(msg["id"], *error)
return
if msg is not None:
await connection.send_big_result(msg["id"], result)
else:
connection.send_result(msg["id"], result)
return send_with_error_handling
@websocket_api.async_response
@websocket_api.websocket_command({"type": "lovelace/resources"})
async def websocket_lovelace_resources(hass, connection, msg):
"""Send Lovelace UI resources over WebSocket configuration."""
resources = hass.data[DOMAIN]["resources"]
if not resources.loaded:
await resources.async_load()
resources.loaded = True
connection.send_result(msg["id"], resources.async_items())
@websocket_api.async_response
@websocket_api.websocket_command(
{
"type": "lovelace/config",
vol.Optional("force", default=False): bool,
vol.Optional(CONF_URL_PATH): vol.Any(None, cv.string),
}
)
@_handle_errors
async def websocket_lovelace_config(hass, connection, msg, config):
"""Send Lovelace UI config over WebSocket configuration."""
return await config.async_load(msg["force"])
@websocket_api.require_admin
@websocket_api.async_response
@websocket_api.websocket_command(
{
"type": "lovelace/config/save",
"config": vol.Any(str, dict),
vol.Optional(CONF_URL_PATH): vol.Any(None, cv.string),
}
)
@_handle_errors
async def websocket_lovelace_save_config(hass, connection, msg, config):
"""Save Lovelace UI configuration."""
await config.async_save(msg["config"])
@websocket_api.require_admin
@websocket_api.async_response
@websocket_api.websocket_command(
{
"type": "lovelace/config/delete",
vol.Optional(CONF_URL_PATH): vol.Any(None, cv.string),
}
)
@_handle_errors
async def websocket_lovelace_delete_config(hass, connection, msg, config):
"""Delete Lovelace UI configuration."""
await config.async_delete()
@websocket_api.websocket_command({"type": "lovelace/dashboards/list"})
@callback
def websocket_lovelace_dashboards(hass, connection, msg):
"""Delete Lovelace UI configuration."""
connection.send_result(
msg["id"],
[
dashboard.config
for dashboard in hass.data[DOMAIN]["dashboards"].values()
if dashboard.config
],
)