1 """Shark IQ Wrapper."""
3 from __future__
import annotations
5 from collections.abc
import Iterable
8 from sharkiq
import OperatingModes, PowerModes, Properties, SharkIqVacuum
9 import voluptuous
as vol
29 from .const
import DOMAIN, LOGGER, SERVICE_CLEAN_ROOM, SHARK
30 from .coordinator
import SharkIqUpdateCoordinator
32 OPERATING_STATE_MAP = {
33 OperatingModes.PAUSE: STATE_PAUSED,
34 OperatingModes.START: STATE_CLEANING,
35 OperatingModes.STOP: STATE_IDLE,
36 OperatingModes.RETURN: STATE_RETURNING,
40 "Eco": PowerModes.ECO,
41 "Normal": PowerModes.NORMAL,
42 "Max": PowerModes.MAX,
45 STATE_RECHARGING_TO_RESUME =
"recharging_to_resume"
48 ATTR_ERROR_CODE =
"last_error_code"
49 ATTR_ERROR_MSG =
"last_error_message"
50 ATTR_LOW_LIGHT =
"low_light"
51 ATTR_RECHARGE_RESUME =
"recharge_and_resume"
57 config_entry: ConfigEntry,
58 async_add_entities: AddEntitiesCallback,
60 """Set up the Shark IQ vacuum cleaner."""
61 coordinator: SharkIqUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
62 devices: Iterable[SharkIqVacuum] = coordinator.shark_vacs.values()
63 device_names = [d.name
for d
in devices]
65 "Found %d Shark IQ device(s): %s",
67 ", ".join([d.name
for d
in devices]),
71 platform = entity_platform.async_get_current_platform()
72 platform.async_register_entity_service(
75 vol.Required(ATTR_ROOMS): vol.All(
76 cv.ensure_list, vol.Length(min=1), [cv.string]
84 """Shark IQ vacuum entity."""
86 _attr_fan_speed_list =
list(FAN_SPEEDS_MAP)
87 _attr_has_entity_name =
True
89 _attr_supported_features = (
90 VacuumEntityFeature.BATTERY
91 | VacuumEntityFeature.FAN_SPEED
92 | VacuumEntityFeature.PAUSE
93 | VacuumEntityFeature.RETURN_HOME
94 | VacuumEntityFeature.START
95 | VacuumEntityFeature.STATE
96 | VacuumEntityFeature.STOP
97 | VacuumEntityFeature.LOCATE
99 _unrecorded_attributes = frozenset({ATTR_ROOMS})
102 self, sharkiq: SharkIqVacuum, coordinator: SharkIqUpdateCoordinator
104 """Create a new SharkVacuumEntity."""
109 identifiers={(DOMAIN, sharkiq.serial_number)},
111 model=self.
modelmodel,
113 sw_version=sharkiq.get_property_value(Properties.ROBOT_FIRMWARE_VERSION),
117 """Clean a spot. Not yet implemented."""
118 raise NotImplementedError
123 params: dict[str, Any] | list[Any] |
None =
None,
126 """Send a command to the vacuum. Not yet implemented."""
127 raise NotImplementedError
131 """Tell us if the device is online."""
136 """Vacuum model number."""
137 if self.
sharkiqsharkiq.vac_model_number:
138 return self.
sharkiqsharkiq.vac_model_number
139 return self.
sharkiqsharkiq.oem_model_number
143 """Return the last observed error code (or None)."""
144 return self.
sharkiqsharkiq.error_code
148 """Return the last observed error message (or None)."""
151 return self.
sharkiqsharkiq.error_text
155 """Operating mode."""
156 op_mode = self.
sharkiqsharkiq.get_property_value(Properties.OPERATING_MODE)
157 return OPERATING_STATE_MAP.get(op_mode)
161 """Return True if vacuum set to recharge and resume cleaning."""
162 return self.
sharkiqsharkiq.get_property_value(Properties.RECHARGING_TO_RESUME)
166 """Get the current vacuum state.
168 NB: Currently, we do not return an error state because they can be very, very stale.
169 In the app, these are (usually) handled by showing the robot as stopped and sending the
172 if self.
sharkiqsharkiq.get_property_value(Properties.CHARGING_STATUS):
178 """Determine if the sensor is available based on API results."""
180 return self.coordinator.last_update_success
and self.
is_onlineis_online
184 """Get the current battery level."""
185 return self.
sharkiqsharkiq.get_property_value(Properties.BATTERY_CAPACITY)
188 """Have the device return to base."""
189 await self.
sharkiqsharkiq.async_set_operating_mode(OperatingModes.RETURN)
193 """Pause the cleaning task."""
194 await self.
sharkiqsharkiq.async_set_operating_mode(OperatingModes.PAUSE)
198 """Start the device."""
199 await self.
sharkiqsharkiq.async_set_operating_mode(OperatingModes.START)
203 """Stop the device."""
204 await self.
sharkiqsharkiq.async_set_operating_mode(OperatingModes.STOP)
208 """Cause the device to generate a loud chirp."""
209 await self.
sharkiqsharkiq.async_find_device()
212 """Clean specific rooms."""
215 rooms = [room.replace(
"_",
" ").title()
for room
in rooms]
217 if room
in valid_rooms:
218 rooms_to_clean.append(room)
221 translation_domain=DOMAIN,
222 translation_key=
"invalid_room",
223 translation_placeholders={
"room": room},
226 LOGGER.debug(
"Cleaning room(s): %s", rooms_to_clean)
227 await self.
sharkiqsharkiq.async_clean_rooms(rooms_to_clean)
232 """Return the current fan speed."""
234 speed_level = self.
sharkiqsharkiq.get_property_value(Properties.POWER_MODE)
235 for k, val
in FAN_SPEEDS_MAP.items():
236 if val == speed_level:
241 """Set the fan speed."""
242 await self.
sharkiqsharkiq.async_set_property_value(
243 Properties.POWER_MODE, FAN_SPEEDS_MAP.get(fan_speed.capitalize())
250 """Recharge and resume mode active."""
251 return self.
sharkiqsharkiq.get_property_value(Properties.RECHARGE_RESUME)
255 """Get the WiFi RSSI."""
256 return self.
sharkiqsharkiq.get_property_value(Properties.RSSI)
260 """Let us know if the robot is operating in low-light mode."""
261 return self.
sharkiqsharkiq.get_property_value(Properties.LOW_LIGHT_MISSION)
265 """Return a list of rooms available to clean."""
266 room_list = self.
sharkiqsharkiq.get_property_value(Properties.ROBOT_ROOM_LIST)
268 return room_list.split(
":")[1:]
273 """Return a dictionary of device state attributes specific to sharkiq."""
276 ATTR_ERROR_MSG: self.
sharkiqsharkiq.error_text,
bool device_is_online(self, str dsn)
None async_return_to_base(self, **Any kwargs)
None async_clean_room(self, list[str] rooms, **Any kwargs)
int|None error_code(self)
dict[str, Any] extra_state_attributes(self)
None async_stop(self, **Any kwargs)
None __init__(self, SharkIqVacuum sharkiq, SharkIqUpdateCoordinator coordinator)
int|None recharging_to_resume(self)
None async_set_fan_speed(self, str fan_speed, **Any kwargs)
str|None operating_mode(self)
list|None available_rooms(self)
str|None error_message(self)
None clean_spot(self, **Any kwargs)
bool|None recharge_resume(self)
int|None battery_level(self)
None send_command(self, str command, dict[str, Any]|list[Any]|None params=None, **Any kwargs)
None async_locate(self, **Any kwargs)
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)