diff --git a/esphome/dashboard/entries.py b/esphome/dashboard/entries.py index 42b3a2e743..060cd4cc9d 100644 --- a/esphome/dashboard/entries.py +++ b/esphome/dashboard/entries.py @@ -4,7 +4,7 @@ import asyncio import logging import os from typing import TYPE_CHECKING, Any - +from collections import defaultdict from esphome import const, util from esphome.storage_json import StorageJSON, ext_storage_path @@ -83,11 +83,16 @@ class DashboardEntries: self._entries: dict[str, DashboardEntry] = {} self._loaded_entries = False self._update_lock = asyncio.Lock() + self._name_to_entry: dict[str, set[DashboardEntry]] = defaultdict(set) def get(self, path: str) -> DashboardEntry | None: """Get an entry by path.""" return self._entries.get(path) + def get_by_name(self, name: str) -> set[DashboardEntry] | None: + """Get an entry by name.""" + return self._name_to_entry.get(name) + async def _async_all(self) -> list[DashboardEntry]: """Return all entries.""" return list(self._entries.values()) @@ -155,6 +160,8 @@ class DashboardEntries: None, self._get_path_to_cache_key ) entries = self._entries + name_to_path = self._name_to_path + assert name_to_path is not None added: dict[DashboardEntry, DashboardCacheKeyType] = {} updated: dict[DashboardEntry, DashboardCacheKeyType] = {} removed: set[DashboardEntry] = { @@ -162,14 +169,17 @@ class DashboardEntries: for filename, entry in entries.items() if filename not in path_to_cache_key } + # TODO: remove name for path, cache_key in path_to_cache_key.items(): if entry := entries.get(path): + # TODO: entry can change name if entry.cache_key != cache_key: updated[entry] = cache_key else: entry = DashboardEntry(path, cache_key) added[entry] = cache_key + # TODO: add name if added or updated: await self._loop.run_in_executor( diff --git a/esphome/dashboard/status/mdns.py b/esphome/dashboard/status/mdns.py index cbe3b3309e..d962d90a5c 100644 --- a/esphome/dashboard/status/mdns.py +++ b/esphome/dashboard/status/mdns.py @@ -24,9 +24,6 @@ class MDNSStatus: self.aiozc: AsyncEsphomeZeroconf | None = None # This is the current mdns state for each host (True, False, None) self.host_mdns_state: dict[str, bool | None] = {} - # This is the hostnames to path mapping - self.host_name_to_path: dict[str, str] = {} - self.path_to_host_name: dict[str, str] = {} # This is a set of host names to track (i.e no_mdns = false) self.host_name_with_mdns_enabled: set[set] = set() self._loop = asyncio.get_running_loop() @@ -47,8 +44,6 @@ class MDNSStatus: current_entries = dashboard.entries.async_all() host_name_with_mdns_enabled = self.host_name_with_mdns_enabled host_mdns_state = self.host_mdns_state - host_name_to_path = self.host_name_to_path - path_to_host_name = self.path_to_host_name entries = dashboard.entries for entry in current_entries: @@ -60,27 +55,18 @@ class MDNSStatus: # We are tracking this host host_name_with_mdns_enabled.add(name) - path = entry.path - # If we just adopted/imported this host, we likely # already have a state for it, so we should make sure # to set it so the dashboard shows it as online if (online := host_mdns_state.get(name, SENTINEL)) != SENTINEL: entries.async_set_state(entry, bool_to_entry_state(online)) - # Make sure the mapping is up to date - # so when we get an mdns update we can map it back - # to the filename - host_name_to_path[name] = path - path_to_host_name[path] = name - async def async_run(self) -> None: dashboard = DASHBOARD entries = dashboard.entries aiozc = AsyncEsphomeZeroconf() self.aiozc = aiozc host_mdns_state = self.host_mdns_state - host_name_to_path = self.host_name_to_path host_name_with_mdns_enabled = self.host_name_with_mdns_enabled def on_update(dat: dict[str, bool | None]) -> None: @@ -89,8 +75,9 @@ class MDNSStatus: host_mdns_state[name] = result if name not in host_name_with_mdns_enabled: continue - if entry := entries.get(host_name_to_path[name]): - entries.async_set_state(entry, bool_to_entry_state(result)) + if matching_entries := entries.get_by_name(name): + for entry in matching_entries: + entries.async_set_state(entry, bool_to_entry_state(result)) stat = DashboardStatus(on_update) imports = DashboardImportDiscovery()