Move gardena_bluetooth base entity to separate module (#126484)

This commit is contained in:
epenet 2024-09-23 13:06:10 +02:00 committed by GitHub
parent fb400af7d2
commit 14bc65e8e7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 73 additions and 72 deletions

View file

@ -18,7 +18,7 @@ from homeassistant.helpers.device_registry import DeviceInfo
import homeassistant.util.dt as dt_util
from .const import DOMAIN
from .coordinator import Coordinator, DeviceUnavailable
from .coordinator import DeviceUnavailable, GardenaBluetoothCoordinator
PLATFORMS: list[Platform] = [
Platform.BINARY_SENSOR,
@ -75,7 +75,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
model=model,
)
coordinator = Coordinator(hass, LOGGER, client, uuids, device, address)
coordinator = GardenaBluetoothCoordinator(
hass, LOGGER, client, uuids, device, address
)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@ -87,7 +89,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
coordinator: Coordinator = hass.data[DOMAIN].pop(entry.entry_id)
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN].pop(entry.entry_id)
await coordinator.async_shutdown()
return unload_ok

View file

@ -18,7 +18,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import Coordinator, GardenaBluetoothDescriptorEntity
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothDescriptorEntity
@dataclass(frozen=True)
@ -55,7 +56,7 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up binary sensor based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities = [
GardenaBluetoothBinarySensor(coordinator, description, description.context)
for description in DESCRIPTIONS

View file

@ -14,7 +14,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import Coordinator, GardenaBluetoothDescriptorEntity
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothDescriptorEntity
@dataclass(frozen=True)
@ -44,7 +45,7 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up button based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities = [
GardenaBluetoothButton(coordinator, description, description.context)
for description in DESCRIPTIONS

View file

@ -4,7 +4,6 @@ from __future__ import annotations
from datetime import timedelta
import logging
from typing import Any
from gardena_bluetooth.client import Client
from gardena_bluetooth.exceptions import (
@ -16,12 +15,7 @@ from gardena_bluetooth.parse import Characteristic, CharacteristicType
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
DataUpdateCoordinator,
UpdateFailed,
)
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
SCAN_INTERVAL = timedelta(seconds=60)
LOGGER = logging.getLogger(__name__)
@ -31,7 +25,7 @@ class DeviceUnavailable(HomeAssistantError):
"""Raised if device can't be found."""
class Coordinator(DataUpdateCoordinator[dict[str, bytes]]):
class GardenaBluetoothCoordinator(DataUpdateCoordinator[dict[str, bytes]]):
"""Class to manage fetching data."""
def __init__(
@ -102,34 +96,3 @@ class Coordinator(DataUpdateCoordinator[dict[str, bytes]]):
self.data[char.uuid] = char.encode(value)
await self.async_refresh()
class GardenaBluetoothEntity(CoordinatorEntity[Coordinator]):
"""Coordinator entity for Gardena Bluetooth."""
_attr_has_entity_name = True
def __init__(self, coordinator: Coordinator, context: Any = None) -> None:
"""Initialize coordinator entity."""
super().__init__(coordinator, context)
self._attr_device_info = coordinator.device_info
@property
def available(self) -> bool:
"""Return if entity is available."""
return self.coordinator.last_update_success and self._attr_available
class GardenaBluetoothDescriptorEntity(GardenaBluetoothEntity):
"""Coordinator entity for entities with entity description."""
def __init__(
self,
coordinator: Coordinator,
description: EntityDescription,
context: set[str],
) -> None:
"""Initialize description entity."""
super().__init__(coordinator, context)
self._attr_unique_id = f"{coordinator.address}-{description.key}"
self.entity_description = description

View file

@ -0,0 +1,43 @@
"""Provides the DataUpdateCoordinator."""
from __future__ import annotations
from typing import Any
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .coordinator import GardenaBluetoothCoordinator
class GardenaBluetoothEntity(CoordinatorEntity[GardenaBluetoothCoordinator]):
"""Coordinator entity for Gardena Bluetooth."""
_attr_has_entity_name = True
def __init__(
self, coordinator: GardenaBluetoothCoordinator, context: Any = None
) -> None:
"""Initialize coordinator entity."""
super().__init__(coordinator, context)
self._attr_device_info = coordinator.device_info
@property
def available(self) -> bool:
"""Return if entity is available."""
return self.coordinator.last_update_success and self._attr_available
class GardenaBluetoothDescriptorEntity(GardenaBluetoothEntity):
"""Coordinator entity for entities with entity description."""
def __init__(
self,
coordinator: GardenaBluetoothCoordinator,
description: EntityDescription,
context: set[str],
) -> None:
"""Initialize description entity."""
super().__init__(coordinator, context)
self._attr_unique_id = f"{coordinator.address}-{description.key}"
self.entity_description = description

View file

@ -23,11 +23,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import (
Coordinator,
GardenaBluetoothDescriptorEntity,
GardenaBluetoothEntity,
)
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothDescriptorEntity, GardenaBluetoothEntity
@dataclass(frozen=True)
@ -111,7 +108,7 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up entity based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[NumberEntity] = [
GardenaBluetoothNumber(coordinator, description, description.context)
for description in DESCRIPTIONS
@ -159,7 +156,7 @@ class GardenaBluetoothRemainingOpenSetNumber(GardenaBluetoothEntity, NumberEntit
def __init__(
self,
coordinator: Coordinator,
coordinator: GardenaBluetoothCoordinator,
) -> None:
"""Initialize the remaining time entity."""
super().__init__(coordinator, {Valve.remaining_open_time.uuid})

View file

@ -21,11 +21,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
import homeassistant.util.dt as dt_util
from .const import DOMAIN
from .coordinator import (
Coordinator,
GardenaBluetoothDescriptorEntity,
GardenaBluetoothEntity,
)
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothDescriptorEntity, GardenaBluetoothEntity
@dataclass(frozen=True)
@ -101,7 +98,7 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up Gardena Bluetooth sensor based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities: list[GardenaBluetoothEntity] = [
GardenaBluetoothSensor(coordinator, description, description.context)
for description in DESCRIPTIONS
@ -140,7 +137,7 @@ class GardenaBluetoothRemainSensor(GardenaBluetoothEntity, SensorEntity):
def __init__(
self,
coordinator: Coordinator,
coordinator: GardenaBluetoothCoordinator,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator, {Valve.remaining_open_time.uuid})

View file

@ -13,14 +13,15 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import Coordinator, GardenaBluetoothEntity
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothEntity
async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up switch based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities = []
if GardenaBluetoothValveSwitch.characteristics.issubset(
coordinator.characteristics
@ -41,7 +42,7 @@ class GardenaBluetoothValveSwitch(GardenaBluetoothEntity, SwitchEntity):
def __init__(
self,
coordinator: Coordinator,
coordinator: GardenaBluetoothCoordinator,
) -> None:
"""Initialize the switch."""
super().__init__(

View file

@ -12,7 +12,8 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import Coordinator, GardenaBluetoothEntity
from .coordinator import GardenaBluetoothCoordinator
from .entity import GardenaBluetoothEntity
FALLBACK_WATERING_TIME_IN_SECONDS = 60 * 60
@ -21,7 +22,7 @@ async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up switch based on a config entry."""
coordinator: Coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator: GardenaBluetoothCoordinator = hass.data[DOMAIN][entry.entry_id]
entities = []
if GardenaBluetoothValve.characteristics.issubset(coordinator.characteristics):
entities.append(GardenaBluetoothValve(coordinator))
@ -45,7 +46,7 @@ class GardenaBluetoothValve(GardenaBluetoothEntity, ValveEntity):
def __init__(
self,
coordinator: Coordinator,
coordinator: GardenaBluetoothCoordinator,
) -> None:
"""Initialize the switch."""
super().__init__(

View file

@ -112,10 +112,5 @@ def mock_client(
@pytest.fixture(autouse=True)
def enable_all_entities():
def enable_all_entities(entity_registry_enabled_by_default: None) -> None:
"""Make sure all entities are enabled."""
with patch(
"homeassistant.components.gardena_bluetooth.coordinator.GardenaBluetoothEntity.entity_registry_enabled_default",
new=Mock(return_value=True),
):
yield