Add non coordinated Entity to Roborock (#93841)
switch to non coordinator entity
This commit is contained in:
parent
8cd8355ab1
commit
81561d4d3e
3 changed files with 52 additions and 36 deletions
|
@ -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."""
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue