wallpanell/custom_components/wall_panel/frontend.py
2026-03-25 23:55:49 +03:00

129 lines
4.6 KiB
Python
Executable File

"""Frontend registration for Wall Panel."""
from __future__ import annotations
import time
from pathlib import Path
from homeassistant.components.lovelace import _register_panel
from homeassistant.components.lovelace.dashboard import LovelaceYAML
from homeassistant.components.frontend import async_register_built_in_panel
from homeassistant.components.http import StaticPathConfig
from homeassistant.core import HomeAssistant
from .const import (
DEFAULT_DASHBOARD_URL_PATH,
CONF_REQUIRE_ADMIN,
CONF_SIDEBAR_ICON,
CONF_SIDEBAR_TITLE,
CONF_SYNC_TOKEN,
DEFAULT_FRONTEND_URL_PATH,
DEFAULT_SIDEBAR_ICON,
DEFAULT_SIDEBAR_TITLE,
DOMAIN,
)
from .helpers import current_entry_config
def _panel_url_path(entry) -> str:
# Keep the HA panel identity stable so Home Assistant can always
# discover this panel in the default-panel picker.
return DEFAULT_FRONTEND_URL_PATH
def _dashboard_url_path(entry) -> str:
# Keep the Lovelace dashboard identity stable and separate from the
# built-in HA panel path.
return DEFAULT_DASHBOARD_URL_PATH
def _dashboard_config(sidebar_title: str, sidebar_icon: str, require_admin: bool) -> dict[str, object]:
return {
"mode": "yaml",
"title": sidebar_title,
"icon": sidebar_icon,
"show_in_sidebar": False,
"require_admin": require_admin,
"filename": "custom_components/wall_panel/lovelace/ui-lovelace.yaml",
}
def _register_lovelace_dashboard(hass: HomeAssistant, dashboard_url_path: str, dashboard_config: dict[str, object]) -> None:
lovelace = hass.data.setdefault("lovelace", {})
dashboards = getattr(lovelace, "dashboards", None)
if dashboards is None and isinstance(lovelace, dict):
dashboards = lovelace.setdefault("dashboards", {})
if dashboards is None:
return
dashboards[dashboard_url_path] = LovelaceYAML(hass, dashboard_url_path, dashboard_config)
_register_panel(hass, dashboard_url_path, "yaml", dashboard_config, False)
async def async_setup_frontend(hass: HomeAssistant, entry) -> str:
"""Register the custom panel and static frontend assets."""
frontend_dir = Path(__file__).parent / "frontend"
# Bundle the HA-native assets inside the component so the integration
# does not depend on files living in the root of /config.
assets_dir = Path(__file__).parent / "assets"
state = hass.data.setdefault(DOMAIN, {})
if not state.get("_static_paths_registered"):
await hass.http.async_register_static_paths([
StaticPathConfig(
f"/api/{DOMAIN}/frontend",
str(frontend_dir),
cache_headers=False,
),
StaticPathConfig(
f"/api/{DOMAIN}/assets",
str(assets_dir),
cache_headers=False,
),
])
state["_static_paths_registered"] = True
panel_url_path = _panel_url_path(entry)
dashboard_url_path = _dashboard_url_path(entry)
sidebar_title = str(entry.options.get(CONF_SIDEBAR_TITLE, DEFAULT_SIDEBAR_TITLE) or DEFAULT_SIDEBAR_TITLE).strip()
sidebar_icon = str(entry.options.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON) or DEFAULT_SIDEBAR_ICON).strip()
require_admin = bool(entry.options.get(CONF_REQUIRE_ADMIN, False))
sync_token = str(entry.options.get(CONF_SYNC_TOKEN, "") or "").strip()
asset_version = str(int(time.time()))
runtime_config = current_entry_config(entry)
dashboard_config = _dashboard_config(sidebar_title, sidebar_icon, require_admin)
_register_lovelace_dashboard(hass, dashboard_url_path, dashboard_config)
async_register_built_in_panel(
hass,
component_name="custom",
sidebar_title=sidebar_title,
sidebar_icon=sidebar_icon,
frontend_url_path=panel_url_path,
config={
"_panel_custom": {
"name": "striker-panel-panel",
"module_url": f"/api/{DOMAIN}/frontend/panel.js?v={asset_version}",
"config": {
"runtime_config": runtime_config,
"ui_mode": "ha-native",
"entry_id": entry.entry_id,
"sync_token": sync_token,
"config_url": f"/api/{DOMAIN}/config/{entry.entry_id}",
},
}
},
require_admin=require_admin,
update=True,
)
state = hass.data.setdefault(DOMAIN, {})
state[entry.entry_id] = {
**state.get(entry.entry_id, {}),
"dashboard_url_path": dashboard_url_path,
"panel_url_path": panel_url_path,
}
return panel_url_path