mirror of
https://github.com/esphome/esphome.git
synced 2025-03-13 14:18:14 +00:00
Merge a1ba64ad9bcfe52b0ab19df4a43eef9219f69690 into 755b0bbfc7d404d9ce1a4a02ee8c99c4c838e63f
This commit is contained in:
commit
14d7590ebb
@ -50,6 +50,7 @@ from esphome.util import (
|
||||
run_external_process,
|
||||
safe_print,
|
||||
)
|
||||
from esphome.zeroconf import get_mac_suffix_nodes
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
@ -95,9 +96,13 @@ def choose_upload_log_host(
|
||||
if default == "SERIAL":
|
||||
return choose_prompt(options, purpose=purpose)
|
||||
if (show_ota and "ota" in CORE.config) or (show_api and "api" in CORE.config):
|
||||
options.append((f"Over The Air ({CORE.address})", CORE.address))
|
||||
if default == "OTA":
|
||||
return CORE.address
|
||||
if CORE.config["esphome"]["name_add_mac_suffix"]:
|
||||
for addr in get_mac_suffix_nodes(CORE.config["esphome"]["name"]):
|
||||
options.append((f"Over The Air ({addr})", addr))
|
||||
else:
|
||||
options.append((f"Over The Air ({CORE.address})", CORE.address))
|
||||
if default == "OTA":
|
||||
return CORE.address
|
||||
if (
|
||||
show_mqtt
|
||||
and (mqtt_config := CORE.config.get(CONF_MQTT))
|
||||
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
import time
|
||||
from typing import Callable
|
||||
|
||||
from zeroconf import IPVersion, ServiceInfo, ServiceStateChange, Zeroconf
|
||||
@ -199,3 +200,57 @@ class AsyncEsphomeZeroconf(AsyncZeroconf):
|
||||
) and (addresses := info.parsed_scoped_addresses(IPVersion.All)):
|
||||
return addresses
|
||||
return None
|
||||
|
||||
|
||||
NODE_SCAN_TIME_SEC = 2
|
||||
|
||||
|
||||
class NodeScanner:
|
||||
def __init__(self, node_raw_name: str) -> None:
|
||||
self.node_raw_name = node_raw_name
|
||||
self.aiobrowser: AsyncServiceBrowser | None = None
|
||||
self.aiozc: AsyncZeroconf | None = None
|
||||
self.found_nodes = []
|
||||
|
||||
def async_on_service_state_change(
|
||||
self,
|
||||
zeroconf: Zeroconf,
|
||||
service_type: str,
|
||||
name: str,
|
||||
state_change: ServiceStateChange,
|
||||
) -> None:
|
||||
if state_change is not ServiceStateChange.Added:
|
||||
return
|
||||
if name.startswith(self.node_raw_name):
|
||||
self.found_nodes.append(name.split(".")[0] + ".local")
|
||||
|
||||
async def async_run(self) -> None:
|
||||
self.aiozc = AsyncZeroconf(ip_version=IPVersion.V4Only)
|
||||
|
||||
services = ["_esphomelib._tcp.local."]
|
||||
self.aiobrowser = AsyncServiceBrowser(
|
||||
self.aiozc.zeroconf, services, handlers=[self.async_on_service_state_change]
|
||||
)
|
||||
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < NODE_SCAN_TIME_SEC:
|
||||
await asyncio.sleep(1)
|
||||
|
||||
await self.async_close()
|
||||
|
||||
async def async_close(self) -> None:
|
||||
assert self.aiozc is not None
|
||||
assert self.aiobrowser is not None
|
||||
await self.aiobrowser.async_cancel()
|
||||
await self.aiozc.async_close()
|
||||
|
||||
|
||||
def get_mac_suffix_nodes(node_name: str) -> list[str]:
|
||||
loop = asyncio.get_event_loop()
|
||||
runner = NodeScanner(node_name)
|
||||
try:
|
||||
loop.run_until_complete(runner.async_run())
|
||||
except KeyboardInterrupt:
|
||||
loop.run_until_complete(runner.async_close())
|
||||
|
||||
return sorted(runner.found_nodes)
|
||||
|
Loading…
x
Reference in New Issue
Block a user