1 """Websocekt API handlers for the hassio integration."""
4 from numbers
import Number
8 import voluptuous
as vol
16 async_dispatcher_connect,
17 async_dispatcher_send,
20 from .
import HassioAPIError
25 ATTR_SESSION_DATA_USER_ID,
29 EVENT_SUPERVISOR_EVENT,
36 from .handler
import HassIO
38 SCHEMA_WEBSOCKET_EVENT = vol.Schema(
39 {vol.Required(ATTR_WS_EVENT): cv.string},
40 extra=vol.ALLOW_EXTRA,
45 WS_NO_ADMIN_ENDPOINTS = re.compile(
47 r"|/ingress/(session|validate_session)"
48 r"|/addons/[^/]+/info"
53 _LOGGER: logging.Logger = logging.getLogger(__package__)
58 """Set up the websocket API."""
59 websocket_api.async_register_command(hass, websocket_supervisor_event)
60 websocket_api.async_register_command(hass, websocket_supervisor_api)
61 websocket_api.async_register_command(hass, websocket_subscribe)
65 @websocket_api.require_admin
66 @websocket_api.websocket_command({vol.Required(WS_TYPE): WS_TYPE_SUBSCRIBE})
68 hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
70 """Subscribe to supervisor events."""
73 def forward_messages(data: dict[str, str]) ->
None:
74 """Forward events to websocket."""
75 connection.send_message(websocket_api.event_message(msg[WS_ID], data))
78 hass, EVENT_SUPERVISOR_EVENT, forward_messages
80 connection.send_message(websocket_api.result_message(msg[WS_ID]))
84 @websocket_api.websocket_command(
{
vol.Required(WS_TYPE): WS_TYPE_EVENT,
85 vol.Required(ATTR_DATA): SCHEMA_WEBSOCKET_EVENT,
89 hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
91 """Publish events from the Supervisor."""
92 connection.send_result(msg[WS_ID])
96 @websocket_api.websocket_command(
{
vol.Required(WS_TYPE): WS_TYPE_API,
97 vol.Required(ATTR_ENDPOINT): cv.string,
98 vol.Required(ATTR_METHOD): cv.string,
99 vol.Optional(ATTR_DATA): dict,
100 vol.Optional(ATTR_TIMEOUT): vol.Any(Number,
None),
103 @websocket_api.async_response
105 hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
107 """Websocket handler to call Supervisor API."""
108 if not connection.user.is_admin
and not WS_NO_ADMIN_ENDPOINTS.match(
112 supervisor: HassIO = hass.data[DOMAIN]
114 command = msg[ATTR_ENDPOINT]
115 payload = msg.get(ATTR_DATA, {})
117 if command ==
"/ingress/session":
120 payload[ATTR_SESSION_DATA_USER_ID] = connection.user.id
123 result = await supervisor.send_command(
125 method=msg[ATTR_METHOD],
126 timeout=msg.get(ATTR_TIMEOUT, 10),
128 source=
"core.websocket_api",
130 except HassioAPIError
as err:
131 _LOGGER.error(
"Failed to to call %s - %s", msg[ATTR_ENDPOINT], err)
132 connection.send_error(
133 msg[WS_ID], code=websocket_api.ERR_UNKNOWN_ERROR, message=
str(err)
136 connection.send_result(msg[WS_ID], result.get(ATTR_DATA, {}))
137
None websocket_supervisor_api(HomeAssistant hass, ActiveConnection connection, dict[str, Any] msg)
None websocket_subscribe(HomeAssistant hass, ActiveConnection connection, dict[str, Any] msg)
None websocket_supervisor_event(HomeAssistant hass, ActiveConnection connection, dict[str, Any] msg)
None async_load_websocket_api(HomeAssistant hass)
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
None async_dispatcher_send(HomeAssistant hass, str signal, *Any args)