1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-14 17:08:22 +00:00

Fix log runner using zeroconf sync close running in the event loop

- Use the log runner code from aioesphomeapi since it handles zeroconf
  correctly

- Avoid calling safe_print since it has a slow late import and does
  mulitple bytes/string conversions
This commit is contained in:
J. Nick Koston 2023-11-11 13:48:52 -06:00
parent 6a5cea171e
commit 64a5bab9f0
No known key found for this signature in database
2 changed files with 28 additions and 41 deletions

View File

@ -1,19 +1,22 @@
import asyncio import asyncio
import logging import logging
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Any, Optional
from aioesphomeapi import APIClient, ReconnectLogic, APIConnectionError, LogLevel from aioesphomeapi import APIClient
import zeroconf from aioesphomeapi.api_pb2 import SubscribeLogsResponse
from aioesphomeapi.log_runner import async_run
from esphome.const import CONF_KEY, CONF_PASSWORD, CONF_PORT, __version__
from esphome.core import CORE
from esphome.const import CONF_KEY, CONF_PORT, CONF_PASSWORD, __version__
from esphome.util import safe_print
from . import CONF_ENCRYPTION from . import CONF_ENCRYPTION
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
async def async_run_logs(config, address): async def async_run_logs(config, address):
"""Run the logs command in the event loop."""
conf = config["api"] conf = config["api"]
port: int = int(conf[CONF_PORT]) port: int = int(conf[CONF_PORT])
password: str = conf[CONF_PASSWORD] password: str = conf[CONF_PASSWORD]
@ -28,44 +31,28 @@ async def async_run_logs(config, address):
client_info=f"ESPHome Logs {__version__}", client_info=f"ESPHome Logs {__version__}",
noise_psk=noise_psk, noise_psk=noise_psk,
) )
first_connect = True dashboard = CORE.dashboard
def on_log(msg): def on_log(msg: SubscribeLogsResponse) -> None:
time_ = datetime.now().time().strftime("[%H:%M:%S]") """Handle a new log message."""
text = msg.message.decode("utf8", "backslashreplace") time_ = datetime.now()
safe_print(time_ + text) message: bytes = msg.message
text = message.decode("utf8", "backslashreplace")
async def on_connect(): if dashboard:
nonlocal first_connect text = text.replace("\033", "\\033")
try: print(f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}]{text}")
await cli.subscribe_logs(
on_log,
log_level=LogLevel.LOG_LEVEL_VERY_VERBOSE,
dump_config=first_connect,
)
first_connect = False
except APIConnectionError:
cli.disconnect()
async def on_disconnect(expected_disconnect: bool) -> None:
_LOGGER.warning("Disconnected from API")
zc = zeroconf.Zeroconf()
reconnect = ReconnectLogic(
client=cli,
on_connect=on_connect,
on_disconnect=on_disconnect,
zeroconf_instance=zc,
)
await reconnect.start()
stop = await async_run(cli, on_log)
try: try:
while True: while True:
await asyncio.sleep(60) await asyncio.sleep(60)
except KeyboardInterrupt: finally:
await reconnect.stop() await stop()
zc.close()
def run_logs(config, address): def run_logs(config: dict[str, Any], address: str) -> None:
"""Run the logs command."""
try:
asyncio.run(async_run_logs(config, address)) asyncio.run(async_run_logs(config, address))
except KeyboardInterrupt:
pass

View File

@ -10,7 +10,7 @@ platformio==6.1.11 # When updating platformio, also update Dockerfile
esptool==4.6.2 esptool==4.6.2
click==8.1.7 click==8.1.7
esphome-dashboard==20231107.0 esphome-dashboard==20231107.0
aioesphomeapi==18.2.7 aioesphomeapi==18.4.0
zeroconf==0.122.3 zeroconf==0.122.3
# esp-idf requires this, but doesn't bundle it by default # esp-idf requires this, but doesn't bundle it by default