182 lines
5.5 KiB
Python
182 lines
5.5 KiB
Python
"""WebSocket handlers for group CRUD operations."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
from uuid import uuid4
|
|
|
|
import voluptuous as vol
|
|
from homeassistant.components import websocket_api
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from ..const import (
|
|
DOMAIN,
|
|
MAX_GROUP_TASK_REFS,
|
|
MAX_ID_LENGTH,
|
|
MAX_NAME_LENGTH,
|
|
MAX_TEXT_LENGTH,
|
|
)
|
|
from ..helpers.permissions import require_write
|
|
from . import _get_global_entry
|
|
|
|
|
|
@websocket_api.websocket_command({vol.Required("type"): f"{DOMAIN}/groups"})
|
|
@websocket_api.async_response
|
|
async def ws_get_groups(
|
|
hass: HomeAssistant,
|
|
connection: websocket_api.ActiveConnection,
|
|
msg: dict[str, Any],
|
|
) -> None:
|
|
"""Return all maintenance groups."""
|
|
from ..const import CONF_GROUPS
|
|
|
|
global_entry = _get_global_entry(hass)
|
|
if global_entry is None:
|
|
connection.send_result(msg["id"], {"groups": {}})
|
|
return
|
|
|
|
options = global_entry.options or global_entry.data
|
|
groups = options.get(CONF_GROUPS, {})
|
|
connection.send_result(msg["id"], {"groups": groups})
|
|
|
|
|
|
@websocket_api.websocket_command(
|
|
{
|
|
vol.Required("type"): f"{DOMAIN}/group/create",
|
|
vol.Required("name"): vol.All(str, vol.Length(min=1, max=MAX_NAME_LENGTH)),
|
|
vol.Optional("description", default=""): vol.All(str, vol.Length(max=MAX_TEXT_LENGTH)),
|
|
vol.Optional("task_refs", default=[]): vol.All(
|
|
[
|
|
{
|
|
vol.Required("entry_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
vol.Required("task_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
}
|
|
],
|
|
vol.Length(max=MAX_GROUP_TASK_REFS),
|
|
),
|
|
}
|
|
)
|
|
@require_write
|
|
@websocket_api.async_response
|
|
async def ws_create_group(
|
|
hass: HomeAssistant,
|
|
connection: websocket_api.ActiveConnection,
|
|
msg: dict[str, Any],
|
|
) -> None:
|
|
"""Create a new maintenance group."""
|
|
from ..const import CONF_GROUPS
|
|
|
|
global_entry = _get_global_entry(hass)
|
|
if global_entry is None:
|
|
connection.send_error(msg["id"], "not_found", "Global config not found")
|
|
return
|
|
|
|
name = msg["name"].strip()
|
|
if not name:
|
|
connection.send_error(msg["id"], "invalid_input", "Name must not be empty")
|
|
return
|
|
|
|
group_id = uuid4().hex
|
|
options = dict(global_entry.options or global_entry.data)
|
|
groups = dict(options.get(CONF_GROUPS, {}))
|
|
groups[group_id] = {
|
|
"name": name,
|
|
"description": msg.get("description", ""),
|
|
"task_refs": msg.get("task_refs", []),
|
|
}
|
|
options[CONF_GROUPS] = groups
|
|
hass.config_entries.async_update_entry(global_entry, options=options)
|
|
|
|
connection.send_result(msg["id"], {"group_id": group_id})
|
|
|
|
|
|
@websocket_api.websocket_command(
|
|
{
|
|
vol.Required("type"): f"{DOMAIN}/group/update",
|
|
vol.Required("group_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
vol.Optional("name"): vol.All(str, vol.Length(min=1, max=MAX_NAME_LENGTH)),
|
|
vol.Optional("description"): vol.All(str, vol.Length(max=MAX_TEXT_LENGTH)),
|
|
vol.Optional("task_refs"): vol.All(
|
|
[
|
|
{
|
|
vol.Required("entry_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
vol.Required("task_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
}
|
|
],
|
|
vol.Length(max=MAX_GROUP_TASK_REFS),
|
|
),
|
|
}
|
|
)
|
|
@require_write
|
|
@websocket_api.async_response
|
|
async def ws_update_group(
|
|
hass: HomeAssistant,
|
|
connection: websocket_api.ActiveConnection,
|
|
msg: dict[str, Any],
|
|
) -> None:
|
|
"""Update an existing maintenance group."""
|
|
from ..const import CONF_GROUPS
|
|
|
|
global_entry = _get_global_entry(hass)
|
|
if global_entry is None:
|
|
connection.send_error(msg["id"], "not_found", "Global config not found")
|
|
return
|
|
|
|
options = dict(global_entry.options or global_entry.data)
|
|
groups = dict(options.get(CONF_GROUPS, {}))
|
|
group_id = msg["group_id"]
|
|
|
|
if group_id not in groups:
|
|
connection.send_error(msg["id"], "not_found", "Group not found")
|
|
return
|
|
|
|
group = dict(groups[group_id])
|
|
if "name" in msg:
|
|
group["name"] = msg["name"]
|
|
if "description" in msg:
|
|
group["description"] = msg["description"]
|
|
if "task_refs" in msg:
|
|
group["task_refs"] = msg["task_refs"]
|
|
|
|
groups[group_id] = group
|
|
options[CONF_GROUPS] = groups
|
|
hass.config_entries.async_update_entry(global_entry, options=options)
|
|
|
|
connection.send_result(msg["id"], {"success": True})
|
|
|
|
|
|
@websocket_api.websocket_command(
|
|
{
|
|
vol.Required("type"): f"{DOMAIN}/group/delete",
|
|
vol.Required("group_id"): vol.All(str, vol.Length(max=MAX_ID_LENGTH)),
|
|
}
|
|
)
|
|
@require_write
|
|
@websocket_api.async_response
|
|
async def ws_delete_group(
|
|
hass: HomeAssistant,
|
|
connection: websocket_api.ActiveConnection,
|
|
msg: dict[str, Any],
|
|
) -> None:
|
|
"""Delete a maintenance group."""
|
|
from ..const import CONF_GROUPS
|
|
|
|
global_entry = _get_global_entry(hass)
|
|
if global_entry is None:
|
|
connection.send_error(msg["id"], "not_found", "Global config not found")
|
|
return
|
|
|
|
options = dict(global_entry.options or global_entry.data)
|
|
groups = dict(options.get(CONF_GROUPS, {}))
|
|
group_id = msg["group_id"]
|
|
|
|
if group_id not in groups:
|
|
connection.send_error(msg["id"], "not_found", "Group not found")
|
|
return
|
|
|
|
del groups[group_id]
|
|
options[CONF_GROUPS] = groups
|
|
hass.config_entries.async_update_entry(global_entry, options=options)
|
|
|
|
connection.send_result(msg["id"], {"success": True})
|