mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 22:27:07 +00:00
Include HKC BLE MAC in device info when available (#141900)
* Include HKC BLE MAC in device info when available * update tests * cover * dry * dry * dry
This commit is contained in:
parent
1aa996d5f0
commit
6f02550ac3
@ -9,10 +9,11 @@ from functools import partial
|
|||||||
import logging
|
import logging
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from types import MappingProxyType
|
from types import MappingProxyType
|
||||||
from typing import Any
|
from typing import Any, cast
|
||||||
|
|
||||||
from aiohomekit import Controller
|
from aiohomekit import Controller
|
||||||
from aiohomekit.controller import TransportType
|
from aiohomekit.controller import TransportType
|
||||||
|
from aiohomekit.controller.ble.discovery import BleDiscovery
|
||||||
from aiohomekit.exceptions import (
|
from aiohomekit.exceptions import (
|
||||||
AccessoryDisconnectedError,
|
AccessoryDisconnectedError,
|
||||||
AccessoryNotFoundError,
|
AccessoryNotFoundError,
|
||||||
@ -372,6 +373,16 @@ class HKDevice:
|
|||||||
if not self.unreliable_serial_numbers:
|
if not self.unreliable_serial_numbers:
|
||||||
identifiers.add((IDENTIFIER_SERIAL_NUMBER, accessory.serial_number))
|
identifiers.add((IDENTIFIER_SERIAL_NUMBER, accessory.serial_number))
|
||||||
|
|
||||||
|
connections: set[tuple[str, str]] = set()
|
||||||
|
if self.pairing.transport == Transport.BLE and (
|
||||||
|
discovery := self.pairing.controller.discoveries.get(
|
||||||
|
normalize_hkid(self.unique_id)
|
||||||
|
)
|
||||||
|
):
|
||||||
|
connections = {
|
||||||
|
(dr.CONNECTION_BLUETOOTH, cast(BleDiscovery, discovery).device.address),
|
||||||
|
}
|
||||||
|
|
||||||
device_info = DeviceInfo(
|
device_info = DeviceInfo(
|
||||||
identifiers={
|
identifiers={
|
||||||
(
|
(
|
||||||
@ -379,6 +390,7 @@ class HKDevice:
|
|||||||
f"{self.unique_id}:aid:{accessory.aid}",
|
f"{self.unique_id}:aid:{accessory.aid}",
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
connections=connections,
|
||||||
name=accessory.name,
|
name=accessory.name,
|
||||||
manufacturer=accessory.manufacturer,
|
manufacturer=accessory.manufacturer,
|
||||||
model=accessory.model,
|
model=accessory.model,
|
||||||
|
@ -4,7 +4,9 @@ from collections.abc import Callable, Generator
|
|||||||
import datetime
|
import datetime
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from aiohomekit.testing import FakeController
|
from aiohomekit.model import Transport
|
||||||
|
from aiohomekit.testing import FakeController, FakeDiscovery, FakePairing
|
||||||
|
from bleak.backends.device import BLEDevice
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
from freezegun.api import FrozenDateTimeFactory
|
from freezegun.api import FrozenDateTimeFactory
|
||||||
import pytest
|
import pytest
|
||||||
@ -57,3 +59,31 @@ def get_next_aid() -> Generator[Callable[[], int]]:
|
|||||||
return id_counter
|
return id_counter
|
||||||
|
|
||||||
return _get_id
|
return _get_id
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fake_ble_discovery() -> Generator[None]:
|
||||||
|
"""Fake BLE discovery."""
|
||||||
|
|
||||||
|
class FakeBLEDiscovery(FakeDiscovery):
|
||||||
|
device = BLEDevice(
|
||||||
|
address="AA:BB:CC:DD:EE:FF", name="TestDevice", rssi=-50, details=()
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch("aiohomekit.testing.FakeDiscovery", FakeBLEDiscovery):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def fake_ble_pairing() -> Generator[None]:
|
||||||
|
"""Fake BLE pairing."""
|
||||||
|
|
||||||
|
class FakeBLEPairing(FakePairing):
|
||||||
|
"""Fake BLE pairing."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def transport(self):
|
||||||
|
return Transport.BLE
|
||||||
|
|
||||||
|
with patch("aiohomekit.testing.FakePairing", FakeBLEPairing):
|
||||||
|
yield
|
||||||
|
@ -174,6 +174,7 @@ async def test_offline_device_raises(
|
|||||||
assert hass.states.get("light.testdevice").state == STATE_OFF
|
assert hass.states.get("light.testdevice").state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("fake_ble_discovery")
|
||||||
async def test_ble_device_only_checks_is_available(
|
async def test_ble_device_only_checks_is_available(
|
||||||
hass: HomeAssistant, get_next_aid: Callable[[], int], controller
|
hass: HomeAssistant, get_next_aid: Callable[[], int], controller
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -242,6 +243,34 @@ async def test_ble_device_only_checks_is_available(
|
|||||||
assert hass.states.get("light.testdevice").state == STATE_OFF
|
assert hass.states.get("light.testdevice").state == STATE_OFF
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("fake_ble_discovery", "fake_ble_pairing")
|
||||||
|
async def test_ble_device_populates_connections(
|
||||||
|
hass: HomeAssistant, get_next_aid: Callable[[], int], controller
|
||||||
|
) -> None:
|
||||||
|
"""Test a BLE device populates connections in the device registry."""
|
||||||
|
aid = get_next_aid()
|
||||||
|
|
||||||
|
accessory = Accessory.create_with_info(
|
||||||
|
aid, "TestDevice", "example.com", "Test", "0001", "0.1"
|
||||||
|
)
|
||||||
|
create_alive_service(accessory)
|
||||||
|
|
||||||
|
await async_setup_component(hass, DOMAIN, {})
|
||||||
|
config_entry, _ = await setup_test_accessories_with_controller(
|
||||||
|
hass, [accessory], controller
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
dev_reg = dr.async_get(hass)
|
||||||
|
assert (
|
||||||
|
dev_reg.async_get_device(
|
||||||
|
identifiers={}, connections={("bluetooth", "AA:BB:CC:DD:EE:FF")}
|
||||||
|
)
|
||||||
|
is not None
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("example", FIXTURES, ids=lambda val: str(val.stem))
|
@pytest.mark.parametrize("example", FIXTURES, ids=lambda val: str(val.stem))
|
||||||
async def test_snapshots(
|
async def test_snapshots(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
"""Basic checks for HomeKit sensor."""
|
"""Basic checks for HomeKit sensor."""
|
||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from aiohomekit.model import Accessory, Transport
|
from aiohomekit.model import Accessory
|
||||||
from aiohomekit.model.characteristics import CharacteristicsTypes
|
from aiohomekit.model.characteristics import CharacteristicsTypes
|
||||||
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
|
from aiohomekit.model.characteristics.const import ThreadNodeCapabilities, ThreadStatus
|
||||||
from aiohomekit.model.services import Service, ServicesTypes
|
from aiohomekit.model.services import Service, ServicesTypes
|
||||||
from aiohomekit.protocol.statuscodes import HapStatusCode
|
from aiohomekit.protocol.statuscodes import HapStatusCode
|
||||||
from aiohomekit.testing import FakePairing
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.homekit_controller.sensor import (
|
from homeassistant.components.homekit_controller.sensor import (
|
||||||
@ -406,21 +404,18 @@ def test_thread_status_to_str() -> None:
|
|||||||
assert thread_status_to_str(ThreadStatus.DISABLED) == "disabled"
|
assert thread_status_to_str(ThreadStatus.DISABLED) == "disabled"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("enable_bluetooth", "entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures(
|
||||||
|
"enable_bluetooth",
|
||||||
|
"entity_registry_enabled_by_default",
|
||||||
|
"fake_ble_discovery",
|
||||||
|
"fake_ble_pairing",
|
||||||
|
)
|
||||||
async def test_rssi_sensor(
|
async def test_rssi_sensor(
|
||||||
hass: HomeAssistant, get_next_aid: Callable[[], int]
|
hass: HomeAssistant, get_next_aid: Callable[[], int]
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test an rssi sensor."""
|
"""Test an rssi sensor."""
|
||||||
inject_bluetooth_service_info(hass, TEST_DEVICE_SERVICE_INFO)
|
inject_bluetooth_service_info(hass, TEST_DEVICE_SERVICE_INFO)
|
||||||
|
|
||||||
class FakeBLEPairing(FakePairing):
|
|
||||||
"""Fake BLE pairing."""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def transport(self):
|
|
||||||
return Transport.BLE
|
|
||||||
|
|
||||||
with patch("aiohomekit.testing.FakePairing", FakeBLEPairing):
|
|
||||||
# Any accessory will do for this test, but we need at least
|
# Any accessory will do for this test, but we need at least
|
||||||
# one or the rssi sensor will not be created
|
# one or the rssi sensor will not be created
|
||||||
await setup_test_component(
|
await setup_test_component(
|
||||||
@ -433,7 +428,12 @@ async def test_rssi_sensor(
|
|||||||
assert hass.states.get("sensor.testdevice_signal_strength").state == "-56"
|
assert hass.states.get("sensor.testdevice_signal_strength").state == "-56"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("enable_bluetooth", "entity_registry_enabled_by_default")
|
@pytest.mark.usefixtures(
|
||||||
|
"enable_bluetooth",
|
||||||
|
"entity_registry_enabled_by_default",
|
||||||
|
"fake_ble_discovery",
|
||||||
|
"fake_ble_pairing",
|
||||||
|
)
|
||||||
async def test_migrate_rssi_sensor_unique_id(
|
async def test_migrate_rssi_sensor_unique_id(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity_registry: er.EntityRegistry,
|
entity_registry: er.EntityRegistry,
|
||||||
@ -449,14 +449,6 @@ async def test_migrate_rssi_sensor_unique_id(
|
|||||||
|
|
||||||
inject_bluetooth_service_info(hass, TEST_DEVICE_SERVICE_INFO)
|
inject_bluetooth_service_info(hass, TEST_DEVICE_SERVICE_INFO)
|
||||||
|
|
||||||
class FakeBLEPairing(FakePairing):
|
|
||||||
"""Fake BLE pairing."""
|
|
||||||
|
|
||||||
@property
|
|
||||||
def transport(self):
|
|
||||||
return Transport.BLE
|
|
||||||
|
|
||||||
with patch("aiohomekit.testing.FakePairing", FakeBLEPairing):
|
|
||||||
# Any accessory will do for this test, but we need at least
|
# Any accessory will do for this test, but we need at least
|
||||||
# one or the rssi sensor will not be created
|
# one or the rssi sensor will not be created
|
||||||
await setup_test_component(
|
await setup_test_component(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user