1
0
mirror of https://github.com/home-assistant/core.git synced 2026-07-14 01:54:11 +01:00
Files

108 lines
3.4 KiB
Python

"""WebSocket API for the HTTP integration user config."""
from typing import Any
import voluptuous as vol
from homeassistant.components import websocket_api
from homeassistant.components.homeassistant import (
DOMAIN as HASS_DOMAIN,
SERVICE_HOMEASSISTANT_RESTART,
)
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from .config import HTTP_STORAGE_SCHEMA, async_get_and_load_store
from .const import ATTR_CONFIG
@callback
def async_register_websocket_commands(hass: HomeAssistant) -> None:
"""Register the HTTP config websocket commands."""
websocket_api.async_register_command(hass, websocket_get_config)
websocket_api.async_register_command(hass, websocket_set_config)
websocket_api.async_register_command(hass, websocket_promote_config)
@websocket_api.require_admin
@websocket_api.websocket_command({vol.Required("type"): "http/config"})
@websocket_api.async_response
async def websocket_get_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Return the HTTP configuration.
``stable`` is the confirmed-working config
``pending`` is an unconfirmed config awaiting promotion, or ``None``.
``revert_at`` is when an unconfirmed pending config auto-reverts to
stable, or ``None`` when no revert is scheduled.
"""
store = await async_get_and_load_store(hass)
connection.send_result(
msg["id"],
{
"stable": store.stable,
"pending": store.pending,
"revert_at": store.revert_deadline,
},
)
@websocket_api.require_admin
@websocket_api.websocket_command(
{
vol.Required("type"): "http/config/configure",
vol.Required(ATTR_CONFIG): vol.Any(None, HTTP_STORAGE_SCHEMA),
}
)
@websocket_api.async_response
async def websocket_set_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Store a new pending HTTP configuration and restart to apply it.
Restart whenever the pending slot changes, so the runtime config is
refreshed. The result reports whether a restart was triggered via
``{"restart": bool}``.
"""
store = await async_get_and_load_store(hass)
previous_pending = store.pending
await store.async_set_pending(msg[ATTR_CONFIG])
restart = store.pending != previous_pending
connection.send_result(msg["id"], {"restart": restart})
if restart:
await hass.services.async_call(HASS_DOMAIN, SERVICE_HOMEASSISTANT_RESTART)
@websocket_api.require_admin
@websocket_api.websocket_command({vol.Required("type"): "http/config/promote"})
@websocket_api.async_response
async def websocket_promote_config(
hass: HomeAssistant,
connection: websocket_api.ActiveConnection,
msg: dict[str, Any],
) -> None:
"""Promote the pending HTTP config to stable.
Called by the user after they have verified Home Assistant is
working correctly with the pending config. The stable config is
the one used by recovery mode, so promotion must be explicit.
"""
store = await async_get_and_load_store(hass)
try:
await store.async_promote_pending()
except HomeAssistantError as err:
connection.send_error(
msg["id"],
websocket_api.const.ERR_NOT_ALLOWED,
str(err),
)
return
connection.send_result(msg["id"])