Home Assistant Unofficial Reference 2024.12.1
vacuum.py
Go to the documentation of this file.
1 """Support for vacuum entities."""
2 
3 from __future__ import annotations
4 
5 from enum import StrEnum
6 import logging
7 
8 from thinqconnect import DeviceType
9 from thinqconnect.integration import ExtendedProperty
10 
12  STATE_CLEANING,
13  STATE_DOCKED,
14  STATE_ERROR,
15  STATE_RETURNING,
16  StateVacuumEntity,
17  StateVacuumEntityDescription,
18  VacuumEntityFeature,
19 )
20 from homeassistant.const import STATE_IDLE, STATE_PAUSED
21 from homeassistant.core import HomeAssistant
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 
24 from . import ThinqConfigEntry
25 from .entity import ThinQEntity
26 
27 DEVICE_TYPE_VACUUM_MAP: dict[DeviceType, tuple[StateVacuumEntityDescription, ...]] = {
28  DeviceType.ROBOT_CLEANER: (
30  key=ExtendedProperty.VACUUM,
31  name=None,
32  ),
33  ),
34 }
35 
36 
37 class State(StrEnum):
38  """State of device."""
39 
40  HOMING = "homing"
41  PAUSE = "pause"
42  RESUME = "resume"
43  SLEEP = "sleep"
44  START = "start"
45  WAKE_UP = "wake_up"
46 
47 
48 ROBOT_STATUS_TO_HA = {
49  "charging": STATE_DOCKED,
50  "diagnosis": STATE_IDLE,
51  "homing": STATE_RETURNING,
52  "initializing": STATE_IDLE,
53  "macrosector": STATE_IDLE,
54  "monitoring_detecting": STATE_IDLE,
55  "monitoring_moving": STATE_IDLE,
56  "monitoring_positioning": STATE_IDLE,
57  "pause": STATE_PAUSED,
58  "reservation": STATE_IDLE,
59  "setdate": STATE_IDLE,
60  "sleep": STATE_IDLE,
61  "standby": STATE_IDLE,
62  "working": STATE_CLEANING,
63  "error": STATE_ERROR,
64 }
65 ROBOT_BATT_TO_HA = {
66  "moveless": 5,
67  "dock_level": 5,
68  "low": 30,
69  "mid": 50,
70  "high": 90,
71  "full": 100,
72  "over_charge": 100,
73 }
74 _LOGGER = logging.getLogger(__name__)
75 
76 
78  hass: HomeAssistant,
79  entry: ThinqConfigEntry,
80  async_add_entities: AddEntitiesCallback,
81 ) -> None:
82  """Set up an entry for vacuum platform."""
83  entities: list[ThinQStateVacuumEntity] = []
84  for coordinator in entry.runtime_data.coordinators.values():
85  if (
86  descriptions := DEVICE_TYPE_VACUUM_MAP.get(
87  coordinator.api.device.device_type
88  )
89  ) is not None:
90  for description in descriptions:
91  entities.extend(
92  ThinQStateVacuumEntity(coordinator, description, property_id)
93  for property_id in coordinator.api.get_active_idx(description.key)
94  )
95 
96  if entities:
97  async_add_entities(entities)
98 
99 
101  """Represent a thinq vacuum platform."""
102 
103  _attr_supported_features = (
104  VacuumEntityFeature.SEND_COMMAND
105  | VacuumEntityFeature.STATE
106  | VacuumEntityFeature.BATTERY
107  | VacuumEntityFeature.START
108  | VacuumEntityFeature.PAUSE
109  | VacuumEntityFeature.RETURN_HOME
110  )
111 
112  def _update_status(self) -> None:
113  """Update status itself."""
114  super()._update_status()
115 
116  # Update state.
117  self._attr_state_attr_state = ROBOT_STATUS_TO_HA[self.datadatadatadata.current_state]
118 
119  # Update battery.
120  if (level := self.datadatadatadata.battery) is not None:
121  self._attr_battery_level_attr_battery_level = (
122  level if isinstance(level, int) else ROBOT_BATT_TO_HA.get(level, 0)
123  )
124 
125  _LOGGER.debug(
126  "[%s:%s] update status: %s -> %s (battery_level=%s)",
127  self.coordinator.device_name,
128  self.property_idproperty_id,
129  self.datadatadatadata.current_state,
130  self.statestatestatestate,
131  self.battery_levelbattery_level,
132  )
133 
134  async def async_start(self, **kwargs) -> None:
135  """Start the device."""
136  if self.datadatadatadata.current_state == State.SLEEP:
137  value = State.WAKE_UP
138  elif self._attr_state_attr_state == STATE_PAUSED:
139  value = State.RESUME
140  else:
141  value = State.START
142 
143  _LOGGER.debug(
144  "[%s:%s] async_start", self.coordinator.device_name, self.property_idproperty_id
145  )
146  await self.async_call_apiasync_call_api(
147  self.coordinator.api.async_set_clean_operation_mode(self.property_idproperty_id, value)
148  )
149 
150  async def async_pause(self, **kwargs) -> None:
151  """Pause the device."""
152  _LOGGER.debug(
153  "[%s:%s] async_pause", self.coordinator.device_name, self.property_idproperty_id
154  )
155  await self.async_call_apiasync_call_api(
156  self.coordinator.api.async_set_clean_operation_mode(
157  self.property_idproperty_id, State.PAUSE
158  )
159  )
160 
161  async def async_return_to_base(self, **kwargs) -> None:
162  """Return device to dock."""
163  _LOGGER.debug(
164  "[%s:%s] async_return_to_base",
165  self.coordinator.device_name,
166  self.property_idproperty_id,
167  )
168  await self.async_call_apiasync_call_api(
169  self.coordinator.api.async_set_clean_operation_mode(
170  self.property_idproperty_id, State.HOMING
171  )
172  )
None async_call_api(self, Coroutine[Any, Any, Any] target, Callable[[], None]|None on_fail_method=None)
Definition: entity.py:101
None async_setup_entry(HomeAssistant hass, ThinqConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: vacuum.py:81