-
This commit is contained in:
parent
4c6ba44dba
commit
b5d3feb726
@ -455,6 +455,10 @@
|
|||||||
url.searchParams.set(key, value);
|
url.searchParams.set(key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const proxyToken = String(window.APP_BOOTSTRAP?.ui?.proxy_token || '').trim();
|
||||||
|
if (proxyToken && !url.searchParams.has('token')) {
|
||||||
|
url.searchParams.set('token', proxyToken);
|
||||||
|
}
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "Wall Panel",
|
"title": "Striker Panel",
|
||||||
"poll_interval_ms": 5000,
|
"poll_interval_ms": 5000,
|
||||||
"main_room_name": "Главная",
|
"main_room_name": "Главная",
|
||||||
"main_room_icon": "mdi:home",
|
"main_room_icon": "mdi:home",
|
||||||
|
|||||||
@ -30,7 +30,7 @@ from .helpers import config_to_json, normalize_config, parse_config_json
|
|||||||
|
|
||||||
def _schema(defaults: dict[str, Any]) -> vol.Schema:
|
def _schema(defaults: dict[str, Any]) -> vol.Schema:
|
||||||
return vol.Schema({
|
return vol.Schema({
|
||||||
vol.Optional(CONF_NAME, default=defaults.get(CONF_NAME, "Wall Panel")): str,
|
vol.Optional(CONF_NAME, default=defaults.get(CONF_NAME, "Striker Panel")): str,
|
||||||
vol.Optional(CONF_PANEL_URL, default=defaults.get(CONF_PANEL_URL, DEFAULT_PANEL_URL)): 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_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_SIDEBAR_ICON, default=defaults.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON)): str,
|
||||||
@ -61,7 +61,7 @@ class WallPanelConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
errors[CONF_CONFIG] = "invalid_json"
|
errors[CONF_CONFIG] = "invalid_json"
|
||||||
else:
|
else:
|
||||||
data = {
|
data = {
|
||||||
CONF_NAME: user_input.get(CONF_NAME, "Wall Panel"),
|
CONF_NAME: user_input.get(CONF_NAME, "Striker Panel"),
|
||||||
CONF_PANEL_URL: str(user_input.get(CONF_PANEL_URL, "") or ""),
|
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_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_SIDEBAR_ICON: str(user_input.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON) or DEFAULT_SIDEBAR_ICON),
|
||||||
@ -75,7 +75,7 @@ class WallPanelConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
return self.async_create_entry(title=data[CONF_SIDEBAR_TITLE], data={}, options=data)
|
return self.async_create_entry(title=data[CONF_SIDEBAR_TITLE], data={}, options=data)
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
CONF_NAME: "Wall Panel",
|
CONF_NAME: "Striker Panel",
|
||||||
CONF_PANEL_URL: DEFAULT_PANEL_URL,
|
CONF_PANEL_URL: DEFAULT_PANEL_URL,
|
||||||
CONF_SIDEBAR_TITLE: DEFAULT_SIDEBAR_TITLE,
|
CONF_SIDEBAR_TITLE: DEFAULT_SIDEBAR_TITLE,
|
||||||
CONF_SIDEBAR_ICON: DEFAULT_SIDEBAR_ICON,
|
CONF_SIDEBAR_ICON: DEFAULT_SIDEBAR_ICON,
|
||||||
@ -106,7 +106,7 @@ class WallPanelOptionsFlow(config_entries.OptionsFlow):
|
|||||||
else:
|
else:
|
||||||
data = dict(self.config_entry.options)
|
data = dict(self.config_entry.options)
|
||||||
data.update({
|
data.update({
|
||||||
CONF_NAME: user_input.get(CONF_NAME, data.get(CONF_NAME, "Wall Panel")),
|
CONF_NAME: user_input.get(CONF_NAME, data.get(CONF_NAME, "Striker Panel")),
|
||||||
CONF_PANEL_URL: str(user_input.get(CONF_PANEL_URL, "") or ""),
|
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_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_SIDEBAR_ICON: str(user_input.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON) or DEFAULT_SIDEBAR_ICON),
|
||||||
@ -118,7 +118,7 @@ class WallPanelOptionsFlow(config_entries.OptionsFlow):
|
|||||||
return self.async_create_entry(title="", data=data)
|
return self.async_create_entry(title="", data=data)
|
||||||
|
|
||||||
defaults = {
|
defaults = {
|
||||||
CONF_NAME: self.config_entry.options.get(CONF_NAME, "Wall Panel"),
|
CONF_NAME: self.config_entry.options.get(CONF_NAME, "Striker Panel"),
|
||||||
CONF_PANEL_URL: self.config_entry.options.get(CONF_PANEL_URL, DEFAULT_PANEL_URL),
|
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_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_SIDEBAR_ICON: self.config_entry.options.get(CONF_SIDEBAR_ICON, DEFAULT_SIDEBAR_ICON),
|
||||||
|
|||||||
@ -10,8 +10,8 @@ CONF_SIDEBAR_ICON = "sidebar_icon"
|
|||||||
CONF_FRONTEND_URL_PATH = "frontend_url_path"
|
CONF_FRONTEND_URL_PATH = "frontend_url_path"
|
||||||
CONF_REQUIRE_ADMIN = "require_admin"
|
CONF_REQUIRE_ADMIN = "require_admin"
|
||||||
|
|
||||||
DEFAULT_NAME = "Wall Panel"
|
DEFAULT_NAME = "Striker Panel"
|
||||||
DEFAULT_PANEL_URL = ""
|
DEFAULT_PANEL_URL = ""
|
||||||
DEFAULT_SIDEBAR_TITLE = "Wall Panel"
|
DEFAULT_SIDEBAR_TITLE = "Striker Panel"
|
||||||
DEFAULT_SIDEBAR_ICON = "mdi:view-dashboard"
|
DEFAULT_SIDEBAR_ICON = "mdi:view-dashboard"
|
||||||
DEFAULT_FRONTEND_URL_PATH = "wall-panel"
|
DEFAULT_FRONTEND_URL_PATH = "striker-panel"
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import time
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from homeassistant.components.frontend import async_register_built_in_panel
|
from homeassistant.components.frontend import async_register_built_in_panel
|
||||||
@ -43,6 +44,7 @@ async def async_setup_frontend(hass: HomeAssistant, entry) -> str:
|
|||||||
require_admin = bool(entry.options.get(CONF_REQUIRE_ADMIN, False))
|
require_admin = bool(entry.options.get(CONF_REQUIRE_ADMIN, False))
|
||||||
panel_url = str(entry.options.get(CONF_PANEL_URL, "") or "").strip()
|
panel_url = str(entry.options.get(CONF_PANEL_URL, "") or "").strip()
|
||||||
sync_token = str(entry.options.get(CONF_SYNC_TOKEN, "") or "").strip()
|
sync_token = str(entry.options.get(CONF_SYNC_TOKEN, "") or "").strip()
|
||||||
|
asset_version = str(int(time.time()))
|
||||||
|
|
||||||
async_register_built_in_panel(
|
async_register_built_in_panel(
|
||||||
hass,
|
hass,
|
||||||
@ -52,8 +54,8 @@ async def async_setup_frontend(hass: HomeAssistant, entry) -> str:
|
|||||||
frontend_url_path=panel_url_path,
|
frontend_url_path=panel_url_path,
|
||||||
config={
|
config={
|
||||||
"_panel_custom": {
|
"_panel_custom": {
|
||||||
"name": "wall-panel-panel",
|
"name": "striker-panel-panel",
|
||||||
"module_url": f"/api/{DOMAIN}/frontend/panel.js",
|
"module_url": f"/api/{DOMAIN}/frontend/panel.js?v={asset_version}",
|
||||||
"embed_iframe": False,
|
"embed_iframe": False,
|
||||||
"trust_external": False,
|
"trust_external": False,
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
@ -81,7 +81,15 @@ class WallPanelPanel extends HTMLElement {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return `/api/wall_panel/proxy/${encodeURIComponent(entryId)}/`;
|
const token = String(payload.sync_token || '').trim();
|
||||||
|
const url = `/api/wall_panel/proxy/${encodeURIComponent(entryId)}/`;
|
||||||
|
if (!token) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyUrl = new URL(url, window.location.href);
|
||||||
|
proxyUrl.searchParams.set('token', token);
|
||||||
|
return proxyUrl.pathname + proxyUrl.search + proxyUrl.hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
_hasPanelUrl() {
|
_hasPanelUrl() {
|
||||||
@ -191,7 +199,7 @@ class WallPanelPanel extends HTMLElement {
|
|||||||
const panelUrl = this._resolveUrl(payload.panel_url || payload.ingress_url || '');
|
const panelUrl = this._resolveUrl(payload.panel_url || payload.ingress_url || '');
|
||||||
const configUrl = this._configUrl();
|
const configUrl = this._configUrl();
|
||||||
this._renderMessage(
|
this._renderMessage(
|
||||||
'Waiting for Wall Panel',
|
'Waiting for Striker Panel',
|
||||||
panelUrl
|
panelUrl
|
||||||
? 'Open this panel through Home Assistant after the add-on URL is configured.'
|
? 'Open this panel through Home Assistant after the add-on URL is configured.'
|
||||||
: 'Set the PHP panel URL in the integration options.',
|
: 'Set the PHP panel URL in the integration options.',
|
||||||
@ -216,6 +224,6 @@ class WallPanelPanel extends HTMLElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!customElements.get('wall-panel-panel')) {
|
if (!customElements.get('striker-panel-panel')) {
|
||||||
customElements.define('wall-panel-panel', WallPanelPanel);
|
customElements.define('striker-panel-panel', WallPanelPanel);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ from .const import (
|
|||||||
def default_config() -> dict[str, Any]:
|
def default_config() -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"app": {
|
"app": {
|
||||||
"title": "Wall Panel",
|
"title": "Striker Panel",
|
||||||
"poll_interval_ms": 5000,
|
"poll_interval_ms": 5000,
|
||||||
"main_room_name": "Главная",
|
"main_room_name": "Главная",
|
||||||
"main_room_icon": "mdi:home",
|
"main_room_icon": "mdi:home",
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"domain": "wall_panel",
|
"domain": "wall_panel",
|
||||||
"name": "Wall Panel",
|
"name": "Striker Panel",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"documentation": "https://example.invalid/wall-panel",
|
"documentation": "https://example.invalid/striker-panel",
|
||||||
"codeowners": [],
|
"codeowners": [],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Wall Panel",
|
"title": "Striker Panel",
|
||||||
"description": "Connect Wall Panel to Home Assistant.",
|
"description": "Connect Striker Panel to Home Assistant.",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"panel_url": "PHP panel URL",
|
"panel_url": "PHP panel URL",
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
"config": {
|
"config": {
|
||||||
"step": {
|
"step": {
|
||||||
"user": {
|
"user": {
|
||||||
"title": "Wall Panel",
|
"title": "Striker Panel",
|
||||||
"description": "Connect Wall Panel to Home Assistant.",
|
"description": "Connect Striker Panel to Home Assistant.",
|
||||||
"data": {
|
"data": {
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"panel_url": "PHP panel URL",
|
"panel_url": "PHP panel URL",
|
||||||
|
|||||||
@ -235,6 +235,9 @@ async def _handle_proxy_request(request: web.Request, entry_id: str, path: str,
|
|||||||
entry = _entry_from_hass(hass, entry_id)
|
entry = _entry_from_hass(hass, entry_id)
|
||||||
if entry is None:
|
if entry is None:
|
||||||
return _response({"ok": False, "error": "Unknown entry"}, 404)
|
return _response({"ok": False, "error": "Unknown entry"}, 404)
|
||||||
|
if not _authorized(entry, request):
|
||||||
|
_LOGGER.warning("Wall Panel proxy denied for %s: unauthorized", entry_id)
|
||||||
|
return _response({"ok": False, "error": "Unauthorized"}, 401)
|
||||||
|
|
||||||
base_url = str(entry.options.get(CONF_PANEL_URL, "") or "").strip()
|
base_url = str(entry.options.get(CONF_PANEL_URL, "") or "").strip()
|
||||||
if not base_url:
|
if not base_url:
|
||||||
|
|||||||
@ -27,6 +27,7 @@ $bootstrap['ui'] = [
|
|||||||
'mode' => $runtimeMode,
|
'mode' => $runtimeMode,
|
||||||
'shell' => $embedMode ? 'embed' : 'standalone',
|
'shell' => $embedMode ? 'embed' : 'standalone',
|
||||||
'config_source' => app_remote_sync_enabled($config) ? 'ha' : 'file',
|
'config_source' => app_remote_sync_enabled($config) ? 'ha' : 'file',
|
||||||
|
'proxy_token' => trim((string)($_GET['token'] ?? '')),
|
||||||
];
|
];
|
||||||
$appTitle = htmlspecialchars((string)($config['app']['title'] ?? 'Wall Panel'), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
$appTitle = htmlspecialchars((string)($config['app']['title'] ?? 'Wall Panel'), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||||
?>
|
?>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ function app_default_config(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'app' => [
|
'app' => [
|
||||||
'title' => 'Wall Panel',
|
'title' => 'Striker Panel',
|
||||||
'poll_interval_ms' => 5000,
|
'poll_interval_ms' => 5000,
|
||||||
'main_room_name' => 'Главная',
|
'main_room_name' => 'Главная',
|
||||||
'main_room_icon' => 'mdi:home',
|
'main_room_icon' => 'mdi:home',
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
name: Wall Panel Add-ons
|
name: Striker Panel Add-ons
|
||||||
url: https://git.striker72rus.ru/PHP/wallpanell.git
|
url: https://git.striker72rus.ru/PHP/wallpanell.git
|
||||||
maintainer: Striker72rus
|
maintainer: Striker72rus
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"active": false,
|
"active": false,
|
||||||
"sensor_entity_id": "binary_sensor.barn_all_occupancy",
|
"sensor_entity_id": "binary_sensor.barn_all_occupancy",
|
||||||
"opened_at": 1774444953,
|
"opened_at": 1774445418,
|
||||||
"expires_at": null
|
"expires_at": null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -455,6 +455,10 @@
|
|||||||
url.searchParams.set(key, value);
|
url.searchParams.set(key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const proxyToken = String(window.APP_BOOTSTRAP?.ui?.proxy_token || '').trim();
|
||||||
|
if (proxyToken && !url.searchParams.has('token')) {
|
||||||
|
url.searchParams.set('token', proxyToken);
|
||||||
|
}
|
||||||
return url.toString();
|
return url.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
name: Wall Panel
|
name: Striker Panel
|
||||||
description: Wall Panel PHP interface as a Home Assistant add-on
|
description: Striker Panel PHP interface as a Home Assistant add-on
|
||||||
version: "1.0.22"
|
version: "1.0.23"
|
||||||
slug: wall_panel
|
slug: wall_panel
|
||||||
url: https://git.striker72rus.ru/PHP/wallpanell.git
|
url: https://git.striker72rus.ru/PHP/wallpanell.git
|
||||||
init: false
|
init: false
|
||||||
@ -15,14 +15,14 @@ ingress: true
|
|||||||
ingress_panel: true
|
ingress_panel: true
|
||||||
ingress_port: 8099
|
ingress_port: 8099
|
||||||
webui: "http://[HOST]:[PORT:8099]/"
|
webui: "http://[HOST]:[PORT:8099]/"
|
||||||
panel_title: Wall Panel
|
panel_title: Striker Panel
|
||||||
panel_icon: mdi:view-dashboard
|
panel_icon: mdi:view-dashboard
|
||||||
hassio_api: true
|
hassio_api: true
|
||||||
hassio_role: default
|
hassio_role: default
|
||||||
ports:
|
ports:
|
||||||
8099/tcp: 8099
|
8099/tcp: 8099
|
||||||
ports_description:
|
ports_description:
|
||||||
8099/tcp: Wall Panel web UI
|
8099/tcp: Striker Panel web UI
|
||||||
map:
|
map:
|
||||||
- type: homeassistant_config
|
- type: homeassistant_config
|
||||||
read_only: false
|
read_only: false
|
||||||
@ -30,7 +30,7 @@ map:
|
|||||||
homeassistant_api: true
|
homeassistant_api: true
|
||||||
options:
|
options:
|
||||||
app:
|
app:
|
||||||
title: Wall Panel
|
title: Striker Panel
|
||||||
poll_interval_ms: 5000
|
poll_interval_ms: 5000
|
||||||
main_room_name: Главная
|
main_room_name: Главная
|
||||||
main_room_icon: mdi:home
|
main_room_icon: mdi:home
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "Wall Panel",
|
"title": "Striker Panel",
|
||||||
"poll_interval_ms": 5000,
|
"poll_interval_ms": 5000,
|
||||||
"main_room_name": "Главная",
|
"main_room_name": "Главная",
|
||||||
"main_room_icon": "mdi:home",
|
"main_room_icon": "mdi:home",
|
||||||
|
|||||||
@ -27,6 +27,7 @@ $bootstrap['ui'] = [
|
|||||||
'mode' => $runtimeMode,
|
'mode' => $runtimeMode,
|
||||||
'shell' => $embedMode ? 'embed' : 'standalone',
|
'shell' => $embedMode ? 'embed' : 'standalone',
|
||||||
'config_source' => app_remote_sync_enabled($config) ? 'ha' : 'file',
|
'config_source' => app_remote_sync_enabled($config) ? 'ha' : 'file',
|
||||||
|
'proxy_token' => trim((string)($_GET['token'] ?? '')),
|
||||||
];
|
];
|
||||||
$appTitle = htmlspecialchars((string)($config['app']['title'] ?? 'Wall Panel'), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
$appTitle = htmlspecialchars((string)($config['app']['title'] ?? 'Wall Panel'), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||||
?>
|
?>
|
||||||
|
|||||||
@ -5,7 +5,7 @@ function app_default_config(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'app' => [
|
'app' => [
|
||||||
'title' => 'Wall Panel',
|
'title' => 'Striker Panel',
|
||||||
'poll_interval_ms' => 5000,
|
'poll_interval_ms' => 5000,
|
||||||
'main_room_name' => 'Главная',
|
'main_room_name' => 'Главная',
|
||||||
'main_room_icon' => 'mdi:home',
|
'main_room_icon' => 'mdi:home',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user