mirror of
https://github.com/esphome/esphome.git
synced 2024-11-14 02:58:11 +01:00
Migrate to using aioesphomeapi for the log runner to fix multiple issues (#5733)
This commit is contained in:
parent
51930a0243
commit
53f3385c49
1 changed files with 35 additions and 41 deletions
|
@ -1,71 +1,65 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Optional
|
from typing import Any
|
||||||
|
|
||||||
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 zeroconf.asyncio import AsyncZeroconf
|
||||||
|
|
||||||
|
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]
|
||||||
noise_psk: Optional[str] = None
|
noise_psk: str | None = None
|
||||||
if CONF_ENCRYPTION in conf:
|
if CONF_ENCRYPTION in conf:
|
||||||
noise_psk = conf[CONF_ENCRYPTION][CONF_KEY]
|
noise_psk = conf[CONF_ENCRYPTION][CONF_KEY]
|
||||||
_LOGGER.info("Starting log output from %s using esphome API", address)
|
_LOGGER.info("Starting log output from %s using esphome API", address)
|
||||||
|
aiozc = AsyncZeroconf()
|
||||||
|
|
||||||
cli = APIClient(
|
cli = APIClient(
|
||||||
address,
|
address,
|
||||||
port,
|
port,
|
||||||
password,
|
password,
|
||||||
client_info=f"ESPHome Logs {__version__}",
|
client_info=f"ESPHome Logs {__version__}",
|
||||||
noise_psk=noise_psk,
|
noise_psk=noise_psk,
|
||||||
|
zeroconf_instance=aiozc.zeroconf,
|
||||||
)
|
)
|
||||||
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, aio_zeroconf_instance=aiozc)
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(60)
|
await asyncio.sleep(60)
|
||||||
except KeyboardInterrupt:
|
finally:
|
||||||
await reconnect.stop()
|
await aiozc.async_close()
|
||||||
zc.close()
|
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))
|
asyncio.run(async_run_logs(config, address))
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
Loading…
Reference in a new issue