1
0
mirror of https://github.com/esphome/esphome.git synced 2025-02-12 16:08:19 +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 logging
from datetime import datetime
from typing import Optional
from typing import Any, Optional
from aioesphomeapi import APIClient, ReconnectLogic, APIConnectionError, LogLevel
import zeroconf
from aioesphomeapi import APIClient
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
_LOGGER = logging.getLogger(__name__)
async def async_run_logs(config, address):
"""Run the logs command in the event loop."""
conf = config["api"]
port: int = int(conf[CONF_PORT])
password: str = conf[CONF_PASSWORD]
@ -28,44 +31,28 @@ async def async_run_logs(config, address):
client_info=f"ESPHome Logs {__version__}",
noise_psk=noise_psk,
)
first_connect = True
dashboard = CORE.dashboard
def on_log(msg):
time_ = datetime.now().time().strftime("[%H:%M:%S]")
text = msg.message.decode("utf8", "backslashreplace")
safe_print(time_ + text)
async def on_connect():
nonlocal first_connect
try:
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()
def on_log(msg: SubscribeLogsResponse) -> None:
"""Handle a new log message."""
time_ = datetime.now()
message: bytes = msg.message
text = message.decode("utf8", "backslashreplace")
if dashboard:
text = text.replace("\033", "\\033")
print(f"[{time_.hour:02}:{time_.minute:02}:{time_.second:02}]{text}")
stop = await async_run(cli, on_log)
try:
while True:
await asyncio.sleep(60)
except KeyboardInterrupt:
await reconnect.stop()
zc.close()
finally:
await stop()
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))
except KeyboardInterrupt:
pass

View File

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