Fix ESPHome Bluetooth diagnostics (#106151)

This commit is contained in:
J. Nick Koston 2023-12-20 18:33:43 -10:00 committed by GitHub
parent ced4123d4c
commit e2314565bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 105 additions and 18 deletions

View File

@ -32,12 +32,13 @@ async def async_get_config_entry_diagnostics(
if (
config_entry.unique_id
and (scanner := async_scanner_by_source(hass, config_entry.unique_id))
and (scanner := async_scanner_by_source(hass, config_entry.unique_id.upper()))
and (bluetooth_device := entry_data.bluetooth_device)
):
diag["bluetooth"] = {
"connections_free": bluetooth_device.ble_connections_free,
"connections_limit": bluetooth_device.ble_connections_limit,
"available": bluetooth_device.available,
"scanner": await scanner.async_diagnostics(),
}

View File

@ -72,6 +72,7 @@ def mock_config_entry(hass) -> MockConfigEntry:
CONF_NOISE_PSK: "12345678123456781234567812345678",
CONF_DEVICE_NAME: "test",
},
# ESPHome unique ids are lower case
unique_id="11:22:33:44:55:aa",
)
config_entry.add_to_hass(hass)
@ -96,7 +97,8 @@ def mock_device_info() -> DeviceInfo:
uses_password=False,
name="test",
legacy_bluetooth_proxy_version=0,
mac_address="11:22:33:44:55:aa",
# ESPHome mac addresses are UPPER case
mac_address="11:22:33:44:55:AA",
esphome_version="1.0.0",
)
@ -230,7 +232,7 @@ async def _mock_generic_device_entry(
"name": "test",
"friendly_name": "Test",
"esphome_version": "1.0.0",
"mac_address": "11:22:33:44:55:aa",
"mac_address": "11:22:33:44:55:AA",
}
device_info = DeviceInfo(**(default_device_info | mock_device_info))

View File

