mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Move BluetoothServiceInfoBleak to home_assistant_bluetooth (#82064)
This commit is contained in:
parent
c940ad9920
commit
682187541f
@ -3,7 +3,6 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Callable, Iterable
|
||||
from dataclasses import replace
|
||||
from datetime import datetime, timedelta
|
||||
import itertools
|
||||
import logging
|
||||
@ -442,7 +441,19 @@ class BluetoothManager:
|
||||
# route any connection attempts to the connectable path, we
|
||||
# mark the service_info as connectable so that the callbacks
|
||||
# will be called and the device can be discovered.
|
||||
service_info = replace(service_info, connectable=True)
|
||||
service_info = BluetoothServiceInfoBleak(
|
||||
name=service_info.name,
|
||||
address=service_info.address,
|
||||
rssi=service_info.rssi,
|
||||
manufacturer_data=service_info.manufacturer_data,
|
||||
service_data=service_info.service_data,
|
||||
service_uuids=service_info.service_uuids,
|
||||
source=service_info.source,
|
||||
device=service_info.device,
|
||||
advertisement=service_info.advertisement,
|
||||
connectable=True,
|
||||
time=service_info.time,
|
||||
)
|
||||
|
||||
matched_domains = self._integration_matcher.match_domains(service_info)
|
||||
_LOGGER.debug(
|
||||
|
@ -21,11 +21,14 @@ from bleak.backends.scanner import (
|
||||
BaseBleakScanner,
|
||||
)
|
||||
from bleak_retry_connector import NO_RSSI_VALUE, freshen_ble_device
|
||||
from home_assistant_bluetooth import BluetoothServiceInfoBleak
|
||||
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback as hass_callback
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.frame import report
|
||||
from homeassistant.helpers.service_info.bluetooth import BluetoothServiceInfo
|
||||
from homeassistant.helpers.service_info.bluetooth import ( # noqa: F401 # pylint: disable=unused-import
|
||||
BluetoothServiceInfo,
|
||||
)
|
||||
from homeassistant.util.dt import monotonic_time_coarse
|
||||
|
||||
from .const import FALLBACK_MAXIMUM_STALE_ADVERTISEMENT_SECONDS
|
||||
@ -53,41 +56,6 @@ MANAGER: BluetoothManager | None = None
|
||||
MONOTONIC_TIME: Final = monotonic_time_coarse
|
||||
|
||||
|
||||
@dataclass
|
||||
class BluetoothServiceInfoBleak(BluetoothServiceInfo):
|
||||
"""BluetoothServiceInfo with bleak data.
|
||||
|
||||
Integrations may need BLEDevice and AdvertisementData
|
||||
to connect to the device without having bleak trigger
|
||||
another scan to translate the address to the system's
|
||||
internal details.
|
||||
"""
|
||||
|
||||
device: BLEDevice
|
||||
advertisement: AdvertisementData
|
||||
connectable: bool
|
||||
time: float
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
"""Return as dict.
|
||||
|
||||
The dataclass asdict method is not used because
|
||||
it will try to deepcopy pyobjc data which will fail.
|
||||
"""
|
||||
return {
|
||||
"name": self.name,
|
||||
"address": self.address,
|
||||
"rssi": self.rssi,
|
||||
"manufacturer_data": self.manufacturer_data,
|
||||
"service_data": self.service_data,
|
||||
"service_uuids": self.service_uuids,
|
||||
"source": self.source,
|
||||
"advertisement": self.advertisement,
|
||||
"connectable": self.connectable,
|
||||
"time": self.time,
|
||||
}
|
||||
|
||||
|
||||
class BluetoothScanningMode(Enum):
|
||||
"""The mode of scanning for bluetooth devices."""
|
||||
|
||||
|
@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
|
||||
from abc import abstractmethod
|
||||
import logging
|
||||
from typing import cast
|
||||
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
|
||||
|
||||
@ -69,7 +70,7 @@ class BasePassiveBluetoothCoordinator:
|
||||
if service_info := async_last_service_info(
|
||||
self.hass, self.address, self.connectable
|
||||
):
|
||||
return service_info.name
|
||||
return cast(str, service_info.name) # for compat this can be a pyobjc
|
||||
return self._last_name
|
||||
|
||||
@property
|
||||
|
@ -62,7 +62,7 @@ def async_name(
|
||||
"""Return a name for the device."""
|
||||
if service_info.address in (
|
||||
service_info.name,
|
||||
service_info.name.replace("_", ":"),
|
||||
service_info.name.replace("-", ":"),
|
||||
):
|
||||
base_name = f"{ibeacon_advertisement.uuid}_{ibeacon_advertisement.major}_{ibeacon_advertisement.minor}"
|
||||
else:
|
||||
|
@ -21,7 +21,7 @@ cryptography==38.0.3
|
||||
dbus-fast==1.74.0
|
||||
fnvhash==0.1.0
|
||||
hass-nabucasa==0.56.0
|
||||
home-assistant-bluetooth==1.6.0
|
||||
home-assistant-bluetooth==1.8.0
|
||||
home-assistant-frontend==20221108.0
|
||||
httpx==0.23.0
|
||||
ifaddr==0.1.7
|
||||
|
@ -36,7 +36,7 @@ dependencies = [
|
||||
# When bumping httpx, please check the version pins of
|
||||
# httpcore, anyio, and h11 in gen_requirements_all
|
||||
"httpx==0.23.0",
|
||||
"home-assistant-bluetooth==1.6.0",
|
||||
"home-assistant-bluetooth==1.8.0",
|
||||
"ifaddr==0.1.7",
|
||||
"jinja2==3.1.2",
|
||||
"lru-dict==1.1.8",
|
||||
|
@ -11,7 +11,7 @@ bcrypt==3.1.7
|
||||
certifi>=2021.5.30
|
||||
ciso8601==2.2.0
|
||||
httpx==0.23.0
|
||||
home-assistant-bluetooth==1.6.0
|
||||
home-assistant-bluetooth==1.8.0
|
||||
ifaddr==0.1.7
|
||||
jinja2==3.1.2
|
||||
lru-dict==1.1.8
|
||||
|
@ -227,6 +227,10 @@ async def test_diagnostics_macos(
|
||||
-127,
|
||||
[[]],
|
||||
],
|
||||
"device": {
|
||||
"__type": "<class " "'bleak.backends.device.BLEDevice'>",
|
||||
"repr": "BLEDevice(44:44:33:11:23:45, " "wohand)",
|
||||
},
|
||||
"connectable": True,
|
||||
"manufacturer_data": {
|
||||
"1": {"__type": "<class " "'bytes'>", "repr": "b'\\x01'"}
|
||||
@ -251,6 +255,10 @@ async def test_diagnostics_macos(
|
||||
-127,
|
||||
[[]],
|
||||
],
|
||||
"device": {
|
||||
"__type": "<class " "'bleak.backends.device.BLEDevice'>",
|
||||
"repr": "BLEDevice(44:44:33:11:23:45, " "wohand)",
|
||||
},
|
||||
"connectable": True,
|
||||
"manufacturer_data": {
|
||||
"1": {"__type": "<class " "'bytes'>", "repr": "b'\\x01'"}
|
||||
|
@ -1,4 +1,6 @@
|
||||
"""Tests for the ibeacon integration."""
|
||||
from typing import Any
|
||||
|
||||
from bleak.backends.device import BLEDevice
|
||||
|
||||
from homeassistant.helpers.service_info.bluetooth import BluetoothServiceInfo
|
||||
@ -115,3 +117,18 @@ FEASY_BEACON_SERVICE_INFO_2 = BluetoothServiceInfo(
|
||||
],
|
||||
source="local",
|
||||
)
|
||||
|
||||
|
||||
def bluetooth_service_info_replace(
|
||||
info: BluetoothServiceInfo, **kwargs: Any
|
||||
) -> BluetoothServiceInfo:
|
||||
"""Replace attributes of a BluetoothServiceInfoBleak."""
|
||||
return BluetoothServiceInfo(
|
||||
address=kwargs.get("address", info.address),
|
||||
name=kwargs.get("name", info.name),
|
||||
rssi=kwargs.get("rssi", info.rssi),
|
||||
manufacturer_data=kwargs.get("manufacturer_data", info.manufacturer_data),
|
||||
service_data=kwargs.get("service_data", info.service_data),
|
||||
service_uuids=kwargs.get("service_uuids", info.service_uuids),
|
||||
source=kwargs.get("source", info.source),
|
||||
)
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""Test the ibeacon sensors."""
|
||||
|
||||
|
||||
from dataclasses import replace
|
||||
from datetime import timedelta
|
||||
import time
|
||||
|
||||
@ -19,6 +18,7 @@ from . import (
|
||||
BLUECHARM_BEACON_SERVICE_INFO_DBUS,
|
||||
TESLA_TRANSIENT,
|
||||
TESLA_TRANSIENT_BLE_DEVICE,
|
||||
bluetooth_service_info_replace as replace,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
@ -145,16 +145,17 @@ async def test_ignore_default_name(hass):
|
||||
assert len(hass.states.async_entity_ids()) == before_entity_count
|
||||
|
||||
|
||||
async def test_rotating_major_minor_and_mac(hass):
|
||||
async def test_rotating_major_minor_and_mac_with_name(hass):
|
||||
"""Test the different uuid, major, minor from many addresses removes all associated entities."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
before_entity_count = len(hass.states.async_entity_ids("device_tracker"))
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
before_entity_count = len(hass.states.async_entity_ids("device_tracker"))
|
||||
|
||||
for i in range(100):
|
||||
service_info = BluetoothServiceInfo(
|
||||
name="BlueCharm_177999",
|
||||
@ -186,9 +187,10 @@ async def test_rotating_major_minor_and_mac_no_name(hass):
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
before_entity_count = len(hass.states.async_entity_ids("device_tracker"))
|
||||
assert await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
before_entity_count = len(hass.states.async_entity_ids("device_tracker"))
|
||||
|
||||
for i in range(51):
|
||||
service_info = BluetoothServiceInfo(
|
||||
name=f"AA:BB:CC:DD:EE:{i:02X}",
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""Test the ibeacon device trackers."""
|
||||
|
||||
|
||||
from dataclasses import replace
|
||||
from datetime import timedelta
|
||||
import time
|
||||
from unittest.mock import patch
|
||||
@ -22,6 +21,7 @@ from . import (
|
||||
BEACON_RANDOM_ADDRESS_SERVICE_INFO,
|
||||
BLUECHARM_BEACON_SERVICE_INFO,
|
||||
BLUECHARM_BLE_DEVICE,
|
||||
bluetooth_service_info_replace as replace,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
@ -1,7 +1,6 @@
|
||||
"""Test the ibeacon sensors."""
|
||||
|
||||
|
||||
from dataclasses import replace
|
||||
from datetime import timedelta
|
||||
|
||||
import pytest
|
||||
@ -24,6 +23,7 @@ from . import (
|
||||
FEASY_BEACON_SERVICE_INFO_1,
|
||||
FEASY_BEACON_SERVICE_INFO_2,
|
||||
NO_NAME_BEACON_SERVICE_INFO,
|
||||
bluetooth_service_info_replace as replace,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
Loading…
x
Reference in New Issue
Block a user