Home Assistant Unofficial Reference 2024.12.1
switch.py
Go to the documentation of this file.
1 """Support for ThinkingCleaner switches."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import time
7 from typing import Any
8 
9 from pythinkingcleaner import Discovery, ThinkingCleaner
10 import voluptuous as vol
11 
12 from homeassistant import util
14  PLATFORM_SCHEMA as SWITCH_PLATFORM_SCHEMA,
15  SwitchEntity,
16  SwitchEntityDescription,
17 )
18 from homeassistant.const import CONF_HOST, STATE_OFF, STATE_ON
19 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
23 
24 MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10)
25 MIN_TIME_BETWEEN_FORCED_SCANS = timedelta(milliseconds=100)
26 
27 MIN_TIME_TO_WAIT = timedelta(seconds=5)
28 MIN_TIME_TO_LOCK_UPDATE = 5
29 
30 SWITCH_TYPES: tuple[SwitchEntityDescription, ...] = (
32  key="clean",
33  name="Clean",
34  ),
36  key="dock",
37  name="Dock",
38  ),
40  key="find",
41  name="Find",
42  ),
43 )
44 
45 PLATFORM_SCHEMA = SWITCH_PLATFORM_SCHEMA.extend({vol.Optional(CONF_HOST): cv.string})
46 
47 
49  hass: HomeAssistant,
50  config: ConfigType,
51  add_entities: AddEntitiesCallback,
52  discovery_info: DiscoveryInfoType | None = None,
53 ) -> None:
54  """Set up the ThinkingCleaner platform."""
55  if host := config.get(CONF_HOST):
56  devices = [ThinkingCleaner(host, "unknown")]
57  else:
58  discovery = Discovery()
59  devices = discovery.discover()
60 
61  @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS)
62  def update_devices():
63  """Update all devices."""
64  for device_object in devices:
65  device_object.update()
66 
67  entities = [
68  ThinkingCleanerSwitch(device, update_devices, description)
69  for device in devices
70  for description in SWITCH_TYPES
71  ]
72 
73  add_entities(entities)
74 
75 
77  """ThinkingCleaner Switch (dock, clean, find me)."""
78 
79  def __init__(
80  self, tc_object, update_devices, description: SwitchEntityDescription
81  ) -> None:
82  """Initialize the ThinkingCleaner."""
83  self.entity_descriptionentity_description = description
84 
85  self._update_devices_update_devices = update_devices
86  self._tc_object_tc_object = tc_object
87  self._state_state = (
88  self._tc_object_tc_object.is_cleaning if description.key == "clean" else False
89  )
90  self.locklock = False
91  self.last_lock_timelast_lock_time = None
92  self.graceful_stategraceful_state = False
93 
94  self._attr_name_attr_name = f"{tc_object.name} {description.name}"
95 
96  def lock_update(self):
97  """Lock the update since TC clean takes some time to update."""
98  if self.is_update_lockedis_update_locked():
99  return
100  self.locklock = True
101  self.last_lock_timelast_lock_time = time.time()
102 
103  def reset_update_lock(self):
104  """Reset the update lock."""
105  self.locklock = False
106  self.last_lock_timelast_lock_time = None
107 
108  def set_graceful_lock(self, state):
109  """Set the graceful state."""
110  self.graceful_stategraceful_state = state
111  self.reset_update_lockreset_update_lock()
112  self.lock_updatelock_update()
113 
114  def is_update_locked(self):
115  """Check if the update method is locked."""
116  if self.last_lock_timelast_lock_time is None:
117  return False
118 
119  if time.time() - self.last_lock_timelast_lock_time >= MIN_TIME_TO_LOCK_UPDATE:
120  self.last_lock_timelast_lock_time = None
121  return False
122 
123  return True
124 
125  @property
126  def is_on(self):
127  """Return true if device is on."""
128  if self.entity_descriptionentity_description.key == "clean":
129  return (
130  self.graceful_stategraceful_state
131  if self.is_update_lockedis_update_locked()
132  else self._tc_object_tc_object.is_cleaning
133  )
134 
135  return False
136 
137  def turn_on(self, **kwargs: Any) -> None:
138  """Turn the device on."""
139  sensor_type = self.entity_descriptionentity_description.key
140  if sensor_type == "clean":
141  self.set_graceful_lockset_graceful_lock(True)
142  self._tc_object_tc_object.start_cleaning()
143  elif sensor_type == "dock":
144  self._tc_object_tc_object.dock()
145  elif sensor_type == "find":
146  self._tc_object_tc_object.find_me()
147 
148  def turn_off(self, **kwargs: Any) -> None:
149  """Turn the device off."""
150  if self.entity_descriptionentity_description.key == "clean":
151  self.set_graceful_lockset_graceful_lock(False)
152  self._tc_object_tc_object.stop_cleaning()
153 
154  def update(self) -> None:
155  """Update the switch state (Only for clean)."""
156  if self.entity_descriptionentity_description.key == "clean" and not self.is_update_lockedis_update_locked():
157  self._tc_object_tc_object.update()
158  self._state_state = STATE_ON if self._tc_object_tc_object.is_cleaning else STATE_OFF
None __init__(self, tc_object, update_devices, SwitchEntityDescription description)
Definition: switch.py:81
None update_devices(HomeAssistant hass, ConfigEntry config_entry, dict[int, Roller] api)
Definition: helpers.py:47
None add_entities(AsusWrtRouter router, AddEntitiesCallback async_add_entities, set[str] tracked)
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: switch.py:53