"""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