wallpanell/custom_components/wall_panel/config_flow.py
2026-03-25 13:48:26 +03:00

135 lines
6.4 KiB
Python
Executable File

"""Config flow for Wall Panel."""
from __future__ import annotations
import json
import secrets
from typing import Any
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_NAME
from homeassistant.helpers.selector import TextSelector, TextSelectorConfig, TextSelectorType
from .const import (
CONF_CONFIG,
CONF_FRONTEND_URL_PATH,
CONF_PANEL_URL,
CONF_REQUIRE_ADMIN,
CONF_SIDEBAR_ICON,
CONF_SIDEBAR_TITLE,
CONF_SYNC_TOKEN,
DEFAULT_FRONTEND_URL_PATH,
DEFAULT_PANEL_URL,
DEFAULT_SIDEBAR_ICON,
DEFAULT_SIDEBAR_TITLE,
DOMAIN,
)
from .helpers import config_to_json, normalize_config, parse_config_json
def _schema(defaults: dict[str, Any]) -> vol.Schema:
return vol.Schema({
vol.Optional(CONF_NAME, default=defaults.get(CONF_NAME, "Wall Panel")): str,
vol.Optional(CONF_PANEL_URL, default=defaults.get(CONF_PANEL_URL, DEFAULT_PANEL_URL)): str,
vol.Optional(CONF_SIDEBAR_TITLE, default=defaults.get(CONF_SIDEBAR_TITLE, DEFAULT_SIDEBAR_TITLE)): str,
vol.Optional(CONF_SIDEBAR_ICON, default=defaults.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON)): str,
vol.Optional(CONF_FRONTEND_URL_PATH, default=defaults.get(CONF_FRONTEND_URL_PATH, DEFAULT_FRONTEND_URL_PATH)): str,
vol.Optional(CONF_REQUIRE_ADMIN, default=bool(defaults.get(CONF_REQUIRE_ADMIN, False))): bool,
vol.Optional(CONF_SYNC_TOKEN, default=defaults.get(CONF_SYNC_TOKEN, secrets.token_urlsafe(24))): str,
vol.Optional(
CONF_CONFIG,
default=defaults.get(CONF_CONFIG, config_to_json(normalize_config({}))),
): TextSelector(TextSelectorConfig(multiline=True, type=TextSelectorType.TEXT)),
})
class WallPanelConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Wall Panel."""
VERSION = 1
async def async_step_user(self, user_input: dict[str, Any] | None = None):
errors: dict[str, str] = {}
if self._async_current_entries():
return self.async_abort(reason="single_instance_allowed")
if user_input is not None:
try:
config = parse_config_json(user_input[CONF_CONFIG])
except (json.JSONDecodeError, ValueError):
errors[CONF_CONFIG] = "invalid_json"
else:
data = {
CONF_NAME: user_input.get(CONF_NAME, "Wall Panel"),
CONF_PANEL_URL: str(user_input.get(CONF_PANEL_URL, "") or ""),
CONF_SIDEBAR_TITLE: str(user_input.get(CONF_SIDEBAR_TITLE, DEFAULT_SIDEBAR_TITLE) or DEFAULT_SIDEBAR_TITLE),
CONF_SIDEBAR_ICON: str(user_input.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON) or DEFAULT_SIDEBAR_ICON),
CONF_FRONTEND_URL_PATH: str(user_input.get(CONF_FRONTEND_URL_PATH, DEFAULT_FRONTEND_URL_PATH) or DEFAULT_FRONTEND_URL_PATH),
CONF_REQUIRE_ADMIN: bool(user_input.get(CONF_REQUIRE_ADMIN, False)),
CONF_SYNC_TOKEN: str(user_input.get(CONF_SYNC_TOKEN, "") or ""),
CONF_CONFIG: config,
}
await self.async_set_unique_id(DOMAIN)
self._abort_if_unique_id_configured()
return self.async_create_entry(title=data[CONF_SIDEBAR_TITLE], data={}, options=data)
defaults = {
CONF_NAME: "Wall Panel",
CONF_PANEL_URL: DEFAULT_PANEL_URL,
CONF_SIDEBAR_TITLE: DEFAULT_SIDEBAR_TITLE,
CONF_SIDEBAR_ICON: DEFAULT_SIDEBAR_ICON,
CONF_FRONTEND_URL_PATH: DEFAULT_FRONTEND_URL_PATH,
CONF_REQUIRE_ADMIN: False,
CONF_SYNC_TOKEN: secrets.token_urlsafe(24),
CONF_CONFIG: config_to_json(normalize_config({})),
}
return self.async_show_form(step_id="user", data_schema=_schema(defaults), errors=errors)
async def async_step_import(self, user_input: dict[str, Any]):
return await self.async_step_user(user_input)
class WallPanelOptionsFlow(config_entries.OptionsFlow):
"""Handle options for Wall Panel."""
def __init__(self, config_entry):
self.config_entry = config_entry
async def async_step_init(self, user_input: dict[str, Any] | None = None):
errors: dict[str, str] = {}
if user_input is not None:
try:
config = parse_config_json(user_input[CONF_CONFIG])
except (json.JSONDecodeError, ValueError):
errors[CONF_CONFIG] = "invalid_json"
else:
data = dict(self.config_entry.options)
data.update({
CONF_NAME: user_input.get(CONF_NAME, data.get(CONF_NAME, "Wall Panel")),
CONF_PANEL_URL: str(user_input.get(CONF_PANEL_URL, "") or ""),
CONF_SIDEBAR_TITLE: str(user_input.get(CONF_SIDEBAR_TITLE, DEFAULT_SIDEBAR_TITLE) or DEFAULT_SIDEBAR_TITLE),
CONF_SIDEBAR_ICON: str(user_input.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON) or DEFAULT_SIDEBAR_ICON),
CONF_FRONTEND_URL_PATH: str(user_input.get(CONF_FRONTEND_URL_PATH, DEFAULT_FRONTEND_URL_PATH) or DEFAULT_FRONTEND_URL_PATH),
CONF_REQUIRE_ADMIN: bool(user_input.get(CONF_REQUIRE_ADMIN, False)),
CONF_SYNC_TOKEN: str(user_input.get(CONF_SYNC_TOKEN, "") or ""),
CONF_CONFIG: config,
})
return self.async_create_entry(title="", data=data)
defaults = {
CONF_NAME: self.config_entry.options.get(CONF_NAME, "Wall Panel"),
CONF_PANEL_URL: self.config_entry.options.get(CONF_PANEL_URL, DEFAULT_PANEL_URL),
CONF_SIDEBAR_TITLE: self.config_entry.options.get(CONF_SIDEBAR_TITLE, DEFAULT_SIDEBAR_TITLE),
CONF_SIDEBAR_ICON: self.config_entry.options.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON),
CONF_FRONTEND_URL_PATH: self.config_entry.options.get(CONF_FRONTEND_URL_PATH, DEFAULT_FRONTEND_URL_PATH),
CONF_REQUIRE_ADMIN: self.config_entry.options.get(CONF_REQUIRE_ADMIN, False),
CONF_SYNC_TOKEN: self.config_entry.options.get(CONF_SYNC_TOKEN, secrets.token_urlsafe(24)),
CONF_CONFIG: config_to_json(normalize_config(self.config_entry.options.get(CONF_CONFIG, {}))),
}
return self.async_show_form(step_id="init", data_schema=_schema(defaults), errors=errors)
def async_get_options_flow(config_entry):
return WallPanelOptionsFlow(config_entry)