mirror of
https://github.com/esphome/esphome.git
synced 2024-12-22 13:34:54 +01:00
Support ignoring discovered devices from the dashboard (#7665)
This commit is contained in:
parent
5b5c2fe71b
commit
ca5c73d170
3 changed files with 71 additions and 0 deletions
|
@ -5,10 +5,14 @@ from collections.abc import Coroutine
|
|||
import contextlib
|
||||
from dataclasses import dataclass
|
||||
from functools import partial
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import threading
|
||||
from typing import TYPE_CHECKING, Any, Callable
|
||||
|
||||
from esphome.storage_json import ignored_devices_storage_path
|
||||
|
||||
from ..zeroconf import DiscoveredImport
|
||||
from .dns import DNSCache
|
||||
from .entries import DashboardEntries
|
||||
|
@ -20,6 +24,8 @@ if TYPE_CHECKING:
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
IGNORED_DEVICES_STORAGE_PATH = "ignored-devices.json"
|
||||
|
||||
|
||||
@dataclass
|
||||
class Event:
|
||||
|
@ -74,6 +80,7 @@ class ESPHomeDashboard:
|
|||
"settings",
|
||||
"dns_cache",
|
||||
"_background_tasks",
|
||||
"ignored_devices",
|
||||
)
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
@ -89,12 +96,30 @@ class ESPHomeDashboard:
|
|||
self.settings = DashboardSettings()
|
||||
self.dns_cache = DNSCache()
|
||||
self._background_tasks: set[asyncio.Task] = set()
|
||||
self.ignored_devices: set[str] = set()
|
||||
|
||||
async def async_setup(self) -> None:
|
||||
"""Setup the dashboard."""
|
||||
self.loop = asyncio.get_running_loop()
|
||||
self.ping_request = asyncio.Event()
|
||||
self.entries = DashboardEntries(self)
|
||||
self.load_ignored_devices()
|
||||
|
||||
def load_ignored_devices(self) -> None:
|
||||
storage_path = Path(ignored_devices_storage_path())
|
||||
try:
|
||||
with storage_path.open("r", encoding="utf-8") as f_handle:
|
||||
data = json.load(f_handle)
|
||||
self.ignored_devices = set(data.get("ignored_devices", set()))
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
def save_ignored_devices(self) -> None:
|
||||
storage_path = Path(ignored_devices_storage_path())
|
||||
with storage_path.open("w", encoding="utf-8") as f_handle:
|
||||
json.dump(
|
||||
{"ignored_devices": sorted(self.ignored_devices)}, indent=2, fp=f_handle
|
||||
)
|
||||
|
||||
async def async_run(self) -> None:
|
||||
"""Run the dashboard."""
|
||||
|
|
|
@ -541,6 +541,46 @@ class ImportRequestHandler(BaseHandler):
|
|||
self.finish()
|
||||
|
||||
|
||||
class IgnoreDeviceRequestHandler(BaseHandler):
|
||||
@authenticated
|
||||
def post(self) -> None:
|
||||
dashboard = DASHBOARD
|
||||
try:
|
||||
args = json.loads(self.request.body.decode())
|
||||
device_name = args["name"]
|
||||
ignore = args["ignore"]
|
||||
except (json.JSONDecodeError, KeyError):
|
||||
self.set_status(400)
|
||||
self.set_header("content-type", "application/json")
|
||||
self.write(json.dumps({"error": "Invalid payload"}))
|
||||
return
|
||||
|
||||
ignored_device = next(
|
||||
(
|
||||
res
|
||||
for res in dashboard.import_result.values()
|
||||
if res.device_name == device_name
|
||||
),
|
||||
None,
|
||||
)
|
||||
|
||||
if ignored_device is None:
|
||||
self.set_status(404)
|
||||
self.set_header("content-type", "application/json")
|
||||
self.write(json.dumps({"error": "Device not found"}))
|
||||
return
|
||||
|
||||
if ignore:
|
||||
dashboard.ignored_devices.add(ignored_device.device_name)
|
||||
else:
|
||||
dashboard.ignored_devices.discard(ignored_device.device_name)
|
||||
|
||||
dashboard.save_ignored_devices()
|
||||
|
||||
self.set_status(204)
|
||||
self.finish()
|
||||
|
||||
|
||||
class DownloadListRequestHandler(BaseHandler):
|
||||
@authenticated
|
||||
@bind_config
|
||||
|
@ -688,6 +728,7 @@ class ListDevicesHandler(BaseHandler):
|
|||
"project_name": res.project_name,
|
||||
"project_version": res.project_version,
|
||||
"network": res.network,
|
||||
"ignored": res.device_name in dashboard.ignored_devices,
|
||||
}
|
||||
for res in dashboard.import_result.values()
|
||||
if res.device_name not in configured
|
||||
|
@ -1156,6 +1197,7 @@ def make_app(debug=get_bool_env(ENV_DEV)) -> tornado.web.Application:
|
|||
(f"{rel}prometheus-sd", PrometheusServiceDiscoveryHandler),
|
||||
(f"{rel}boards/([a-z0-9]+)", BoardsRequestHandler),
|
||||
(f"{rel}version", EsphomeVersionHandler),
|
||||
(f"{rel}ignore-device", IgnoreDeviceRequestHandler),
|
||||
],
|
||||
**app_settings,
|
||||
)
|
||||
|
|
|
@ -28,6 +28,10 @@ def esphome_storage_path() -> str:
|
|||
return os.path.join(CORE.data_dir, "esphome.json")
|
||||
|
||||
|
||||
def ignored_devices_storage_path() -> str:
|
||||
return os.path.join(CORE.data_dir, "ignored-devices.json")
|
||||
|
||||
|
||||
def trash_storage_path() -> str:
|
||||
return CORE.relative_config_path("trash")
|
||||
|
||||
|
|
Loading…
Reference in a new issue