135 lines
6.4 KiB
Python
Executable File
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)
|