Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for Roborock switch."""
2 
3 from __future__ import annotations
4 
5 import asyncio
6 from collections.abc import Callable, Coroutine
7 from dataclasses import dataclass
8 import logging
9 from typing import Any
10 
11 from roborock.command_cache import CacheableAttribute
12 from roborock.exceptions import RoborockException
13 from roborock.version_1_apis.roborock_client_v1 import AttributeCache
14 
15 from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
16 from homeassistant.const import EntityCategory
17 from homeassistant.core import HomeAssistant
18 from homeassistant.exceptions import HomeAssistantError
19 from homeassistant.helpers.entity_platform import AddEntitiesCallback
20 
21 from . import DOMAIN, RoborockConfigEntry
22 from .coordinator import RoborockDataUpdateCoordinator
23 from .entity import RoborockEntityV1
24 
25 _LOGGER = logging.getLogger(__name__)
26 
27 
28 @dataclass(frozen=True, kw_only=True)
30  """Class to describe a Roborock switch entity."""
31 
32  # Gets the status of the switch
33  cache_key: CacheableAttribute
34  # Sets the status of the switch
35  update_value: Callable[[AttributeCache, bool], Coroutine[Any, Any, None]]
36  # Attribute from cache
37  attribute: str
38 
39 
40 SWITCH_DESCRIPTIONS: list[RoborockSwitchDescription] = [
42  cache_key=CacheableAttribute.child_lock_status,
43  update_value=lambda cache, value: cache.update_value(
44  {"lock_status": 1 if value else 0}
45  ),
46  attribute="lock_status",
47  key="child_lock",
48  translation_key="child_lock",
49  entity_category=EntityCategory.CONFIG,
50  ),
52  cache_key=CacheableAttribute.flow_led_status,
53  update_value=lambda cache, value: cache.update_value(
54  {"status": 1 if value else 0}
55  ),
56  attribute="status",
57  key="status_indicator",
58  translation_key="status_indicator",
59  entity_category=EntityCategory.CONFIG,
60  ),
62  cache_key=CacheableAttribute.dnd_timer,
63  update_value=lambda cache, value: cache.update_value(
64  [
65  cache.value.get("start_hour"),
66  cache.value.get("start_minute"),
67  cache.value.get("end_hour"),
68  cache.value.get("end_minute"),
69  ]
70  )
71  if value
72  else cache.close_value(),
73  attribute="enabled",
74  key="dnd_switch",
75  translation_key="dnd_switch",
76  entity_category=EntityCategory.CONFIG,
77  ),
79  cache_key=CacheableAttribute.valley_electricity_timer,
80  update_value=lambda cache, value: cache.update_value(
81  [
82  cache.value.get("start_hour"),
83  cache.value.get("start_minute"),
84  cache.value.get("end_hour"),
85  cache.value.get("end_minute"),
86  ]
87  )
88  if value
89  else cache.close_value(),
90  attribute="enabled",
91  key="off_peak_switch",
92  translation_key="off_peak_switch",
93  entity_category=EntityCategory.CONFIG,
94  entity_registry_enabled_default=False,
95  ),
96 ]
97 
98 
100  hass: HomeAssistant,
101  config_entry: RoborockConfigEntry,
102  async_add_entities: AddEntitiesCallback,
103 ) -> None:
104  """Set up Roborock switch platform."""
105  possible_entities: list[
106  tuple[RoborockDataUpdateCoordinator, RoborockSwitchDescription]
107  ] = [
108  (coordinator, description)
109  for coordinator in config_entry.runtime_data.v1
110  for description in SWITCH_DESCRIPTIONS
111  ]
112  # We need to check if this function is supported by the device.
113  results = await asyncio.gather(
114  *(
115  coordinator.api.get_from_cache(description.cache_key)
116  for coordinator, description in possible_entities
117  ),
118  return_exceptions=True,
119  )
120  valid_entities: list[RoborockSwitch] = []
121  for (coordinator, description), result in zip(
122  possible_entities, results, strict=False
123  ):
124  if result is None or isinstance(result, Exception):
125  _LOGGER.debug("Not adding entity because of %s", result)
126  else:
127  valid_entities.append(
129  f"{description.key}_{coordinator.duid_slug}",
130  coordinator,
131  description,
132  )
133  )
134  async_add_entities(valid_entities)
135 
136 
138  """A class to let you turn functionality on Roborock devices on and off that does need a coordinator."""
139 
140  entity_description: RoborockSwitchDescription
141 
142  def __init__(
143  self,
144  unique_id: str,
145  coordinator: RoborockDataUpdateCoordinator,
146  entity_description: RoborockSwitchDescription,
147  ) -> None:
148  """Initialize the entity."""
149  self.entity_descriptionentity_description = entity_description
150  super().__init__(unique_id, coordinator.device_info, coordinator.api)
151 
152  async def async_turn_off(self, **kwargs: Any) -> None:
153  """Turn off the switch."""
154  try:
155  await self.entity_descriptionentity_description.update_value(
156  self.get_cacheget_cache(self.entity_descriptionentity_description.cache_key), False
157  )
158  except RoborockException as err:
159  raise HomeAssistantError(
160  translation_domain=DOMAIN,
161  translation_key="update_options_failed",
162  ) from err
163 
164  async def async_turn_on(self, **kwargs: Any) -> None:
165  """Turn on the switch."""
166  try:
167  await self.entity_descriptionentity_description.update_value(
168  self.get_cacheget_cache(self.entity_descriptionentity_description.cache_key), True
169  )
170  except RoborockException as err:
171  raise HomeAssistantError(
172  translation_domain=DOMAIN,
173  translation_key="update_options_failed",
174  ) from err
175 
176  @property
177  def is_on(self) -> bool | None:
178  """Return True if entity is on."""
179  status = self.get_cacheget_cache(self.entity_descriptionentity_description.cache_key).value.get(
180  self.entity_descriptionentity_description.attribute
181  )
182  if status is None:
183  return status
184  return bool(status)
AttributeCache get_cache(self, CacheableAttribute attribute)
Definition: entity.py:52
None __init__(self, str unique_id, RoborockDataUpdateCoordinator coordinator, RoborockSwitchDescription entity_description)
Definition: switch.py:147
None async_setup_entry(HomeAssistant hass, RoborockConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: switch.py:103