From 626935ee14b85ca23ab6be32d566eaf2347a2334 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 8 Apr 2025 04:59:01 -1000 Subject: [PATCH] Move inkbird coordinator logic into coordinator.py (#142517) * Move inkbird coordinator logic into coordinator.py Not a functional change, one to one relocation * Move inkbird coordinator logic into coordinator.py Not a functional change, one to one copy * Move inkbird coordinator logic into coordinator.py Not a functional change, one to one copy --- homeassistant/components/inkbird/__init__.py | 95 +---------------- .../components/inkbird/coordinator.py | 100 ++++++++++++++++++ tests/components/inkbird/test_sensor.py | 2 +- 3 files changed, 104 insertions(+), 93 deletions(-) create mode 100644 homeassistant/components/inkbird/coordinator.py diff --git a/homeassistant/components/inkbird/__init__.py b/homeassistant/components/inkbird/__init__.py index 467fa2445e8..738d412d849 100644 --- a/homeassistant/components/inkbird/__init__.py +++ b/homeassistant/components/inkbird/__init__.py @@ -2,106 +2,17 @@ from __future__ import annotations -from datetime import datetime, timedelta -import logging +from inkbird_ble import INKBIRDBluetoothDeviceData -from inkbird_ble import INKBIRDBluetoothDeviceData, SensorUpdate - -from homeassistant.components.bluetooth import ( - BluetoothScanningMode, - BluetoothServiceInfo, - BluetoothServiceInfoBleak, - async_ble_device_from_address, -) -from homeassistant.components.bluetooth.active_update_processor import ( - ActiveBluetoothProcessorCoordinator, -) from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform -from homeassistant.core import HomeAssistant, callback -from homeassistant.helpers.event import async_track_time_interval +from homeassistant.core import HomeAssistant from .const import CONF_DEVICE_TYPE, DOMAIN +from .coordinator import INKBIRDActiveBluetoothProcessorCoordinator PLATFORMS: list[Platform] = [Platform.SENSOR] -_LOGGER = logging.getLogger(__name__) - -FALLBACK_POLL_INTERVAL = timedelta(seconds=180) - - -class INKBIRDActiveBluetoothProcessorCoordinator(ActiveBluetoothProcessorCoordinator): - """Coordinator for INKBIRD Bluetooth devices.""" - - def __init__( - self, - hass: HomeAssistant, - entry: ConfigEntry, - data: INKBIRDBluetoothDeviceData, - ) -> None: - """Initialize the INKBIRD Bluetooth processor coordinator.""" - self._data = data - self._entry = entry - address = entry.unique_id - assert address is not None - entry.async_on_unload( - async_track_time_interval( - hass, self._async_schedule_poll, FALLBACK_POLL_INTERVAL - ) - ) - super().__init__( - hass=hass, - logger=_LOGGER, - address=address, - mode=BluetoothScanningMode.ACTIVE, - update_method=self._async_on_update, - needs_poll_method=self._async_needs_poll, - poll_method=self._async_poll_data, - ) - - async def _async_poll_data( - self, last_service_info: BluetoothServiceInfoBleak - ) -> SensorUpdate: - """Poll the device.""" - return await self._data.async_poll(last_service_info.device) - - @callback - def _async_needs_poll( - self, service_info: BluetoothServiceInfoBleak, last_poll: float | None - ) -> bool: - return ( - not self.hass.is_stopping - and self._data.poll_needed(service_info, last_poll) - and bool( - async_ble_device_from_address( - self.hass, service_info.device.address, connectable=True - ) - ) - ) - - @callback - def _async_on_update(self, service_info: BluetoothServiceInfo) -> SensorUpdate: - """Handle update callback from the passive BLE processor.""" - update = self._data.update(service_info) - if ( - self._entry.data.get(CONF_DEVICE_TYPE) is None - and self._data.device_type is not None - ): - device_type_str = str(self._data.device_type) - self.hass.config_entries.async_update_entry( - self._entry, - data={**self._entry.data, CONF_DEVICE_TYPE: device_type_str}, - ) - return update - - @callback - def _async_schedule_poll(self, _: datetime) -> None: - """Schedule a poll of the device.""" - if self._last_service_info and self._async_needs_poll( - self._last_service_info, self._last_poll - ): - self._debounced_poll.async_schedule_call() - async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up INKBIRD BLE device from a config entry.""" diff --git a/homeassistant/components/inkbird/coordinator.py b/homeassistant/components/inkbird/coordinator.py new file mode 100644 index 00000000000..bcd519b32aa --- /dev/null +++ b/homeassistant/components/inkbird/coordinator.py @@ -0,0 +1,100 @@ +"""The INKBIRD Bluetooth integration.""" + +from __future__ import annotations + +from datetime import datetime, timedelta +import logging + +from inkbird_ble import INKBIRDBluetoothDeviceData, SensorUpdate + +from homeassistant.components.bluetooth import ( + BluetoothScanningMode, + BluetoothServiceInfo, + BluetoothServiceInfoBleak, + async_ble_device_from_address, +) +from homeassistant.components.bluetooth.active_update_processor import ( + ActiveBluetoothProcessorCoordinator, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.event import async_track_time_interval + +from .const import CONF_DEVICE_TYPE + +_LOGGER = logging.getLogger(__name__) + +FALLBACK_POLL_INTERVAL = timedelta(seconds=180) + + +class INKBIRDActiveBluetoothProcessorCoordinator(ActiveBluetoothProcessorCoordinator): + """Coordinator for INKBIRD Bluetooth devices.""" + + def __init__( + self, + hass: HomeAssistant, + entry: ConfigEntry, + data: INKBIRDBluetoothDeviceData, + ) -> None: + """Initialize the INKBIRD Bluetooth processor coordinator.""" + self._data = data + self._entry = entry + address = entry.unique_id + assert address is not None + entry.async_on_unload( + async_track_time_interval( + hass, self._async_schedule_poll, FALLBACK_POLL_INTERVAL + ) + ) + super().__init__( + hass=hass, + logger=_LOGGER, + address=address, + mode=BluetoothScanningMode.ACTIVE, + update_method=self._async_on_update, + needs_poll_method=self._async_needs_poll, + poll_method=self._async_poll_data, + ) + + async def _async_poll_data( + self, last_service_info: BluetoothServiceInfoBleak + ) -> SensorUpdate: + """Poll the device.""" + return await self._data.async_poll(last_service_info.device) + + @callback + def _async_needs_poll( + self, service_info: BluetoothServiceInfoBleak, last_poll: float | None + ) -> bool: + return ( + not self.hass.is_stopping + and self._data.poll_needed(service_info, last_poll) + and bool( + async_ble_device_from_address( + self.hass, service_info.device.address, connectable=True + ) + ) + ) + + @callback + def _async_on_update(self, service_info: BluetoothServiceInfo) -> SensorUpdate: + """Handle update callback from the passive BLE processor.""" + update = self._data.update(service_info) + if ( + self._entry.data.get(CONF_DEVICE_TYPE) is None + and self._data.device_type is not None + ): + device_type_str = str(self._data.device_type) + self.hass.config_entries.async_update_entry( + self._entry, + data={**self._entry.data, CONF_DEVICE_TYPE: device_type_str}, + ) + return update + + @callback + def _async_schedule_poll(self, _: datetime) -> None: + """Schedule a poll of the device.""" + if self._last_service_info and self._async_needs_poll( + self._last_service_info, self._last_poll + ): + self._debounced_poll.async_schedule_call() diff --git a/tests/components/inkbird/test_sensor.py b/tests/components/inkbird/test_sensor.py index 00b76366b48..67e08396c79 100644 --- a/tests/components/inkbird/test_sensor.py +++ b/tests/components/inkbird/test_sensor.py @@ -12,8 +12,8 @@ from inkbird_ble import ( ) from sensor_state_data import SensorDeviceClass -from homeassistant.components.inkbird import FALLBACK_POLL_INTERVAL from homeassistant.components.inkbird.const import CONF_DEVICE_TYPE, DOMAIN +from homeassistant.components.inkbird.coordinator import FALLBACK_POLL_INTERVAL from homeassistant.components.sensor import ATTR_STATE_CLASS from homeassistant.const import ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT from homeassistant.core import HomeAssistant