1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-27 13:13:50 +00:00

[nrf52] support BLE --device for logging (#9861)

Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
tomaszduda23
2025-10-23 02:55:34 +02:00
committed by GitHub
parent 7f567bdfbe
commit b91b12d77a
4 changed files with 81 additions and 0 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import annotations from __future__ import annotations
import asyncio
import logging import logging
from pathlib import Path from pathlib import Path
@@ -277,3 +278,19 @@ def upload_program(config: ConfigType, args, host: str) -> bool:
raise EsphomeError(f"Upload failed with result: {result}") raise EsphomeError(f"Upload failed with result: {result}")
return handled return handled
def show_logs(config: ConfigType, args, devices: list[str]) -> bool:
address = devices[0]
from .ble_logger import is_mac_address, logger_connect, logger_scan
if devices[0] == "BLE":
ble_device = asyncio.run(logger_scan(CORE.config["esphome"]["name"]))
if ble_device:
address = ble_device.address
else:
return True
if is_mac_address(address):
asyncio.run(logger_connect(address))
return True
return False

View File

@@ -0,0 +1,60 @@
import asyncio
import logging
import re
from typing import Final
from bleak import BleakClient, BleakScanner, BLEDevice
from bleak.exc import (
BleakCharacteristicNotFoundError,
BleakDBusError,
BleakDeviceNotFoundError,
)
_LOGGER = logging.getLogger(__name__)
NUS_SERVICE_UUID = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
NUS_TX_CHAR_UUID = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"
MAC_ADDRESS_PATTERN: Final = re.compile(
r"([0-9A-F]{2}[:]){5}[0-9A-F]{2}$", flags=re.IGNORECASE
)
def is_mac_address(value: str) -> bool:
return MAC_ADDRESS_PATTERN.match(value)
async def logger_scan(name: str) -> BLEDevice | None:
_LOGGER.info("Scanning bluetooth for %s...", name)
device = await BleakScanner.find_device_by_name(name)
if not device:
_LOGGER.error("%s Bluetooth LE device was not found!", name)
return device
async def logger_connect(host: str) -> int | None:
disconnected_event = asyncio.Event()
def handle_disconnect(client):
disconnected_event.set()
def handle_rx(_, data: bytearray):
print(data.decode("utf-8"), end="")
_LOGGER.info("Connecting %s...", host)
try:
async with BleakClient(host, disconnected_callback=handle_disconnect) as client:
_LOGGER.info("Connected %s...", host)
try:
await client.start_notify(NUS_TX_CHAR_UUID, handle_rx)
except BleakDBusError as e:
_LOGGER.error("Bluetooth LE logger: %s", e)
disconnected_event.set()
await disconnected_event.wait()
except BleakDeviceNotFoundError:
_LOGGER.error("Device %s not found", host)
return 1
except BleakCharacteristicNotFoundError:
_LOGGER.error("Device %s has no NUS characteristic", host)
return 1

View File

@@ -234,6 +234,9 @@ def copy_files():
"url": "https://esphome.io/", "url": "https://esphome.io/",
"vendor": "esphome", "vendor": "esphome",
"build": { "build": {
"bsp": {
"name": "adafruit"
},
"softdevice": { "softdevice": {
"sd_fwid": "0x00B6" "sd_fwid": "0x00B6"
} }

View File

@@ -22,6 +22,7 @@ pillow==11.3.0
cairosvg==2.8.2 cairosvg==2.8.2
freetype-py==2.5.1 freetype-py==2.5.1
jinja2==3.1.6 jinja2==3.1.6
bleak==1.0.1
# esp-idf >= 5.0 requires this # esp-idf >= 5.0 requires this
pyparsing >= 3.0 pyparsing >= 3.0