Bump deebot-client to 8.0.0 (#119515)

Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
Robert Resch 2024-06-13 11:49:20 +02:00 committed by GitHub
parent d211af75ef
commit f5b86154b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 100 additions and 160 deletions

View File

@ -4,7 +4,7 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Generic from typing import Generic
from deebot_client.capabilities import CapabilityEvent, VacuumCapabilities from deebot_client.capabilities import CapabilityEvent
from deebot_client.events.water_info import WaterInfoEvent from deebot_client.events.water_info import WaterInfoEvent
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
@ -16,12 +16,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .entity import ( from .entity import EcovacsCapabilityEntityDescription, EcovacsDescriptionEntity, EventT
CapabilityDevice,
EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity,
EventT,
)
from .util import get_supported_entitites from .util import get_supported_entitites
@ -38,7 +33,6 @@ class EcovacsBinarySensorEntityDescription(
ENTITY_DESCRIPTIONS: tuple[EcovacsBinarySensorEntityDescription, ...] = ( ENTITY_DESCRIPTIONS: tuple[EcovacsBinarySensorEntityDescription, ...] = (
EcovacsBinarySensorEntityDescription[WaterInfoEvent]( EcovacsBinarySensorEntityDescription[WaterInfoEvent](
device_capabilities=VacuumCapabilities,
capability_fn=lambda caps: caps.water, capability_fn=lambda caps: caps.water,
value_fn=lambda e: e.mop_attached, value_fn=lambda e: e.mop_attached,
key="water_mop_attached", key="water_mop_attached",
@ -62,7 +56,7 @@ async def async_setup_entry(
class EcovacsBinarySensor( class EcovacsBinarySensor(
EcovacsDescriptionEntity[CapabilityDevice, CapabilityEvent[EventT]], EcovacsDescriptionEntity[CapabilityEvent[EventT]],
BinarySensorEntity, BinarySensorEntity,
): ):
"""Ecovacs binary sensor.""" """Ecovacs binary sensor."""

View File

@ -2,12 +2,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from deebot_client.capabilities import ( from deebot_client.capabilities import CapabilityExecute, CapabilityLifeSpan
Capabilities,
CapabilityExecute,
CapabilityLifeSpan,
VacuumCapabilities,
)
from deebot_client.events import LifeSpan from deebot_client.events import LifeSpan
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
@ -18,7 +13,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .const import SUPPORTED_LIFESPANS from .const import SUPPORTED_LIFESPANS
from .entity import ( from .entity import (
CapabilityDevice,
EcovacsCapabilityEntityDescription, EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity, EcovacsDescriptionEntity,
EcovacsEntity, EcovacsEntity,
@ -43,7 +37,6 @@ class EcovacsLifespanButtonEntityDescription(ButtonEntityDescription):
ENTITY_DESCRIPTIONS: tuple[EcovacsButtonEntityDescription, ...] = ( ENTITY_DESCRIPTIONS: tuple[EcovacsButtonEntityDescription, ...] = (
EcovacsButtonEntityDescription( EcovacsButtonEntityDescription(
device_capabilities=VacuumCapabilities,
capability_fn=lambda caps: caps.map.relocation if caps.map else None, capability_fn=lambda caps: caps.map.relocation if caps.map else None,
key="relocate", key="relocate",
translation_key="relocate", translation_key="relocate",
@ -77,7 +70,7 @@ async def async_setup_entry(
EcovacsResetLifespanButtonEntity( EcovacsResetLifespanButtonEntity(
device, device.capabilities.life_span, description device, device.capabilities.life_span, description
) )
for device in controller.devices(Capabilities) for device in controller.devices
for description in LIFESPAN_ENTITY_DESCRIPTIONS for description in LIFESPAN_ENTITY_DESCRIPTIONS
if description.component in device.capabilities.life_span.types if description.component in device.capabilities.life_span.types
) )
@ -85,7 +78,7 @@ async def async_setup_entry(
class EcovacsButtonEntity( class EcovacsButtonEntity(
EcovacsDescriptionEntity[CapabilityDevice, CapabilityExecute], EcovacsDescriptionEntity[CapabilityExecute],
ButtonEntity, ButtonEntity,
): ):
"""Ecovacs button entity.""" """Ecovacs button entity."""
@ -98,7 +91,7 @@ class EcovacsButtonEntity(
class EcovacsResetLifespanButtonEntity( class EcovacsResetLifespanButtonEntity(
EcovacsDescriptionEntity[Capabilities, CapabilityLifeSpan], EcovacsDescriptionEntity[CapabilityLifeSpan],
ButtonEntity, ButtonEntity,
): ):
"""Ecovacs reset lifespan button entity.""" """Ecovacs reset lifespan button entity."""

View File

@ -9,7 +9,6 @@ from typing import Any
from deebot_client.api_client import ApiClient from deebot_client.api_client import ApiClient
from deebot_client.authentication import Authenticator, create_rest_config from deebot_client.authentication import Authenticator, create_rest_config
from deebot_client.capabilities import Capabilities
from deebot_client.const import UNDEFINED, UndefinedType from deebot_client.const import UNDEFINED, UndefinedType
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.exceptions import DeebotError, InvalidAuthenticationError from deebot_client.exceptions import DeebotError, InvalidAuthenticationError
@ -18,10 +17,9 @@ from deebot_client.mqtt_client import MqttClient, create_mqtt_config
from deebot_client.util import md5 from deebot_client.util import md5
from deebot_client.util.continents import get_continent from deebot_client.util.continents import get_continent
from sucks import EcoVacsAPI, VacBot from sucks import EcoVacsAPI, VacBot
from typing_extensions import Generator
from homeassistant.const import CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_COUNTRY, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from homeassistant.util.ssl import get_default_no_verify_context from homeassistant.util.ssl import get_default_no_verify_context
@ -119,12 +117,10 @@ class EcovacsController:
await self._mqtt.disconnect() await self._mqtt.disconnect()
await self._authenticator.teardown() await self._authenticator.teardown()
@callback @property
def devices(self, capability: type[Capabilities]) -> Generator[Device]: def devices(self) -> list[Device]:
"""Return generator for devices with a specific capability.""" """Return devices."""
for device in self._devices: return self._devices
if isinstance(device.capabilities, capability):
yield device
@property @property
def legacy_devices(self) -> list[VacBot]: def legacy_devices(self) -> list[VacBot]:

View File

@ -4,8 +4,6 @@ from __future__ import annotations
from typing import Any from typing import Any
from deebot_client.capabilities import Capabilities
from homeassistant.components.diagnostics import async_redact_data from homeassistant.components.diagnostics import async_redact_data
from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME from homeassistant.const import CONF_NAME, CONF_PASSWORD, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -34,7 +32,7 @@ async def async_get_config_entry_diagnostics(
diag["devices"] = [ diag["devices"] = [
async_redact_data(device.device_info, REDACT_DEVICE) async_redact_data(device.device_info, REDACT_DEVICE)
for device in controller.devices(Capabilities) for device in controller.devices
] ]
diag["legacy_devices"] = [ diag["legacy_devices"] = [
async_redact_data(device.vacuum, REDACT_DEVICE) async_redact_data(device.vacuum, REDACT_DEVICE)

View File

@ -18,11 +18,10 @@ from homeassistant.helpers.entity import Entity, EntityDescription
from .const import DOMAIN from .const import DOMAIN
CapabilityEntity = TypeVar("CapabilityEntity") CapabilityEntity = TypeVar("CapabilityEntity")
CapabilityDevice = TypeVar("CapabilityDevice", bound=Capabilities)
EventT = TypeVar("EventT", bound=Event) EventT = TypeVar("EventT", bound=Event)
class EcovacsEntity(Entity, Generic[CapabilityDevice, CapabilityEntity]): class EcovacsEntity(Entity, Generic[CapabilityEntity]):
"""Ecovacs entity.""" """Ecovacs entity."""
_attr_should_poll = False _attr_should_poll = False
@ -31,7 +30,7 @@ class EcovacsEntity(Entity, Generic[CapabilityDevice, CapabilityEntity]):
def __init__( def __init__(
self, self,
device: Device[CapabilityDevice], device: Device,
capability: CapabilityEntity, capability: CapabilityEntity,
**kwargs: Any, **kwargs: Any,
) -> None: ) -> None:
@ -97,12 +96,12 @@ class EcovacsEntity(Entity, Generic[CapabilityDevice, CapabilityEntity]):
self._device.events.request_refresh(event_type) self._device.events.request_refresh(event_type)
class EcovacsDescriptionEntity(EcovacsEntity[CapabilityDevice, CapabilityEntity]): class EcovacsDescriptionEntity(EcovacsEntity[CapabilityEntity]):
"""Ecovacs entity.""" """Ecovacs entity."""
def __init__( def __init__(
self, self,
device: Device[CapabilityDevice], device: Device,
capability: CapabilityEntity, capability: CapabilityEntity,
entity_description: EntityDescription, entity_description: EntityDescription,
**kwargs: Any, **kwargs: Any,
@ -115,9 +114,8 @@ class EcovacsDescriptionEntity(EcovacsEntity[CapabilityDevice, CapabilityEntity]
@dataclass(kw_only=True, frozen=True) @dataclass(kw_only=True, frozen=True)
class EcovacsCapabilityEntityDescription( class EcovacsCapabilityEntityDescription(
EntityDescription, EntityDescription,
Generic[CapabilityDevice, CapabilityEntity], Generic[CapabilityEntity],
): ):
"""Ecovacs entity description.""" """Ecovacs entity description."""
device_capabilities: type[CapabilityDevice] capability_fn: Callable[[Capabilities], CapabilityEntity | None]
capability_fn: Callable[[CapabilityDevice], CapabilityEntity | None]

View File

@ -1,6 +1,6 @@
"""Event module.""" """Event module."""
from deebot_client.capabilities import Capabilities, CapabilityEvent from deebot_client.capabilities import CapabilityEvent
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.events import CleanJobStatus, ReportStatsEvent from deebot_client.events import CleanJobStatus, ReportStatsEvent
@ -22,12 +22,12 @@ async def async_setup_entry(
"""Add entities for passed config_entry in HA.""" """Add entities for passed config_entry in HA."""
controller = config_entry.runtime_data controller = config_entry.runtime_data
async_add_entities( async_add_entities(
EcovacsLastJobEventEntity(device) for device in controller.devices(Capabilities) EcovacsLastJobEventEntity(device) for device in controller.devices
) )
class EcovacsLastJobEventEntity( class EcovacsLastJobEventEntity(
EcovacsEntity[Capabilities, CapabilityEvent[ReportStatsEvent]], EcovacsEntity[CapabilityEvent[ReportStatsEvent]],
EventEntity, EventEntity,
): ):
"""Ecovacs last job event entity.""" """Ecovacs last job event entity."""
@ -39,7 +39,7 @@ class EcovacsLastJobEventEntity(
event_types=["finished", "finished_with_warnings", "manually_stopped"], event_types=["finished", "finished_with_warnings", "manually_stopped"],
) )
def __init__(self, device: Device[Capabilities]) -> None: def __init__(self, device: Device) -> None:
"""Initialize entity.""" """Initialize entity."""
super().__init__(device, device.capabilities.stats.report) super().__init__(device, device.capabilities.stats.report)

View File

@ -1,6 +1,6 @@
"""Ecovacs image entities.""" """Ecovacs image entities."""
from deebot_client.capabilities import CapabilityMap, VacuumCapabilities from deebot_client.capabilities import CapabilityMap
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.events.map import CachedMapInfoEvent, MapChangedEvent from deebot_client.events.map import CachedMapInfoEvent, MapChangedEvent
@ -20,18 +20,18 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Add entities for passed config_entry in HA.""" """Add entities for passed config_entry in HA."""
controller = config_entry.runtime_data controller = config_entry.runtime_data
entities = [] entities = [
for device in controller.devices(VacuumCapabilities): EcovacsMap(device, caps, hass)
capabilities: VacuumCapabilities = device.capabilities for device in controller.devices
if caps := capabilities.map: if (caps := device.capabilities.map)
entities.append(EcovacsMap(device, caps, hass)) ]
if entities: if entities:
async_add_entities(entities) async_add_entities(entities)
class EcovacsMap( class EcovacsMap(
EcovacsEntity[VacuumCapabilities, CapabilityMap], EcovacsEntity[CapabilityMap],
ImageEntity, ImageEntity,
): ):
"""Ecovacs map.""" """Ecovacs map."""

View File

@ -4,7 +4,7 @@ from __future__ import annotations
import logging import logging
from deebot_client.capabilities import MowerCapabilities from deebot_client.capabilities import Capabilities, DeviceType
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.events import StateEvent from deebot_client.events import StateEvent
from deebot_client.models import CleanAction, State from deebot_client.models import CleanAction, State
@ -42,14 +42,16 @@ async def async_setup_entry(
"""Set up the Ecovacs mowers.""" """Set up the Ecovacs mowers."""
controller = config_entry.runtime_data controller = config_entry.runtime_data
mowers: list[EcovacsMower] = [ mowers: list[EcovacsMower] = [
EcovacsMower(device) for device in controller.devices(MowerCapabilities) EcovacsMower(device)
for device in controller.devices
if device.capabilities.device_type is DeviceType.MOWER
] ]
_LOGGER.debug("Adding Ecovacs Mowers to Home Assistant: %s", mowers) _LOGGER.debug("Adding Ecovacs Mowers to Home Assistant: %s", mowers)
async_add_entities(mowers) async_add_entities(mowers)
class EcovacsMower( class EcovacsMower(
EcovacsEntity[MowerCapabilities, MowerCapabilities], EcovacsEntity[Capabilities],
LawnMowerEntity, LawnMowerEntity,
): ):
"""Ecovacs Mower.""" """Ecovacs Mower."""
@ -62,10 +64,9 @@ class EcovacsMower(
entity_description = LawnMowerEntityEntityDescription(key="mower", name=None) entity_description = LawnMowerEntityEntityDescription(key="mower", name=None)
def __init__(self, device: Device[MowerCapabilities]) -> None: def __init__(self, device: Device) -> None:
"""Initialize the mower.""" """Initialize the mower."""
capabilities = device.capabilities super().__init__(device, device.capabilities)
super().__init__(device, capabilities)
async def async_added_to_hass(self) -> None: async def async_added_to_hass(self) -> None:
"""Set up the event listeners now that hass is ready.""" """Set up the event listeners now that hass is ready."""

View File

@ -6,5 +6,5 @@
"documentation": "https://www.home-assistant.io/integrations/ecovacs", "documentation": "https://www.home-assistant.io/integrations/ecovacs",
"iot_class": "cloud_push", "iot_class": "cloud_push",
"loggers": ["sleekxmppfs", "sucks", "deebot_client"], "loggers": ["sleekxmppfs", "sucks", "deebot_client"],
"requirements": ["py-sucks==0.9.10", "deebot-client==7.3.0"] "requirements": ["py-sucks==0.9.10", "deebot-client==8.0.0"]
} }

View File

@ -6,7 +6,7 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Generic from typing import Generic
from deebot_client.capabilities import Capabilities, CapabilitySet, VacuumCapabilities from deebot_client.capabilities import CapabilitySet
from deebot_client.events import CleanCountEvent, VolumeEvent from deebot_client.events import CleanCountEvent, VolumeEvent
from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.components.number import NumberEntity, NumberEntityDescription
@ -16,7 +16,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .entity import ( from .entity import (
CapabilityDevice,
EcovacsCapabilityEntityDescription, EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity, EcovacsDescriptionEntity,
EcovacsEntity, EcovacsEntity,
@ -39,7 +38,6 @@ class EcovacsNumberEntityDescription(
ENTITY_DESCRIPTIONS: tuple[EcovacsNumberEntityDescription, ...] = ( ENTITY_DESCRIPTIONS: tuple[EcovacsNumberEntityDescription, ...] = (
EcovacsNumberEntityDescription[VolumeEvent]( EcovacsNumberEntityDescription[VolumeEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.settings.volume, capability_fn=lambda caps: caps.settings.volume,
value_fn=lambda e: e.volume, value_fn=lambda e: e.volume,
native_max_value_fn=lambda e: e.maximum, native_max_value_fn=lambda e: e.maximum,
@ -52,7 +50,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsNumberEntityDescription, ...] = (
native_step=1.0, native_step=1.0,
), ),
EcovacsNumberEntityDescription[CleanCountEvent]( EcovacsNumberEntityDescription[CleanCountEvent](
device_capabilities=VacuumCapabilities,
capability_fn=lambda caps: caps.clean.count, capability_fn=lambda caps: caps.clean.count,
value_fn=lambda e: e.count, value_fn=lambda e: e.count,
key="clean_count", key="clean_count",
@ -81,7 +78,7 @@ async def async_setup_entry(
class EcovacsNumberEntity( class EcovacsNumberEntity(
EcovacsDescriptionEntity[CapabilityDevice, CapabilitySet[EventT, int]], EcovacsDescriptionEntity[CapabilitySet[EventT, int]],
NumberEntity, NumberEntity,
): ):
"""Ecovacs number entity.""" """Ecovacs number entity."""

View File

@ -4,7 +4,7 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any, Generic from typing import Any, Generic
from deebot_client.capabilities import CapabilitySetTypes, VacuumCapabilities from deebot_client.capabilities import CapabilitySetTypes
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.events import WaterInfoEvent, WorkModeEvent from deebot_client.events import WaterInfoEvent, WorkModeEvent
@ -14,12 +14,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .entity import ( from .entity import EcovacsCapabilityEntityDescription, EcovacsDescriptionEntity, EventT
CapabilityDevice,
EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity,
EventT,
)
from .util import get_name_key, get_supported_entitites from .util import get_name_key, get_supported_entitites
@ -37,7 +32,6 @@ class EcovacsSelectEntityDescription(
ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = ( ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = (
EcovacsSelectEntityDescription[WaterInfoEvent]( EcovacsSelectEntityDescription[WaterInfoEvent](
device_capabilities=VacuumCapabilities,
capability_fn=lambda caps: caps.water, capability_fn=lambda caps: caps.water,
current_option_fn=lambda e: get_name_key(e.amount), current_option_fn=lambda e: get_name_key(e.amount),
options_fn=lambda water: [get_name_key(amount) for amount in water.types], options_fn=lambda water: [get_name_key(amount) for amount in water.types],
@ -46,7 +40,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSelectEntityDescription, ...] = (
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSelectEntityDescription[WorkModeEvent]( EcovacsSelectEntityDescription[WorkModeEvent](
device_capabilities=VacuumCapabilities,
capability_fn=lambda caps: caps.clean.work_mode, capability_fn=lambda caps: caps.clean.work_mode,
current_option_fn=lambda e: get_name_key(e.mode), current_option_fn=lambda e: get_name_key(e.mode),
options_fn=lambda cap: [get_name_key(mode) for mode in cap.types], options_fn=lambda cap: [get_name_key(mode) for mode in cap.types],
@ -73,7 +66,7 @@ async def async_setup_entry(
class EcovacsSelectEntity( class EcovacsSelectEntity(
EcovacsDescriptionEntity[CapabilityDevice, CapabilitySetTypes[EventT, str]], EcovacsDescriptionEntity[CapabilitySetTypes[EventT, str]],
SelectEntity, SelectEntity,
): ):
"""Ecovacs select entity.""" """Ecovacs select entity."""

View File

@ -6,7 +6,7 @@ from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from typing import Generic from typing import Generic
from deebot_client.capabilities import Capabilities, CapabilityEvent, CapabilityLifeSpan from deebot_client.capabilities import CapabilityEvent, CapabilityLifeSpan
from deebot_client.events import ( from deebot_client.events import (
BatteryEvent, BatteryEvent,
ErrorEvent, ErrorEvent,
@ -39,7 +39,6 @@ from homeassistant.helpers.typing import StateType
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .const import SUPPORTED_LIFESPANS from .const import SUPPORTED_LIFESPANS
from .entity import ( from .entity import (
CapabilityDevice,
EcovacsCapabilityEntityDescription, EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity, EcovacsDescriptionEntity,
EcovacsEntity, EcovacsEntity,
@ -63,7 +62,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
# Stats # Stats
EcovacsSensorEntityDescription[StatsEvent]( EcovacsSensorEntityDescription[StatsEvent](
key="stats_area", key="stats_area",
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.stats.clean, capability_fn=lambda caps: caps.stats.clean,
value_fn=lambda e: e.area, value_fn=lambda e: e.area,
translation_key="stats_area", translation_key="stats_area",
@ -71,7 +69,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
), ),
EcovacsSensorEntityDescription[StatsEvent]( EcovacsSensorEntityDescription[StatsEvent](
key="stats_time", key="stats_time",
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.stats.clean, capability_fn=lambda caps: caps.stats.clean,
value_fn=lambda e: e.time, value_fn=lambda e: e.time,
translation_key="stats_time", translation_key="stats_time",
@ -81,7 +78,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
), ),
# TotalStats # TotalStats
EcovacsSensorEntityDescription[TotalStatsEvent]( EcovacsSensorEntityDescription[TotalStatsEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.stats.total, capability_fn=lambda caps: caps.stats.total,
value_fn=lambda e: e.area, value_fn=lambda e: e.area,
key="total_stats_area", key="total_stats_area",
@ -90,7 +86,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
), ),
EcovacsSensorEntityDescription[TotalStatsEvent]( EcovacsSensorEntityDescription[TotalStatsEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.stats.total, capability_fn=lambda caps: caps.stats.total,
value_fn=lambda e: e.time, value_fn=lambda e: e.time,
key="total_stats_time", key="total_stats_time",
@ -101,7 +96,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
), ),
EcovacsSensorEntityDescription[TotalStatsEvent]( EcovacsSensorEntityDescription[TotalStatsEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.stats.total, capability_fn=lambda caps: caps.stats.total,
value_fn=lambda e: e.cleanings, value_fn=lambda e: e.cleanings,
key="total_stats_cleanings", key="total_stats_cleanings",
@ -109,7 +103,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
state_class=SensorStateClass.TOTAL_INCREASING, state_class=SensorStateClass.TOTAL_INCREASING,
), ),
EcovacsSensorEntityDescription[BatteryEvent]( EcovacsSensorEntityDescription[BatteryEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.battery, capability_fn=lambda caps: caps.battery,
value_fn=lambda e: e.value, value_fn=lambda e: e.value,
key=ATTR_BATTERY_LEVEL, key=ATTR_BATTERY_LEVEL,
@ -118,7 +111,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
), ),
EcovacsSensorEntityDescription[NetworkInfoEvent]( EcovacsSensorEntityDescription[NetworkInfoEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.network, capability_fn=lambda caps: caps.network,
value_fn=lambda e: e.ip, value_fn=lambda e: e.ip,
key="network_ip", key="network_ip",
@ -127,7 +119,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
), ),
EcovacsSensorEntityDescription[NetworkInfoEvent]( EcovacsSensorEntityDescription[NetworkInfoEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.network, capability_fn=lambda caps: caps.network,
value_fn=lambda e: e.rssi, value_fn=lambda e: e.rssi,
key="network_rssi", key="network_rssi",
@ -136,7 +127,6 @@ ENTITY_DESCRIPTIONS: tuple[EcovacsSensorEntityDescription, ...] = (
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
), ),
EcovacsSensorEntityDescription[NetworkInfoEvent]( EcovacsSensorEntityDescription[NetworkInfoEvent](
device_capabilities=Capabilities,
capability_fn=lambda caps: caps.network, capability_fn=lambda caps: caps.network,
value_fn=lambda e: e.ssid, value_fn=lambda e: e.ssid,
key="network_ssid", key="network_ssid",
@ -181,13 +171,13 @@ async def async_setup_entry(
) )
entities.extend( entities.extend(
EcovacsLifespanSensor(device, device.capabilities.life_span, description) EcovacsLifespanSensor(device, device.capabilities.life_span, description)
for device in controller.devices(Capabilities) for device in controller.devices
for description in LIFESPAN_ENTITY_DESCRIPTIONS for description in LIFESPAN_ENTITY_DESCRIPTIONS
if description.component in device.capabilities.life_span.types if description.component in device.capabilities.life_span.types
) )
entities.extend( entities.extend(
EcovacsErrorSensor(device, capability) EcovacsErrorSensor(device, capability)
for device in controller.devices(Capabilities) for device in controller.devices
if (capability := device.capabilities.error) if (capability := device.capabilities.error)
) )
@ -195,7 +185,7 @@ async def async_setup_entry(
class EcovacsSensor( class EcovacsSensor(
EcovacsDescriptionEntity[CapabilityDevice, CapabilityEvent], EcovacsDescriptionEntity[CapabilityEvent],
SensorEntity, SensorEntity,
): ):
"""Ecovacs sensor.""" """Ecovacs sensor."""
@ -218,7 +208,7 @@ class EcovacsSensor(
class EcovacsLifespanSensor( class EcovacsLifespanSensor(
EcovacsDescriptionEntity[Capabilities, CapabilityLifeSpan], EcovacsDescriptionEntity[CapabilityLifeSpan],
SensorEntity, SensorEntity,
): ):
"""Lifespan sensor.""" """Lifespan sensor."""
@ -238,7 +228,7 @@ class EcovacsLifespanSensor(
class EcovacsErrorSensor( class EcovacsErrorSensor(
EcovacsEntity[Capabilities, CapabilityEvent[ErrorEvent]], EcovacsEntity[CapabilityEvent[ErrorEvent]],
SensorEntity, SensorEntity,
): ):
"""Error sensor.""" """Error sensor."""

View File

@ -3,11 +3,7 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any from typing import Any
from deebot_client.capabilities import ( from deebot_client.capabilities import CapabilitySetEnable
Capabilities,
CapabilitySetEnable,
VacuumCapabilities,
)
from deebot_client.events import EnableEvent from deebot_client.events import EnableEvent
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
@ -17,7 +13,6 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import EcovacsConfigEntry from . import EcovacsConfigEntry
from .entity import ( from .entity import (
CapabilityDevice,
EcovacsCapabilityEntityDescription, EcovacsCapabilityEntityDescription,
EcovacsDescriptionEntity, EcovacsDescriptionEntity,
EcovacsEntity, EcovacsEntity,
@ -28,86 +23,76 @@ from .util import get_supported_entitites
@dataclass(kw_only=True, frozen=True) @dataclass(kw_only=True, frozen=True)
class EcovacsSwitchEntityDescription( class EcovacsSwitchEntityDescription(
SwitchEntityDescription, SwitchEntityDescription,
EcovacsCapabilityEntityDescription[CapabilityDevice, CapabilitySetEnable], EcovacsCapabilityEntityDescription[CapabilitySetEnable],
): ):
"""Ecovacs switch entity description.""" """Ecovacs switch entity description."""
ENTITY_DESCRIPTIONS: tuple[EcovacsSwitchEntityDescription, ...] = ( ENTITY_DESCRIPTIONS: tuple[EcovacsSwitchEntityDescription, ...] = (
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.advanced_mode, capability_fn=lambda c: c.settings.advanced_mode,
key="advanced_mode", key="advanced_mode",
translation_key="advanced_mode", translation_key="advanced_mode",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[VacuumCapabilities]( EcovacsSwitchEntityDescription(
device_capabilities=VacuumCapabilities,
capability_fn=lambda c: c.clean.continuous, capability_fn=lambda c: c.clean.continuous,
key="continuous_cleaning", key="continuous_cleaning",
translation_key="continuous_cleaning", translation_key="continuous_cleaning",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[VacuumCapabilities]( EcovacsSwitchEntityDescription(
device_capabilities=VacuumCapabilities,
capability_fn=lambda c: c.settings.carpet_auto_fan_boost, capability_fn=lambda c: c.settings.carpet_auto_fan_boost,
key="carpet_auto_fan_boost", key="carpet_auto_fan_boost",
translation_key="carpet_auto_fan_boost", translation_key="carpet_auto_fan_boost",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[VacuumCapabilities]( EcovacsSwitchEntityDescription(
device_capabilities=VacuumCapabilities,
capability_fn=lambda c: c.clean.preference, capability_fn=lambda c: c.clean.preference,
key="clean_preference", key="clean_preference",
translation_key="clean_preference", translation_key="clean_preference",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.true_detect, capability_fn=lambda c: c.settings.true_detect,
key="true_detect", key="true_detect",
translation_key="true_detect", translation_key="true_detect",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.border_switch, capability_fn=lambda c: c.settings.border_switch,
key="border_switch", key="border_switch",
translation_key="border_switch", translation_key="border_switch",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.child_lock, capability_fn=lambda c: c.settings.child_lock,
key="child_lock", key="child_lock",
translation_key="child_lock", translation_key="child_lock",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.moveup_warning, capability_fn=lambda c: c.settings.moveup_warning,
key="move_up_warning", key="move_up_warning",
translation_key="move_up_warning", translation_key="move_up_warning",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.cross_map_border_warning, capability_fn=lambda c: c.settings.cross_map_border_warning,
key="cross_map_border_warning", key="cross_map_border_warning",
translation_key="cross_map_border_warning", translation_key="cross_map_border_warning",
entity_registry_enabled_default=False, entity_registry_enabled_default=False,
entity_category=EntityCategory.CONFIG, entity_category=EntityCategory.CONFIG,
), ),
EcovacsSwitchEntityDescription[Capabilities]( EcovacsSwitchEntityDescription(
device_capabilities=Capabilities,
capability_fn=lambda c: c.settings.safe_protect, capability_fn=lambda c: c.settings.safe_protect,
key="safe_protect", key="safe_protect",
translation_key="safe_protect", translation_key="safe_protect",
@ -132,7 +117,7 @@ async def async_setup_entry(
class EcovacsSwitchEntity( class EcovacsSwitchEntity(
EcovacsDescriptionEntity[CapabilityDevice, CapabilitySetEnable], EcovacsDescriptionEntity[CapabilitySetEnable],
SwitchEntity, SwitchEntity,
): ):
"""Ecovacs switch entity.""" """Ecovacs switch entity."""

View File

@ -7,8 +7,6 @@ import random
import string import string
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from deebot_client.capabilities import Capabilities
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.util import slugify from homeassistant.util import slugify
@ -40,9 +38,8 @@ def get_supported_entitites(
"""Return all supported entities for all devices.""" """Return all supported entities for all devices."""
return [ return [
entity_class(device, capability, description) entity_class(device, capability, description)
for device in controller.devices(Capabilities) for device in controller.devices
for description in descriptions for description in descriptions
if isinstance(device.capabilities, description.device_capabilities)
if (capability := description.capability_fn(device.capabilities)) if (capability := description.capability_fn(device.capabilities))
] ]

View File

@ -4,9 +4,9 @@ from __future__ import annotations
from collections.abc import Mapping from collections.abc import Mapping
import logging import logging
from typing import Any from typing import TYPE_CHECKING, Any
from deebot_client.capabilities import VacuumCapabilities from deebot_client.capabilities import Capabilities, DeviceType
from deebot_client.device import Device from deebot_client.device import Device
from deebot_client.events import BatteryEvent, FanSpeedEvent, RoomsEvent, StateEvent from deebot_client.events import BatteryEvent, FanSpeedEvent, RoomsEvent, StateEvent
from deebot_client.models import CleanAction, CleanMode, Room, State from deebot_client.models import CleanAction, CleanMode, Room, State
@ -52,7 +52,9 @@ async def async_setup_entry(
controller = config_entry.runtime_data controller = config_entry.runtime_data
vacuums: list[EcovacsVacuum | EcovacsLegacyVacuum] = [ vacuums: list[EcovacsVacuum | EcovacsLegacyVacuum] = [
EcovacsVacuum(device) for device in controller.devices(VacuumCapabilities) EcovacsVacuum(device)
for device in controller.devices
if device.capabilities.device_type is DeviceType.VACUUM
] ]
for device in controller.legacy_devices: for device in controller.legacy_devices:
await hass.async_add_executor_job(device.connect_and_wait_until_ready) await hass.async_add_executor_job(device.connect_and_wait_until_ready)
@ -232,7 +234,7 @@ _ATTR_ROOMS = "rooms"
class EcovacsVacuum( class EcovacsVacuum(
EcovacsEntity[VacuumCapabilities, VacuumCapabilities], EcovacsEntity[Capabilities],
StateVacuumEntity, StateVacuumEntity,
): ):
"""Ecovacs vacuum.""" """Ecovacs vacuum."""
@ -243,7 +245,6 @@ class EcovacsVacuum(
VacuumEntityFeature.PAUSE VacuumEntityFeature.PAUSE
| VacuumEntityFeature.STOP | VacuumEntityFeature.STOP
| VacuumEntityFeature.RETURN_HOME | VacuumEntityFeature.RETURN_HOME
| VacuumEntityFeature.FAN_SPEED
| VacuumEntityFeature.BATTERY | VacuumEntityFeature.BATTERY
| VacuumEntityFeature.SEND_COMMAND | VacuumEntityFeature.SEND_COMMAND
| VacuumEntityFeature.LOCATE | VacuumEntityFeature.LOCATE
@ -255,16 +256,17 @@ class EcovacsVacuum(
key="vacuum", translation_key="vacuum", name=None key="vacuum", translation_key="vacuum", name=None
) )
def __init__(self, device: Device[VacuumCapabilities]) -> None: def __init__(self, device: Device) -> None:
"""Initialize the vacuum.""" """Initialize the vacuum."""
capabilities = device.capabilities super().__init__(device, device.capabilities)
super().__init__(device, capabilities)
self._rooms: list[Room] = [] self._rooms: list[Room] = []
self._attr_fan_speed_list = [ if fan_speed := self._capability.fan_speed:
get_name_key(level) for level in capabilities.fan_speed.types self._attr_supported_features |= VacuumEntityFeature.FAN_SPEED
] self._attr_fan_speed_list = [
get_name_key(level) for level in fan_speed.types
]
async def async_added_to_hass(self) -> None: async def async_added_to_hass(self) -> None:
"""Set up the event listeners now that hass is ready.""" """Set up the event listeners now that hass is ready."""
@ -274,10 +276,6 @@ class EcovacsVacuum(
self._attr_battery_level = event.value self._attr_battery_level = event.value
self.async_write_ha_state() self.async_write_ha_state()
async def on_fan_speed(event: FanSpeedEvent) -> None:
self._attr_fan_speed = get_name_key(event.speed)
self.async_write_ha_state()
async def on_rooms(event: RoomsEvent) -> None: async def on_rooms(event: RoomsEvent) -> None:
self._rooms = event.rooms self._rooms = event.rooms
self.async_write_ha_state() self.async_write_ha_state()
@ -287,9 +285,16 @@ class EcovacsVacuum(
self.async_write_ha_state() self.async_write_ha_state()
self._subscribe(self._capability.battery.event, on_battery) self._subscribe(self._capability.battery.event, on_battery)
self._subscribe(self._capability.fan_speed.event, on_fan_speed)
self._subscribe(self._capability.state.event, on_status) self._subscribe(self._capability.state.event, on_status)
if self._capability.fan_speed:
async def on_fan_speed(event: FanSpeedEvent) -> None:
self._attr_fan_speed = get_name_key(event.speed)
self.async_write_ha_state()
self._subscribe(self._capability.fan_speed.event, on_fan_speed)
if map_caps := self._capability.map: if map_caps := self._capability.map:
self._subscribe(map_caps.rooms.event, on_rooms) self._subscribe(map_caps.rooms.event, on_rooms)
@ -319,6 +324,8 @@ class EcovacsVacuum(
async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None: async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
"""Set fan speed.""" """Set fan speed."""
if TYPE_CHECKING:
assert self._capability.fan_speed
await self._device.execute_command(self._capability.fan_speed.set(fan_speed)) await self._device.execute_command(self._capability.fan_speed.set(fan_speed))
async def async_return_to_base(self, **kwargs: Any) -> None: async def async_return_to_base(self, **kwargs: Any) -> None:

View File

@ -706,7 +706,7 @@ debugpy==1.8.1
# decora==0.6 # decora==0.6
# homeassistant.components.ecovacs # homeassistant.components.ecovacs
deebot-client==7.3.0 deebot-client==8.0.0
# homeassistant.components.ihc # homeassistant.components.ihc
# homeassistant.components.namecheapdns # homeassistant.components.namecheapdns

View File

@ -584,7 +584,7 @@ dbus-fast==2.21.3
debugpy==1.8.1 debugpy==1.8.1
# homeassistant.components.ecovacs # homeassistant.components.ecovacs
deebot-client==7.3.0 deebot-client==8.0.0
# homeassistant.components.ihc # homeassistant.components.ihc
# homeassistant.components.namecheapdns # homeassistant.components.namecheapdns

View File

@ -1,6 +1,5 @@
"""Tests for Ecovacs binary sensors.""" """Tests for Ecovacs binary sensors."""
from deebot_client.capabilities import Capabilities
from deebot_client.events import WaterAmount, WaterInfoEvent from deebot_client.events import WaterAmount, WaterInfoEvent
import pytest import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
@ -38,7 +37,7 @@ async def test_mop_attached(
assert entity_entry == snapshot(name=f"{entity_id}-entity_entry") assert entity_entry == snapshot(name=f"{entity_id}-entity_entry")
assert entity_entry.device_id assert entity_entry.device_id
device = next(controller.devices(Capabilities)) device = controller.devices[0]
assert (device_entry := device_registry.async_get(entity_entry.device_id)) assert (device_entry := device_registry.async_get(entity_entry.device_id))
assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])} assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])}

View File

@ -1,6 +1,5 @@
"""Tests for Ecovacs sensors.""" """Tests for Ecovacs sensors."""
from deebot_client.capabilities import Capabilities
from deebot_client.command import Command from deebot_client.command import Command
from deebot_client.commands.json import ResetLifeSpan, SetRelocationState from deebot_client.commands.json import ResetLifeSpan, SetRelocationState
from deebot_client.events import LifeSpan from deebot_client.events import LifeSpan
@ -74,7 +73,7 @@ async def test_buttons(
) -> None: ) -> None:
"""Test that sensor entity snapshots match.""" """Test that sensor entity snapshots match."""
assert hass.states.async_entity_ids() == [e[0] for e in entities] assert hass.states.async_entity_ids() == [e[0] for e in entities]
device = next(controller.devices(Capabilities)) device = controller.devices[0]
for entity_id, command in entities: for entity_id, command in entities:
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
assert state.state == STATE_UNKNOWN assert state.state == STATE_UNKNOWN

View File

@ -2,7 +2,6 @@
from datetime import timedelta from datetime import timedelta
from deebot_client.capabilities import Capabilities
from deebot_client.events import CleanJobStatus, ReportStatsEvent from deebot_client.events import CleanJobStatus, ReportStatsEvent
from freezegun.api import FrozenDateTimeFactory from freezegun.api import FrozenDateTimeFactory
import pytest import pytest
@ -44,7 +43,7 @@ async def test_last_job(
assert entity_entry == snapshot(name=f"{entity_id}-entity_entry") assert entity_entry == snapshot(name=f"{entity_id}-entity_entry")
assert entity_entry.device_id assert entity_entry.device_id
device = next(controller.devices(Capabilities)) device = controller.devices[0]
assert (device_entry := device_registry.async_get(entity_entry.device_id)) assert (device_entry := device_registry.async_get(entity_entry.device_id))
assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])} assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])}

View File

@ -3,7 +3,6 @@
from typing import Any from typing import Any
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
from deebot_client.capabilities import Capabilities
from deebot_client.exceptions import DeebotError, InvalidAuthenticationError from deebot_client.exceptions import DeebotError, InvalidAuthenticationError
import pytest import pytest
from syrupy import SnapshotAssertion from syrupy import SnapshotAssertion
@ -121,7 +120,7 @@ async def test_devices_in_dr(
snapshot: SnapshotAssertion, snapshot: SnapshotAssertion,
) -> None: ) -> None:
"""Test all devices are in the device registry.""" """Test all devices are in the device registry."""
for device in controller.devices(Capabilities): for device in controller.devices:
assert ( assert (
device_entry := device_registry.async_get_device( device_entry := device_registry.async_get_device(
identifiers={(DOMAIN, device.device_info["did"])} identifiers={(DOMAIN, device.device_info["did"])}

View File

@ -2,7 +2,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from deebot_client.capabilities import MowerCapabilities
from deebot_client.command import Command from deebot_client.command import Command
from deebot_client.commands.json import Charge, CleanV2 from deebot_client.commands.json import Charge, CleanV2
from deebot_client.events import StateEvent from deebot_client.events import StateEvent
@ -56,7 +55,7 @@ async def test_lawn_mower(
assert entity_entry == snapshot(name=f"{entity_id}-entity_entry") assert entity_entry == snapshot(name=f"{entity_id}-entity_entry")
assert entity_entry.device_id assert entity_entry.device_id
device = next(controller.devices(MowerCapabilities)) device = controller.devices[0]
assert (device_entry := device_registry.async_get(entity_entry.device_id)) assert (device_entry := device_registry.async_get(entity_entry.device_id))
assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])} assert device_entry.identifiers == {(DOMAIN, device.device_info["did"])}
@ -104,7 +103,7 @@ async def test_mover_services(
tests: list[MowerTestCase], tests: list[MowerTestCase],
) -> None: ) -> None:
"""Test mover services.""" """Test mover services."""
device = next(controller.devices(MowerCapabilities)) device = controller.devices[0]
for test in tests: for test in tests:
device._execute_command.reset_mock() device._execute_command.reset_mock()

View File

@ -2,7 +2,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from deebot_client.capabilities import Capabilities
from deebot_client.command import Command from deebot_client.command import Command
from deebot_client.commands.json import SetVolume from deebot_client.commands.json import SetVolume
from deebot_client.events import Event, VolumeEvent from deebot_client.events import Event, VolumeEvent
@ -66,7 +65,7 @@ async def test_number_entities(
tests: list[NumberTestCase], tests: list[NumberTestCase],
) -> None: ) -> None:
"""Test that number entity snapshots match.""" """Test that number entity snapshots match."""
device = next(controller.devices(Capabilities)) device = controller.devices[0]
event_bus = device.events event_bus = device.events
assert sorted(hass.states.async_entity_ids()) == sorted( assert sorted(hass.states.async_entity_ids()) == sorted(
@ -131,7 +130,7 @@ async def test_volume_maximum(
controller: EcovacsController, controller: EcovacsController,
) -> None: ) -> None:
"""Test volume maximum.""" """Test volume maximum."""
device = next(controller.devices(Capabilities)) device = controller.devices[0]
event_bus = device.events event_bus = device.events
entity_id = "number.ozmo_950_volume" entity_id = "number.ozmo_950_volume"
assert (state := hass.states.get(entity_id)) assert (state := hass.states.get(entity_id))

View File

@ -1,6 +1,5 @@
"""Tests for Ecovacs select entities.""" """Tests for Ecovacs select entities."""
from deebot_client.capabilities import Capabilities
from deebot_client.command import Command from deebot_client.command import Command
from deebot_client.commands.json import SetWaterInfo from deebot_client.commands.json import SetWaterInfo
from deebot_client.event_bus import EventBus from deebot_client.event_bus import EventBus
@ -64,7 +63,7 @@ async def test_selects(
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
assert state.state == STATE_UNKNOWN assert state.state == STATE_UNKNOWN
device = next(controller.devices(Capabilities)) device = controller.devices[0]
await notify_events(hass, device.events) await notify_events(hass, device.events)
for entity_id in entity_ids: for entity_id in entity_ids:
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
@ -100,7 +99,7 @@ async def test_selects_change(
command: Command, command: Command,
) -> None: ) -> None:
"""Test that changing select entities works.""" """Test that changing select entities works."""
device = next(controller.devices(Capabilities)) device = controller.devices[0]
await notify_events(hass, device.events) await notify_events(hass, device.events)
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"

View File

@ -1,6 +1,5 @@
"""Tests for Ecovacs sensors.""" """Tests for Ecovacs sensors."""
from deebot_client.capabilities import Capabilities
from deebot_client.event_bus import EventBus from deebot_client.event_bus import EventBus
from deebot_client.events import ( from deebot_client.events import (
BatteryEvent, BatteryEvent,
@ -103,7 +102,7 @@ async def test_sensors(
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"
assert state.state == STATE_UNKNOWN assert state.state == STATE_UNKNOWN
device = next(controller.devices(Capabilities)) device = controller.devices[0]
await notify_events(hass, device.events) await notify_events(hass, device.events)
for entity_id in entity_ids: for entity_id in entity_ids:
assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing" assert (state := hass.states.get(entity_id)), f"State of {entity_id} is missing"

View File

@ -2,7 +2,6 @@
from dataclasses import dataclass from dataclasses import dataclass
from deebot_client.capabilities import Capabilities
from deebot_client.command import Command from deebot_client.command import Command
from deebot_client.commands.json import ( from deebot_client.commands.json import (
SetAdvancedMode, SetAdvancedMode,
@ -140,7 +139,7 @@ async def test_switch_entities(
tests: list[SwitchTestCase], tests: list[SwitchTestCase],
) -> None: ) -> None:
"""Test switch entities.""" """Test switch entities."""
device = next(controller.devices(Capabilities)) device = controller.devices[0]
event_bus = device.events event_bus = device.events
assert hass.states.async_entity_ids() == [test.entity_id for test in tests] assert hass.states.async_entity_ids() == [test.entity_id for test in tests]