Add non coordinated Entity to Roborock (#93841)

switch to non coordinator entity
This commit is contained in:
Luke 2023-05-30 22:58:27 -04:00 committed by GitHub
parent 8cd8355ab1
commit 81561d4d3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 36 deletions

View file

@ -10,6 +10,7 @@ from roborock.local_api import RoborockLocalClient
from roborock.roborock_typing import DeviceProp from roborock.roborock_typing import DeviceProp
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN from .const import DOMAIN
@ -40,6 +41,13 @@ class RoborockDataUpdateCoordinator(DataUpdateCoordinator[DeviceProp]):
) )
device_info = DeviceData(device, product_info.model, device_networking.ip) device_info = DeviceData(device, product_info.model, device_networking.ip)
self.api = RoborockLocalClient(device_info) self.api = RoborockLocalClient(device_info)
self.device_specification = DeviceInfo(
name=self.device_info.device.name,
identifiers={(DOMAIN, self.device_info.device.duid)},
manufacturer="Roborock",
model=self.device_info.product.model,
sw_version=self.device_info.device.fv,
)
async def release(self) -> None: async def release(self) -> None:
"""Disconnect from API.""" """Disconnect from API."""

View file

@ -4,17 +4,46 @@ from typing import Any
from roborock.containers import Status from roborock.containers import Status
from roborock.exceptions import RoborockException from roborock.exceptions import RoborockException
from roborock.local_api import RoborockLocalClient
from roborock.roborock_typing import RoborockCommand from roborock.roborock_typing import RoborockCommand
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo, Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import RoborockDataUpdateCoordinator from . import RoborockDataUpdateCoordinator
from .const import DOMAIN
class RoborockCoordinatedEntity(CoordinatorEntity[RoborockDataUpdateCoordinator]): class RoborockEntity(Entity):
"""Representation of a base Roborock Entity."""
_attr_has_entity_name = True
def __init__(
self, unique_id: str, device_info: DeviceInfo, api: RoborockLocalClient
) -> None:
"""Initialize the coordinated Roborock Device."""
self._attr_unique_id = unique_id
self._attr_device_info = device_info
self._api = api
async def send(
self, command: RoborockCommand, params: dict[str, Any] | list[Any] | None = None
) -> dict:
"""Send a command to a vacuum cleaner."""
try:
response = await self._api.send_command(command, params)
except RoborockException as err:
raise HomeAssistantError(
f"Error while calling {command.name} with {params}"
) from err
return response
class RoborockCoordinatedEntity(
RoborockEntity, CoordinatorEntity[RoborockDataUpdateCoordinator]
):
"""Representation of a base a coordinated Roborock Entity.""" """Representation of a base a coordinated Roborock Entity."""
_attr_has_entity_name = True _attr_has_entity_name = True
@ -25,7 +54,13 @@ class RoborockCoordinatedEntity(CoordinatorEntity[RoborockDataUpdateCoordinator]
coordinator: RoborockDataUpdateCoordinator, coordinator: RoborockDataUpdateCoordinator,
) -> None: ) -> None:
"""Initialize the coordinated Roborock Device.""" """Initialize the coordinated Roborock Device."""
super().__init__(coordinator) RoborockEntity.__init__(
self,
unique_id=unique_id,
device_info=coordinator.device_specification,
api=coordinator.api,
)
CoordinatorEntity.__init__(self, coordinator=coordinator)
self._attr_unique_id = unique_id self._attr_unique_id = unique_id
@property @property
@ -37,28 +72,3 @@ class RoborockCoordinatedEntity(CoordinatorEntity[RoborockDataUpdateCoordinator]
if status: if status:
return status return status
return Status({}) return Status({})
@property
def device_info(self) -> DeviceInfo:
"""Return the device info."""
return DeviceInfo(
name=self.coordinator.device_info.device.name,
identifiers={(DOMAIN, self.coordinator.device_info.device.duid)},
manufacturer="Roborock",
model=self.coordinator.device_info.product.model,
sw_version=self.coordinator.device_info.device.fv,
)
async def send(
self, command: RoborockCommand, params: dict[str, Any] | list[Any] | None = None
) -> dict:
"""Send a command to a vacuum cleaner."""
try:
response = await self.coordinator.api.send_command(command, params)
except RoborockException as err:
raise HomeAssistantError(
f"Error while calling {command.name} with {params}"
) from err
await self.coordinator.async_request_refresh()
return response

View file

@ -15,7 +15,7 @@ from homeassistant.util import slugify
from .const import DOMAIN from .const import DOMAIN
from .coordinator import RoborockDataUpdateCoordinator from .coordinator import RoborockDataUpdateCoordinator
from .device import RoborockCoordinatedEntity from .device import RoborockEntity
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -25,11 +25,11 @@ class RoborockSwitchDescriptionMixin:
"""Define an entity description mixin for switch entities.""" """Define an entity description mixin for switch entities."""
# Gets the status of the switch # Gets the status of the switch
get_value: Callable[[RoborockCoordinatedEntity], Coroutine[Any, Any, dict]] get_value: Callable[[RoborockEntity], Coroutine[Any, Any, dict]]
# Evaluate the result of get_value to determine a bool # Evaluate the result of get_value to determine a bool
evaluate_value: Callable[[dict], bool] evaluate_value: Callable[[dict], bool]
# Sets the status of the switch # Sets the status of the switch
set_command: Callable[[RoborockCoordinatedEntity, bool], Coroutine[Any, Any, dict]] set_command: Callable[[RoborockEntity, bool], Coroutine[Any, Any, dict]]
@dataclass @dataclass
@ -78,7 +78,7 @@ async def async_setup_entry(
) )
class RoborockSwitchEntity(RoborockCoordinatedEntity, SwitchEntity): class RoborockSwitchEntity(RoborockEntity, SwitchEntity):
"""A class to let you turn functionality on Roborock devices on and off.""" """A class to let you turn functionality on Roborock devices on and off."""
entity_description: RoborockSwitchDescription entity_description: RoborockSwitchDescription
@ -91,17 +91,15 @@ class RoborockSwitchEntity(RoborockCoordinatedEntity, SwitchEntity):
) -> None: ) -> None:
"""Create a switch entity.""" """Create a switch entity."""
self.entity_description = entity_description self.entity_description = entity_description
super().__init__(unique_id, coordinator) super().__init__(unique_id, coordinator.device_specification, coordinator.api)
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn off the switch.""" """Turn off the switch."""
await self.entity_description.set_command(self, False) await self.entity_description.set_command(self, False)
return self.async_schedule_update_ha_state(True)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn on the switch.""" """Turn on the switch."""
await self.entity_description.set_command(self, True) await self.entity_description.set_command(self, True)
return self.async_schedule_update_ha_state(True)
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update switch.""" """Update switch."""