1 """Support for vacuum cleaner robots (botvacs)."""
3 from __future__
import annotations
5 from datetime
import timedelta
6 from enum
import IntFlag
7 from functools
import partial
11 from propcache
import cached_property
12 import voluptuous
as vol
28 DeprecatedConstantEnum,
29 all_with_deprecated_constants,
30 check_if_deprecated_constant,
31 dir_with_deprecated_constants,
40 from .const
import DOMAIN, STATE_CLEANING, STATE_DOCKED, STATE_ERROR, STATE_RETURNING
42 _LOGGER = logging.getLogger(__name__)
44 DATA_COMPONENT: HassKey[EntityComponent[StateVacuumEntity]] =
HassKey(DOMAIN)
45 ENTITY_ID_FORMAT = DOMAIN +
".{}"
46 PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA
47 PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE
50 ATTR_BATTERY_ICON =
"battery_icon"
51 ATTR_CLEANED_AREA =
"cleaned_area"
52 ATTR_FAN_SPEED =
"fan_speed"
53 ATTR_FAN_SPEED_LIST =
"fan_speed_list"
54 ATTR_PARAMS =
"params"
55 ATTR_STATUS =
"status"
57 SERVICE_CLEAN_SPOT =
"clean_spot"
58 SERVICE_LOCATE =
"locate"
59 SERVICE_RETURN_TO_BASE =
"return_to_base"
60 SERVICE_SEND_COMMAND =
"send_command"
61 SERVICE_SET_FAN_SPEED =
"set_fan_speed"
62 SERVICE_START_PAUSE =
"start_pause"
63 SERVICE_START =
"start"
64 SERVICE_PAUSE =
"pause"
68 STATES = [STATE_CLEANING, STATE_DOCKED, STATE_RETURNING, STATE_ERROR]
70 DEFAULT_NAME =
"Vacuum cleaner robot"
74 """Supported features of the vacuum entity."""
95 VacuumEntityFeature.TURN_ON,
"2025.10"
98 VacuumEntityFeature.TURN_OFF,
"2025.10"
103 VacuumEntityFeature.RETURN_HOME,
"2025.10"
106 VacuumEntityFeature.FAN_SPEED,
"2025.10"
109 VacuumEntityFeature.BATTERY,
"2025.10"
112 VacuumEntityFeature.STATUS,
"2025.10"
115 VacuumEntityFeature.SEND_COMMAND,
"2025.10"
118 VacuumEntityFeature.LOCATE,
"2025.10"
121 VacuumEntityFeature.CLEAN_SPOT,
"2025.10"
131 def is_on(hass: HomeAssistant, entity_id: str) -> bool:
132 """Return if the vacuum is on based on the statemachine."""
133 return hass.states.is_state(entity_id, STATE_ON)
136 async
def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
137 """Set up the vacuum component."""
138 component = hass.data[DATA_COMPONENT] = EntityComponent[StateVacuumEntity](
139 _LOGGER, DOMAIN, hass, SCAN_INTERVAL
142 await component.async_setup(config)
144 component.async_register_entity_service(
148 [VacuumEntityFeature.START],
150 component.async_register_entity_service(
154 [VacuumEntityFeature.PAUSE],
156 component.async_register_entity_service(
157 SERVICE_RETURN_TO_BASE,
159 "async_return_to_base",
160 [VacuumEntityFeature.RETURN_HOME],
162 component.async_register_entity_service(
166 [VacuumEntityFeature.CLEAN_SPOT],
168 component.async_register_entity_service(
172 [VacuumEntityFeature.LOCATE],
174 component.async_register_entity_service(
178 [VacuumEntityFeature.STOP],
180 component.async_register_entity_service(
181 SERVICE_SET_FAN_SPEED,
182 {vol.Required(ATTR_FAN_SPEED): cv.string},
183 "async_set_fan_speed",
184 [VacuumEntityFeature.FAN_SPEED],
186 component.async_register_entity_service(
187 SERVICE_SEND_COMMAND,
189 vol.Required(ATTR_COMMAND): cv.string,
190 vol.Optional(ATTR_PARAMS): vol.Any(dict, cv.ensure_list),
192 "async_send_command",
193 [VacuumEntityFeature.SEND_COMMAND],
200 """Set up a config entry."""
205 """Unload a config entry."""
210 """A class that describes vacuum entities."""
213 STATE_VACUUM_CACHED_PROPERTIES_WITH_ATTR_ = {
214 "supported_features",
224 Entity, cached_properties=STATE_VACUUM_CACHED_PROPERTIES_WITH_ATTR_
226 """Representation of a vacuum cleaner robot that supports states."""
228 entity_description: StateVacuumEntityDescription
230 _entity_component_unrecorded_attributes = frozenset({ATTR_FAN_SPEED_LIST})
232 _attr_battery_icon: str
233 _attr_battery_level: int |
None =
None
234 _attr_fan_speed: str |
None =
None
235 _attr_fan_speed_list: list[str]
236 _attr_state: str |
None =
None
241 """Return the battery level of the vacuum cleaner."""
242 return self._attr_battery_level
246 """Return the battery icon for the vacuum cleaner."""
250 battery_level=self.
battery_levelbattery_level, charging=charging
255 """Return capability attributes."""
262 """Return the fan speed of the vacuum cleaner."""
263 return self._attr_fan_speed
267 """Get the list of available fan speed steps of the vacuum cleaner."""
268 return self._attr_fan_speed_list
272 """Return the state attributes of the vacuum cleaner."""
273 data: dict[str, Any] = {}
276 if VacuumEntityFeature.BATTERY
in supported_features:
280 if VacuumEntityFeature.FAN_SPEED
in supported_features:
281 data[ATTR_FAN_SPEED] = self.
fan_speedfan_speed
287 """Return the state of the vacuum cleaner."""
288 return self._attr_state
292 """Flag vacuum cleaner features that are supported."""
293 return self._attr_supported_features
297 """Return the supported features as VacuumEntityFeature.
299 Remove this compatibility shim in 2025.1 or later.
302 if type(features)
is int:
308 def stop(self, **kwargs: Any) ->
None:
309 """Stop the vacuum cleaner."""
310 raise NotImplementedError
313 """Stop the vacuum cleaner.
315 This method must be run in the event loop.
317 await self.
hasshass.async_add_executor_job(partial(self.
stopstop, **kwargs))
320 """Set the vacuum cleaner to return to the dock."""
321 raise NotImplementedError
324 """Set the vacuum cleaner to return to the dock.
326 This method must be run in the event loop.
328 await self.
hasshass.async_add_executor_job(partial(self.
return_to_basereturn_to_base, **kwargs))
331 """Perform a spot clean-up."""
332 raise NotImplementedError
335 """Perform a spot clean-up.
337 This method must be run in the event loop.
339 await self.
hasshass.async_add_executor_job(partial(self.
clean_spotclean_spot, **kwargs))
342 """Locate the vacuum cleaner."""
343 raise NotImplementedError
346 """Locate the vacuum cleaner.
348 This method must be run in the event loop.
350 await self.
hasshass.async_add_executor_job(partial(self.
locatelocate, **kwargs))
354 raise NotImplementedError
359 This method must be run in the event loop.
361 await self.
hasshass.async_add_executor_job(
362 partial(self.
set_fan_speedset_fan_speed, fan_speed, **kwargs)
368 params: dict[str, Any] | list[Any] |
None =
None,
371 """Send a command to a vacuum cleaner."""
372 raise NotImplementedError
377 params: dict[str, Any] | list[Any] |
None =
None,
380 """Send a command to a vacuum cleaner.
382 This method must be run in the event loop.
384 await self.
hasshass.async_add_executor_job(
385 partial(self.
send_commandsend_command, command, params=params, **kwargs)
389 """Start or resume the cleaning task."""
390 raise NotImplementedError
393 """Start or resume the cleaning task.
395 This method must be run in the event loop.
397 await self.
hasshass.async_add_executor_job(self.
startstart)
400 """Pause the cleaning task."""
401 raise NotImplementedError
404 """Pause the cleaning task.
406 This method must be run in the event loop.
408 await self.
hasshass.async_add_executor_job(self.
pausepause)
414 __getattr__ = partial(check_if_deprecated_constant, module_globals=globals())
416 dir_with_deprecated_constants, module_globals_keys=[*globals().keys()]
None return_to_base(self, **Any kwargs)
None async_stop(self, **Any kwargs)
None async_set_fan_speed(self, str fan_speed, **Any kwargs)
int|None battery_level(self)
None stop(self, **Any kwargs)
None set_fan_speed(self, str fan_speed, **Any kwargs)
list[str] fan_speed_list(self)
None async_locate(self, **Any kwargs)
None send_command(self, str command, dict[str, Any]|list[Any]|None params=None, **Any kwargs)
dict[str, Any]|None capability_attributes(self)
None async_return_to_base(self, **Any kwargs)
dict[str, Any] state_attributes(self)
None clean_spot(self, **Any kwargs)
None async_send_command(self, str command, dict[str, Any]|list[Any]|None params=None, **Any kwargs)
None locate(self, **Any kwargs)
VacuumEntityFeature supported_features(self)
None async_clean_spot(self, **Any kwargs)
VacuumEntityFeature supported_features_compat(self)
None _report_deprecated_supported_features_values(self, IntFlag replacement)
int|None supported_features(self)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
bool is_on(HomeAssistant hass, str entity_id)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup(HomeAssistant hass, ConfigType config)
list[str] all_with_deprecated_constants(dict[str, Any] module_globals)
str icon_for_battery_level(int|None battery_level=None, bool charging=False)