Files
esphome-dev/esphome/dashboard/status/mdns.py
T
J. Nick Koston cd9bf29df1 dashboard: Add lookup by name to entries (#5790)
* Add lookup by name to entries

* adj

* tweak

* tweak

* tweak

* tweak

* tweak

* tweak

* preen
2023-11-19 22:29:40 -05:00

84 lines
2.8 KiB
Python

from __future__ import annotations
import asyncio
from esphome.zeroconf import (
ESPHOME_SERVICE_TYPE,
AsyncEsphomeZeroconf,
DashboardBrowser,
DashboardImportDiscovery,
DashboardStatus,
)
from ..const import SENTINEL
from ..core import DASHBOARD
from ..entries import bool_to_entry_state
class MDNSStatus:
"""Class that updates the mdns status."""
def __init__(self) -> None:
"""Initialize the MDNSStatus class."""
super().__init__()
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] = {}
self._loop = asyncio.get_running_loop()
async def async_resolve_host(self, host_name: str) -> str | None:
"""Resolve a host name to an address in a thread-safe manner."""
if aiozc := self.aiozc:
return await aiozc.async_resolve_host(host_name)
return None
async def async_refresh_hosts(self):
"""Refresh the hosts to track."""
dashboard = DASHBOARD
host_mdns_state = self.host_mdns_state
entries = dashboard.entries
for entry in entries.async_all():
if entry.no_mdns:
continue
# 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(entry.name, SENTINEL)) != SENTINEL:
entries.async_set_state(entry, bool_to_entry_state(online))
async def async_run(self) -> None:
dashboard = DASHBOARD
entries = dashboard.entries
aiozc = AsyncEsphomeZeroconf()
self.aiozc = aiozc
host_mdns_state = self.host_mdns_state
def on_update(dat: dict[str, bool | None]) -> None:
"""Update the entry state."""
for name, result in dat.items():
host_mdns_state[name] = result
if matching_entries := entries.get_by_name(name):
for entry in matching_entries:
if not entry.no_mdns:
entries.async_set_state(entry, bool_to_entry_state(result))
stat = DashboardStatus(on_update)
imports = DashboardImportDiscovery()
dashboard.import_result = imports.import_state
browser = DashboardBrowser(
aiozc.zeroconf,
ESPHOME_SERVICE_TYPE,
[stat.browser_callback, imports.browser_callback],
)
ping_request = dashboard.ping_request
while not dashboard.stop_event.is_set():
await self.async_refresh_hosts()
await ping_request.wait()
ping_request.clear()
await browser.async_cancel()
await aiozc.async_close()
self.aiozc = None