Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions homeassistant/components/roborock/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
from __future__ import annotations

import asyncio
from collections.abc import Callable
from dataclasses import dataclass
import itertools
import logging
from typing import Any

from roborock.devices.traits.v1 import PropertiesApi
from roborock.devices.traits.v1.consumeable import ConsumableAttribute
from roborock.exceptions import RoborockException
from roborock.roborock_message import RoborockZeoProtocol
from roborock.roborock_typing import RoborockCommand

from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.const import EntityCategory
Expand Down Expand Up @@ -97,6 +100,41 @@ class RoborockButtonDescriptionA01(ButtonEntityDescription):
]


@dataclass(frozen=True, kw_only=True)
class RoborockDockCommandButtonDescription(ButtonEntityDescription):
"""Describes a Roborock dock command button entity."""

api_command: RoborockCommand
availability_fn: Callable[[PropertiesApi], bool]
"""Return True if this button should be created for the given device."""


DOCK_COMMAND_BUTTON_DESCRIPTIONS: list[RoborockDockCommandButtonDescription] = [
RoborockDockCommandButtonDescription(
key="dock_empty",
translation_key="dock_empty",
api_command=RoborockCommand.APP_START_COLLECT_DUST,
availability_fn=lambda api: api.dust_collection_mode is not None,
entity_registry_enabled_default=False,
),
RoborockDockCommandButtonDescription(
key="dock_wash_mop",
translation_key="dock_wash_mop",
api_command=RoborockCommand.APP_START_WASH,
# wash_towel_mode being non-None is the API proxy for "has mop washing station"
availability_fn=lambda api: api.wash_towel_mode is not None,
entity_registry_enabled_default=False,
),
RoborockDockCommandButtonDescription(
key="dock_stop_drying",
translation_key="dock_stop_drying",
api_command=RoborockCommand.APP_STOP_WASH,
Comment thread
iainswarts marked this conversation as resolved.
availability_fn=lambda api: api.wash_towel_mode is not None,
entity_registry_enabled_default=False,
),
Comment thread
iainswarts marked this conversation as resolved.
]


async def async_setup_entry(
hass: HomeAssistant,
config_entry: RoborockConfigEntry,
Expand Down Expand Up @@ -139,6 +177,13 @@ async def async_setup_entry(
if isinstance(coordinator, RoborockWashingMachineUpdateCoordinator)
for description in ZEO_BUTTON_DESCRIPTIONS
),
(
RoborockDockCommandButtonEntity(coordinator, description)
for coordinator in config_entry.runtime_data.v1
for description in DOCK_COMMAND_BUTTON_DESCRIPTIONS
if isinstance(coordinator, RoborockDataUpdateCoordinator)
if description.availability_fn(coordinator.properties_api)
),
)
)

Expand Down Expand Up @@ -233,3 +278,26 @@ async def async_press(self) -> None:
) from err
finally:
await self.coordinator.async_request_refresh()


class RoborockDockCommandButtonEntity(RoborockEntityV1, ButtonEntity):
"""A class to define Roborock dock command button entities."""

entity_description: RoborockDockCommandButtonDescription

def __init__(
self,
coordinator: RoborockDataUpdateCoordinator,
entity_description: RoborockDockCommandButtonDescription,
) -> None:
"""Create a dock command button entity."""
super().__init__(
f"{entity_description.key}_{coordinator.duid_slug}",
coordinator.dock_device_info,
api=coordinator.properties_api.command,
)
self.entity_description = entity_description

async def async_press(self, **kwargs: Any) -> None:
"""Send the dock command."""
await self.send(self.entity_description.api_command)
9 changes: 9 additions & 0 deletions homeassistant/components/roborock/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@
}
},
"button": {
"dock_empty": {
"name": "Empty"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does empty mean? Dock Empty but what does it empty? Maybe this is obvious as I don't have the device, but now it sounds very ambiguous

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it means to start emptying the robot vaccum's dust bin into the dock's dust bin. So "Empty" as a verb meaning empty the robots dust bin. The other name is to start dust connection.

Looking at some videos online, the app has a button that says "Empty" and the device speaks "Empty Dust Bin" so maybe that would be a better name?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I have a roborock with dock and when it is docked, I can push the button in the roborock app on my phone and it empties the dustbin of the robot into the dock (which is much much bigger). So it would Empty the robot into the dock

},
"dock_stop_drying": {
"name": "Stop drying"
},
"dock_wash_mop": {
"name": "Wash mop"
},
"pause": {
"name": "Pause"
},
Expand Down
2 changes: 2 additions & 0 deletions tests/components/roborock/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
NamedRoomMapping,
NetworkInfo,
RoborockBase,
RoborockDockWashTowelModeCode,
RoborockDyadStateCode,
ValleyElectricityTimer,
WorkStatusMapping,
Expand Down Expand Up @@ -374,6 +375,7 @@ def create_v1_properties(network_info: NetworkInfo) -> AsyncMock:
trait_spec=DustCollectionModeTrait
)
v1_properties.wash_towel_mode = make_mock_trait(trait_spec=WashTowelModeTrait)
v1_properties.wash_towel_mode.wash_mode = RoborockDockWashTowelModeCode.light
v1_properties.smart_wash_params = make_mock_trait(trait_spec=SmartWashParamsTrait)
v1_properties.home = make_home_trait(
map_info=MULTI_MAP_LIST.map_info,
Expand Down
Loading