diff --git a/homeassistant/components/bthome/__init__.py b/homeassistant/components/bthome/__init__.py index 6f17adeeca7..f5e634b774d 100644 --- a/homeassistant/components/bthome/__init__.py +++ b/homeassistant/components/bthome/__init__.py @@ -2,6 +2,7 @@ from __future__ import annotations +from functools import partial import logging from bthome_ble import BTHomeBluetoothDeviceData, SensorUpdate @@ -12,7 +13,6 @@ from homeassistant.components.bluetooth import ( BluetoothScanningMode, BluetoothServiceInfoBleak, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant from homeassistant.helpers import device_registry as dr @@ -29,6 +29,7 @@ from .const import ( BTHomeBleEvent, ) from .coordinator import BTHomePassiveBluetoothProcessorCoordinator +from .types import BTHomeConfigEntry PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.EVENT, Platform.SENSOR] @@ -37,16 +38,14 @@ _LOGGER = logging.getLogger(__name__) def process_service_info( hass: HomeAssistant, - entry: ConfigEntry, - data: BTHomeBluetoothDeviceData, - service_info: BluetoothServiceInfoBleak, + entry: BTHomeConfigEntry, device_registry: DeviceRegistry, + service_info: BluetoothServiceInfoBleak, ) -> SensorUpdate: """Process a BluetoothServiceInfoBleak, running side effects and returning sensor data.""" + coordinator = entry.runtime_data + data = coordinator.device_data update = data.update(service_info) - coordinator: BTHomePassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ - entry.entry_id - ] discovered_event_classes = coordinator.discovered_event_classes if entry.data.get(CONF_SLEEPY_DEVICE, False) != data.sleepy_device: hass.config_entries.async_update_entry( @@ -117,7 +116,7 @@ def format_discovered_event_class(address: str) -> SignalType[str, BTHomeBleEven return SignalType(f"{DOMAIN}_discovered_event_class_{address}") -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: BTHomeConfigEntry) -> bool: """Set up BTHome Bluetooth from a config entry.""" address = entry.unique_id assert address is not None @@ -128,34 +127,26 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: data = BTHomeBluetoothDeviceData(**kwargs) device_registry = dr.async_get(hass) - coordinator = hass.data.setdefault(DOMAIN, {})[entry.entry_id] = ( - BTHomePassiveBluetoothProcessorCoordinator( - hass, - _LOGGER, - address=address, - mode=BluetoothScanningMode.PASSIVE, - update_method=lambda service_info: process_service_info( - hass, entry, data, service_info, device_registry - ), - device_data=data, - discovered_event_classes=set( - entry.data.get(CONF_DISCOVERED_EVENT_CLASSES, []) - ), - connectable=False, - entry=entry, - ) + event_classes = set(entry.data.get(CONF_DISCOVERED_EVENT_CLASSES, ())) + coordinator = BTHomePassiveBluetoothProcessorCoordinator( + hass, + _LOGGER, + address=address, + mode=BluetoothScanningMode.PASSIVE, + update_method=partial(process_service_info, hass, entry, device_registry), + device_data=data, + discovered_event_classes=event_classes, + connectable=False, + entry=entry, ) + entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) - entry.async_on_unload( - coordinator.async_start() - ) # only start after all platforms have had a chance to subscribe + # only start after all platforms have had a chance to subscribe + entry.async_on_unload(coordinator.async_start()) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: BTHomeConfigEntry) -> bool: """Unload a config entry.""" - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/bthome/binary_sensor.py b/homeassistant/components/bthome/binary_sensor.py index 1a311f9f3a4..bcc420df4a8 100644 --- a/homeassistant/components/bthome/binary_sensor.py +++ b/homeassistant/components/bthome/binary_sensor.py @@ -7,7 +7,6 @@ from bthome_ble import ( SensorUpdate, ) -from homeassistant import config_entries from homeassistant.components.binary_sensor import ( BinarySensorDeviceClass, BinarySensorEntity, @@ -21,12 +20,9 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info -from .const import DOMAIN -from .coordinator import ( - BTHomePassiveBluetoothDataProcessor, - BTHomePassiveBluetoothProcessorCoordinator, -) +from .coordinator import BTHomePassiveBluetoothDataProcessor from .device import device_key_to_bluetooth_entity_key +from .types import BTHomeConfigEntry BINARY_SENSOR_DESCRIPTIONS = { BTHomeBinarySensorDeviceClass.BATTERY: BinarySensorEntityDescription( @@ -172,13 +168,11 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, + entry: BTHomeConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the BTHome BLE binary sensors.""" - coordinator: BTHomePassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ - entry.entry_id - ] + coordinator = entry.runtime_data processor = BTHomePassiveBluetoothDataProcessor( sensor_update_to_bluetooth_data_update ) diff --git a/homeassistant/components/bthome/coordinator.py b/homeassistant/components/bthome/coordinator.py index cb2abef6a43..2ef29541f40 100644 --- a/homeassistant/components/bthome/coordinator.py +++ b/homeassistant/components/bthome/coordinator.py @@ -13,10 +13,10 @@ from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothDataProcessor, PassiveBluetoothProcessorCoordinator, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from .const import CONF_SLEEPY_DEVICE +from .types import BTHomeConfigEntry class BTHomePassiveBluetoothProcessorCoordinator( @@ -33,7 +33,7 @@ class BTHomePassiveBluetoothProcessorCoordinator( update_method: Callable[[BluetoothServiceInfoBleak], SensorUpdate], device_data: BTHomeBluetoothDeviceData, discovered_event_classes: set[str], - entry: ConfigEntry, + entry: BTHomeConfigEntry, connectable: bool = False, ) -> None: """Initialize the BTHome Bluetooth Passive Update Processor Coordinator.""" diff --git a/homeassistant/components/bthome/event.py b/homeassistant/components/bthome/event.py index a0f59c0ddb7..128d1e8388f 100644 --- a/homeassistant/components/bthome/event.py +++ b/homeassistant/components/bthome/event.py @@ -9,7 +9,6 @@ from homeassistant.components.event import ( EventEntity, EventEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -24,7 +23,7 @@ from .const import ( EVENT_TYPE, BTHomeBleEvent, ) -from .coordinator import BTHomePassiveBluetoothProcessorCoordinator +from .types import BTHomeConfigEntry DESCRIPTIONS_BY_EVENT_CLASS = { EVENT_CLASS_BUTTON: EventEntityDescription( @@ -103,13 +102,11 @@ class BTHomeEventEntity(EventEntity): async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: BTHomeConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up BTHome event.""" - coordinator: BTHomePassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ - entry.entry_id - ] + coordinator = entry.runtime_data address = coordinator.address ent_reg = er.async_get(hass) async_add_entities( diff --git a/homeassistant/components/bthome/sensor.py b/homeassistant/components/bthome/sensor.py index 2178481b21a..656addad620 100644 --- a/homeassistant/components/bthome/sensor.py +++ b/homeassistant/components/bthome/sensor.py @@ -9,7 +9,6 @@ from bthome_ble.const import ( ExtendedSensorDeviceClass as BTHomeExtendedSensorDeviceClass, ) -from homeassistant import config_entries from homeassistant.components.bluetooth.passive_update_processor import ( PassiveBluetoothDataUpdate, PassiveBluetoothProcessorEntity, @@ -45,12 +44,9 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.sensor import sensor_device_info_to_hass_device_info -from .const import DOMAIN -from .coordinator import ( - BTHomePassiveBluetoothDataProcessor, - BTHomePassiveBluetoothProcessorCoordinator, -) +from .coordinator import BTHomePassiveBluetoothDataProcessor from .device import device_key_to_bluetooth_entity_key +from .types import BTHomeConfigEntry SENSOR_DESCRIPTIONS = { # Acceleration (m/s²) @@ -394,13 +390,11 @@ def sensor_update_to_bluetooth_data_update( async def async_setup_entry( hass: HomeAssistant, - entry: config_entries.ConfigEntry, + entry: BTHomeConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the BTHome BLE sensors.""" - coordinator: BTHomePassiveBluetoothProcessorCoordinator = hass.data[DOMAIN][ - entry.entry_id - ] + coordinator = entry.runtime_data processor = BTHomePassiveBluetoothDataProcessor( sensor_update_to_bluetooth_data_update ) diff --git a/homeassistant/components/bthome/types.py b/homeassistant/components/bthome/types.py new file mode 100644 index 00000000000..f89caa22b10 --- /dev/null +++ b/homeassistant/components/bthome/types.py @@ -0,0 +1,10 @@ +"""The BTHome Bluetooth integration.""" + +from typing import TYPE_CHECKING + +from homeassistant.config_entries import ConfigEntry + +if TYPE_CHECKING: + from .coordinator import BTHomePassiveBluetoothProcessorCoordinator + +type BTHomeConfigEntry = ConfigEntry[BTHomePassiveBluetoothProcessorCoordinator]