Home Assistant Unofficial Reference 2024.12.1
vacuum.py
Go to the documentation of this file.
1 """Support for Roborock vacuum class."""
2 
3 from dataclasses import asdict
4 from typing import Any
5 
6 from roborock.code_mappings import RoborockStateCode
7 from roborock.roborock_message import RoborockDataProtocol
8 from roborock.roborock_typing import RoborockCommand
9 
11  STATE_CLEANING,
12  STATE_DOCKED,
13  STATE_ERROR,
14  STATE_IDLE,
15  STATE_PAUSED,
16  STATE_RETURNING,
17  StateVacuumEntity,
18  VacuumEntityFeature,
19 )
20 from homeassistant.core import HomeAssistant, ServiceResponse, SupportsResponse
21 from homeassistant.helpers import entity_platform
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 
24 from . import RoborockConfigEntry
25 from .const import DOMAIN, GET_MAPS_SERVICE_NAME
26 from .coordinator import RoborockDataUpdateCoordinator
27 from .entity import RoborockCoordinatedEntityV1
28 
29 STATE_CODE_TO_STATE = {
30  RoborockStateCode.starting: STATE_IDLE, # "Starting"
31  RoborockStateCode.charger_disconnected: STATE_IDLE, # "Charger disconnected"
32  RoborockStateCode.idle: STATE_IDLE, # "Idle"
33  RoborockStateCode.remote_control_active: STATE_CLEANING, # "Remote control active"
34  RoborockStateCode.cleaning: STATE_CLEANING, # "Cleaning"
35  RoborockStateCode.returning_home: STATE_RETURNING, # "Returning home"
36  RoborockStateCode.manual_mode: STATE_CLEANING, # "Manual mode"
37  RoborockStateCode.charging: STATE_DOCKED, # "Charging"
38  RoborockStateCode.charging_problem: STATE_ERROR, # "Charging problem"
39  RoborockStateCode.paused: STATE_PAUSED, # "Paused"
40  RoborockStateCode.spot_cleaning: STATE_CLEANING, # "Spot cleaning"
41  RoborockStateCode.error: STATE_ERROR, # "Error"
42  RoborockStateCode.shutting_down: STATE_IDLE, # "Shutting down"
43  RoborockStateCode.updating: STATE_DOCKED, # "Updating"
44  RoborockStateCode.docking: STATE_RETURNING, # "Docking"
45  RoborockStateCode.going_to_target: STATE_CLEANING, # "Going to target"
46  RoborockStateCode.zoned_cleaning: STATE_CLEANING, # "Zoned cleaning"
47  RoborockStateCode.segment_cleaning: STATE_CLEANING, # "Segment cleaning"
48  RoborockStateCode.emptying_the_bin: STATE_DOCKED, # "Emptying the bin" on s7+
49  RoborockStateCode.washing_the_mop: STATE_DOCKED, # "Washing the mop" on s7maxV
50  RoborockStateCode.going_to_wash_the_mop: STATE_RETURNING, # "Going to wash the mop" on s7maxV
51  RoborockStateCode.charging_complete: STATE_DOCKED, # "Charging complete"
52  RoborockStateCode.device_offline: STATE_ERROR, # "Device offline"
53 }
54 
55 
57  hass: HomeAssistant,
58  config_entry: RoborockConfigEntry,
59  async_add_entities: AddEntitiesCallback,
60 ) -> None:
61  """Set up the Roborock sensor."""
63  RoborockVacuum(coordinator)
64  for coordinator in config_entry.runtime_data.v1
65  if isinstance(coordinator, RoborockDataUpdateCoordinator)
66  )
67 
68  platform = entity_platform.async_get_current_platform()
69 
70  platform.async_register_entity_service(
71  GET_MAPS_SERVICE_NAME,
72  None,
73  RoborockVacuum.get_maps.__name__,
74  supports_response=SupportsResponse.ONLY,
75  )
76 
77 
79  """General Representation of a Roborock vacuum."""
80 
81  _attr_icon = "mdi:robot-vacuum"
82  _attr_supported_features = (
83  VacuumEntityFeature.PAUSE
84  | VacuumEntityFeature.STOP
85  | VacuumEntityFeature.RETURN_HOME
86  | VacuumEntityFeature.FAN_SPEED
87  | VacuumEntityFeature.BATTERY
88  | VacuumEntityFeature.SEND_COMMAND
89  | VacuumEntityFeature.LOCATE
90  | VacuumEntityFeature.CLEAN_SPOT
91  | VacuumEntityFeature.STATE
92  | VacuumEntityFeature.START
93  )
94  _attr_translation_key = DOMAIN
95  _attr_name = None
96 
97  def __init__(
98  self,
99  coordinator: RoborockDataUpdateCoordinator,
100  ) -> None:
101  """Initialize a vacuum."""
102  StateVacuumEntity.__init__(self)
103  RoborockCoordinatedEntityV1.__init__(
104  self,
105  coordinator.duid_slug,
106  coordinator,
107  listener_request=[
108  RoborockDataProtocol.FAN_POWER,
109  RoborockDataProtocol.STATE,
110  ],
111  )
112  self._attr_fan_speed_list_attr_fan_speed_list = self._device_status_device_status.fan_power_options
113 
114  @property
115  def state(self) -> str | None:
116  """Return the status of the vacuum cleaner."""
117  assert self._device_status_device_status.state is not None
118  return STATE_CODE_TO_STATE.get(self._device_status_device_status.state)
119 
120  @property
121  def battery_level(self) -> int | None:
122  """Return the battery level of the vacuum cleaner."""
123  return self._device_status_device_status.battery
124 
125  @property
126  def fan_speed(self) -> str | None:
127  """Return the fan speed of the vacuum cleaner."""
128  return self._device_status_device_status.fan_power_name
129 
130  async def async_start(self) -> None:
131  """Start the vacuum."""
132  if self._device_status_device_status.in_cleaning == 2:
133  await self.sendsendsend(RoborockCommand.RESUME_ZONED_CLEAN)
134  elif self._device_status_device_status.in_cleaning == 3:
135  await self.sendsendsend(RoborockCommand.RESUME_SEGMENT_CLEAN)
136  else:
137  await self.sendsendsend(RoborockCommand.APP_START)
138 
139  async def async_pause(self) -> None:
140  """Pause the vacuum."""
141  await self.sendsendsend(RoborockCommand.APP_PAUSE)
142 
143  async def async_stop(self, **kwargs: Any) -> None:
144  """Stop the vacuum."""
145  await self.sendsendsend(RoborockCommand.APP_STOP)
146 
147  async def async_return_to_base(self, **kwargs: Any) -> None:
148  """Send vacuum back to base."""
149  await self.sendsendsend(RoborockCommand.APP_CHARGE)
150 
151  async def async_clean_spot(self, **kwargs: Any) -> None:
152  """Spot clean."""
153  await self.sendsendsend(RoborockCommand.APP_SPOT)
154 
155  async def async_locate(self, **kwargs: Any) -> None:
156  """Locate vacuum."""
157  await self.sendsendsend(RoborockCommand.FIND_ME)
158 
159  async def async_set_fan_speed(self, fan_speed: str, **kwargs: Any) -> None:
160  """Set vacuum fan speed."""
161  await self.sendsendsend(
162  RoborockCommand.SET_CUSTOM_MODE,
163  [self._device_status_device_status.get_fan_speed_code(fan_speed)],
164  )
165 
167  self,
168  command: str,
169  params: dict[str, Any] | list[Any] | None = None,
170  **kwargs: Any,
171  ) -> None:
172  """Send a command to a vacuum cleaner."""
173  await self.sendsendsend(command, params)
174 
175  async def get_maps(self) -> ServiceResponse:
176  """Get map information such as map id and room ids."""
177  return {
178  "maps": [
179  asdict(vacuum_map) for vacuum_map in self.coordinator.maps.values()
180  ]
181  }
dict send(self, RoborockCommand|str command, dict[str, Any]|list[Any]|int|None params=None)
Definition: entity.py:153
dict send(self, RoborockCommand|str command, dict[str, Any]|list[Any]|int|None params=None)
Definition: entity.py:60
None __init__(self, RoborockDataUpdateCoordinator coordinator)
Definition: vacuum.py:100
None async_send_command(self, str command, dict[str, Any]|list[Any]|None params=None, **Any kwargs)
Definition: vacuum.py:171
None async_set_fan_speed(self, str fan_speed, **Any kwargs)
Definition: vacuum.py:159
None async_setup_entry(HomeAssistant hass, RoborockConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: vacuum.py:60