Add bluetooth diagnostics to esphome (#82761)

This commit is contained in:
J. Nick Koston 2022-11-27 09:59:37 -10:00 committed by GitHub
parent 3e3138ef1b
commit f0ae1cc6ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 116 additions and 17 deletions

View File

@ -67,12 +67,14 @@ class BaseHaScanner:
"""Return diagnostic information about the scanner."""
return {
"type": self.__class__.__name__,
"discovered_devices": [
"discovered_devices_and_advertisement_data": [
{
"name": device.name,
"address": device.address,
"name": device_adv[0].name,
"address": device_adv[0].address,
"rssi": device_adv[0].rssi,
"advertisement_data": device_adv[1],
}
for device in self.discovered_devices
for device_adv in self.discovered_devices_and_advertisement_data.values()
],
}

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import re
from typing import Any
from aioesphomeapi import BluetoothLEAdvertisement
@ -27,3 +28,18 @@ class ESPHomeScanner(BaseHaRemoteScanner):
adv.manufacturer_data,
None,
)
async def async_diagnostics(self) -> dict[str, Any]:
"""Return diagnostic information about the scanner."""
return await super().async_diagnostics() | {
"type": self.__class__.__name__,
"discovered_devices_and_advertisement_data": [
{
"name": device_adv[0].name,
"address": device_adv[0].address,
"rssi": device_adv[0].rssi,
"advertisement_data": device_adv[1],
}
for device_adv in self.discovered_devices_and_advertisement_data.values()
],
}

View File

@ -3,6 +3,7 @@ from __future__ import annotations
from typing import Any, cast
from homeassistant.components.bluetooth import async_scanner_by_source
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_PASSWORD
@ -29,4 +30,13 @@ async def async_get_config_entry_diagnostics(
storage_data = cast("dict[str, Any]", storage_data)
diag["storage_data"] = storage_data
if config_entry.unique_id and (
scanner := async_scanner_by_source(hass, config_entry.unique_id)
):
diag["bluetooth"] = {
"connections_free": entry_data.ble_connections_free,
"connections_limit": entry_data.ble_connections_limit,
"scanner": await scanner.async_diagnostics(),
}
return async_redact_data(diag, REDACT_KEYS)

View File

@ -24,8 +24,13 @@ async def test_diagnostics(
# error if the test is not running on linux since we won't have the correct
# deps installed when testing on MacOS.
with patch(
"homeassistant.components.bluetooth.scanner.HaScanner.discovered_devices",
[BLEDevice(name="x", rssi=-60, address="44:44:33:11:23:45")],
"homeassistant.components.bluetooth.scanner.HaScanner.discovered_devices_and_advertisement_data",
{
"44:44:33:11:23:45": (
BLEDevice(name="x", rssi=-60, address="44:44:33:11:23:45"),
generate_advertisement_data(local_name="x"),
)
},
), patch(
"homeassistant.components.bluetooth.diagnostics.platform.system",
return_value="Linux",
@ -120,8 +125,21 @@ async def test_diagnostics(
"scanners": [
{
"adapter": "hci0",
"discovered_devices": [
{"address": "44:44:33:11:23:45", "name": "x"}
"discovered_devices_and_advertisement_data": [
{
"address": "44:44:33:11:23:45",
"advertisement_data": [
"x",
{},
{},
[],
-127,
-127,
[[]],
],
"name": "x",
"rssi": -60,
}
],
"last_detection": ANY,
"name": "hci0 (00:00:00:00:00:01)",
@ -131,8 +149,21 @@ async def test_diagnostics(
},
{
"adapter": "hci0",
"discovered_devices": [
{"address": "44:44:33:11:23:45", "name": "x"}
"discovered_devices_and_advertisement_data": [
{
"address": "44:44:33:11:23:45",
"advertisement_data": [
"x",
{},
{},
[],
-127,
-127,
[[]],
],
"name": "x",
"rssi": -60,
}
],
"last_detection": ANY,
"name": "hci0 (00:00:00:00:00:01)",
@ -142,8 +173,21 @@ async def test_diagnostics(
},
{
"adapter": "hci1",
"discovered_devices": [
{"address": "44:44:33:11:23:45", "name": "x"}
"discovered_devices_and_advertisement_data": [
{
"address": "44:44:33:11:23:45",
"advertisement_data": [
"x",
{},
{},
[],
-127,
-127,
[[]],
],
"name": "x",
"rssi": -60,
}
],
"last_detection": ANY,
"name": "hci1 (00:00:00:00:00:02)",
@ -171,8 +215,13 @@ async def test_diagnostics_macos(
)
with patch(
"homeassistant.components.bluetooth.scanner.HaScanner.discovered_devices",
[BLEDevice(name="x", rssi=-60, address="44:44:33:11:23:45")],
"homeassistant.components.bluetooth.scanner.HaScanner.discovered_devices_and_advertisement_data",
{
"44:44:33:11:23:45": (
BLEDevice(name="x", rssi=-60, address="44:44:33:11:23:45"),
switchbot_adv,
)
},
), patch(
"homeassistant.components.bluetooth.diagnostics.platform.system",
return_value="Darwin",
@ -274,8 +323,26 @@ async def test_diagnostics_macos(
"scanners": [
{
"adapter": "Core Bluetooth",
"discovered_devices": [
{"address": "44:44:33:11:23:45", "name": "x"}
"discovered_devices_and_advertisement_data": [
{
"address": "44:44:33:11:23:45",
"advertisement_data": [
"wohand",
{
"1": {
"__type": "<class " "'bytes'>",
"repr": "b'\\x01'",
}
},
{},
[],
-127,
-127,
[[]],
],
"name": "x",
"rssi": -60,
}
],
"last_detection": ANY,
"name": "Core Bluetooth",

View File

@ -1,6 +1,7 @@
"""Tests for the diagnostics data provided by the ESPHome integration."""
from aiohttp import ClientSession
import pytest
from homeassistant.components.esphome import CONF_NOISE_PSK
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT
@ -11,7 +12,10 @@ from tests.components.diagnostics import get_diagnostics_for_config_entry
async def test_diagnostics(
hass: HomeAssistant, hass_client: ClientSession, init_integration: MockConfigEntry
hass: HomeAssistant,
hass_client: ClientSession,
init_integration: MockConfigEntry,
enable_bluetooth: pytest.fixture,
):
"""Test diagnostics for config entry."""
result = await get_diagnostics_for_config_entry(hass, hass_client, init_integration)