@ -10,7 +10,7 @@ async def test_bluetooth_connect_with_raw_adv(
hass: HomeAssistant, mock_bluetooth_entry_with_raw_adv: MockESPHomeDevice
) -> None:
"""Test bluetooth connect with raw advertisements."""
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner is not None
assert scanner.connectable is True
assert scanner.scanning is True
@ -18,11 +18,11 @@ async def test_bluetooth_connect_with_raw_adv(
await mock_bluetooth_entry_with_raw_adv.mock_disconnect(True)
await hass.async_block_till_done()
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner is None
await mock_bluetooth_entry_with_raw_adv.mock_connect()
await hass.async_block_till_done()
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner.scanning is True
@ -30,7 +30,7 @@ async def test_bluetooth_connect_with_legacy_adv(
hass: HomeAssistant, mock_bluetooth_entry_with_legacy_adv: MockESPHomeDevice
) -> None:
"""Test bluetooth connect with legacy advertisements."""
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner is not None
assert scanner.connectable is True
assert scanner.scanning is True
@ -38,9 +38,9 @@ async def test_bluetooth_connect_with_legacy_adv(
await mock_bluetooth_entry_with_legacy_adv.mock_disconnect(True)
await hass.async_block_till_done()
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner is None
await mock_bluetooth_entry_with_legacy_adv.mock_connect()
await hass.async_block_till_done()
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:aa")
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner.scanning is True

View File

@ -432,7 +432,7 @@ async def test_user_discovers_name_and_gets_key_from_dashboard_fails(
DeviceInfo(
uses_password=False,
name="test",
mac_address="11:22:33:44:55:aa",
mac_address="11:22:33:44:55:AA",
),
]

View File

@ -1,8 +1,13 @@
"""Tests for the diagnostics data provided by the ESPHome integration."""
from unittest.mock import ANY
from syrupy import SnapshotAssertion
from homeassistant.components import bluetooth
from homeassistant.core import HomeAssistant
from .conftest import MockESPHomeDevice
from tests.common import MockConfigEntry
from tests.components.diagnostics import get_diagnostics_for_config_entry
from tests.typing import ClientSessionGenerator
@ -20,3 +25,77 @@ async def test_diagnostics(
result = await get_diagnostics_for_config_entry(hass, hass_client, init_integration)
assert result == snapshot
async def test_diagnostics_with_bluetooth(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
mock_bluetooth_entry_with_raw_adv: MockESPHomeDevice,
) -> None:
"""Test diagnostics for config entry with Bluetooth."""
scanner = bluetooth.async_scanner_by_source(hass, "11:22:33:44:55:AA")
assert scanner is not None
assert scanner.connectable is True
entry = mock_bluetooth_entry_with_raw_adv.entry
result = await get_diagnostics_for_config_entry(hass, hass_client, entry)
assert result == {
"bluetooth": {
"available": True,
"connections_free": 0,
"connections_limit": 0,
"scanner": {
"connectable": True,
"discovered_device_timestamps": {},
"discovered_devices_and_advertisement_data": [],
"last_detection": ANY,
"monotonic_time": ANY,
"name": "test (11:22:33:44:55:AA)",
"scanning": True,
"source": "11:22:33:44:55:AA",
"start_time": ANY,
"time_since_last_device_detection": {},
"type": "ESPHomeScanner",
},
},
"config": {
"data": {
"device_name": "test",
"host": "test.local",
"password": "",
"port": 6053,
},
"disabled_by": None,
"domain": "esphome",
"entry_id": ANY,
"minor_version": 1,
"options": {"allow_service_calls": False},
"pref_disable_new_entities": False,
"pref_disable_polling": False,
"source": "user",
"title": "Mock Title",
"unique_id": "11:22:33:44:55:aa",
"version": 1,
},
"storage_data": {
"api_version": {"major": 99, "minor": 99},
"device_info": {
"bluetooth_proxy_feature_flags": 63,
"compilation_time": "",
"esphome_version": "1.0.0",
"friendly_name": "Test",
"has_deep_sleep": False,
"legacy_bluetooth_proxy_version": 0,
"mac_address": "**REDACTED**",
"manufacturer": "",
"model": "",
"name": "test",
"project_name": "",
"project_version": "",
"suggested_area": "",
"uses_password": False,
"voice_assistant_version": 0,
"webserver_port": 0,
},
"services": [],
},
}

View File

@ -51,7 +51,7 @@ async def test_migrate_entity_unique_id(
assert entity_registry.async_get_entity_id("sensor", "esphome", "my_sensor") is None
# Note that ESPHome includes the EntityInfo type in the unique id
# as this is not a 1:1 mapping to the entity platform (ie. text_sensor)
assert entry.unique_id == "11:22:33:44:55:aa-sensor-mysensor"
assert entry.unique_id == "11:22:33:44:55:AA-sensor-mysensor"
async def test_migrate_entity_unique_id_downgrade_upgrade(
@ -71,7 +71,7 @@ async def test_migrate_entity_unique_id_downgrade_upgrade(
entity_registry.async_get_or_create(
"sensor",
"esphome",
"11:22:33:44:55:aa-sensor-mysensor",
"11:22:33:44:55:AA-sensor-mysensor",
suggested_object_id="new_sensor",
disabled_by=None,
)
@ -108,4 +108,4 @@ async def test_migrate_entity_unique_id_downgrade_upgrade(
)
# Note that ESPHome includes the EntityInfo type in the unique id
# as this is not a 1:1 mapping to the entity platform (ie. text_sensor)
assert entry.unique_id == "11:22:33:44:55:aa-sensor-mysensor"
assert entry.unique_id == "11:22:33:44:55:AA-sensor-mysensor"

View File

@ -45,7 +45,7 @@ async def test_esphome_device_with_old_bluetooth(
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
issue = issue_registry.async_get_issue(
"esphome", "ble_firmware_outdated-11:22:33:44:55:aa"
"esphome", "ble_firmware_outdated-11:22:33:44:55:AA"
)
assert (
issue.learn_more_url
@ -87,7 +87,10 @@ async def test_esphome_device_with_password(
issue_registry = ir.async_get(hass)
assert (
issue_registry.async_get_issue(
"esphome", "api_password_deprecated-11:22:33:44:55:aa"
# This issue uses the ESPHome mac address which
# is always UPPER case
"esphome",
"api_password_deprecated-11:22:33:44:55:AA",
)
is not None
)
@ -118,8 +121,10 @@ async def test_esphome_device_with_current_bluetooth(
await hass.async_block_till_done()
issue_registry = ir.async_get(hass)
assert (
# This issue uses the ESPHome device info mac address which
# is always UPPER case
issue_registry.async_get_issue(
"esphome", "ble_firmware_outdated-11:22:33:44:55:aa"
"esphome", "ble_firmware_outdated-11:22:33:44:55:AA"
)
is None
)

View File

@ -118,7 +118,7 @@ async def test_generic_numeric_sensor_with_entity_category_and_icon(
assert entry is not None
# Note that ESPHome includes the EntityInfo type in the unique id
# as this is not a 1:1 mapping to the entity platform (ie. text_sensor)
assert entry.unique_id == "11:22:33:44:55:aa-sensor-mysensor"
assert entry.unique_id == "11:22:33:44:55:AA-sensor-mysensor"
assert entry.entity_category is EntityCategory.DIAGNOSTIC
@ -156,7 +156,7 @@ async def test_generic_numeric_sensor_state_class_measurement(
assert entry is not None
# Note that ESPHome includes the EntityInfo type in the unique id
# as this is not a 1:1 mapping to the entity platform (ie. text_sensor)
assert entry.unique_id == "11:22:33:44:55:aa-sensor-mysensor"
assert entry.unique_id == "11:22:33:44:55:AA-sensor-mysensor"
assert entry.entity_category is None