Home Assistant Unofficial Reference 2024.12.1
cover.py
Go to the documentation of this file.
1 """Demo platform for the cover component."""
2 
3 from __future__ import annotations
4 
5 from datetime import datetime
6 from typing import Any
7 
9  ATTR_POSITION,
10  ATTR_TILT_POSITION,
11  CoverDeviceClass,
12  CoverEntity,
13  CoverEntityFeature,
14 )
15 from homeassistant.config_entries import ConfigEntry
16 from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
17 from homeassistant.helpers.device_registry import DeviceInfo
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 from homeassistant.helpers.event import async_track_utc_time_change
20 
21 from . import DOMAIN
22 
23 
25  hass: HomeAssistant,
26  config_entry: ConfigEntry,
27  async_add_entities: AddEntitiesCallback,
28 ) -> None:
29  """Set up the demo cover platform."""
31  [
32  DemoCover(hass, "cover_1", "Kitchen Window"),
33  DemoCover(hass, "cover_2", "Hall Window", 10),
34  DemoCover(hass, "cover_3", "Living Room Window", 70, 50),
35  DemoCover(
36  hass,
37  "cover_4",
38  "Garage Door",
39  device_class=CoverDeviceClass.GARAGE,
40  supported_features=(CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE),
41  ),
42  DemoCover(
43  hass,
44  "cover_5",
45  "Pergola Roof",
46  tilt_position=60,
47  supported_features=(
48  CoverEntityFeature.OPEN_TILT
49  | CoverEntityFeature.STOP_TILT
50  | CoverEntityFeature.CLOSE_TILT
51  | CoverEntityFeature.SET_TILT_POSITION
52  ),
53  ),
54  ]
55  )
56 
57 
59  """Representation of a demo cover."""
60 
61  _attr_has_entity_name = True
62  _attr_name = None
63  _attr_should_poll = False
64 
65  def __init__(
66  self,
67  hass: HomeAssistant,
68  unique_id: str,
69  device_name: str,
70  position: int | None = None,
71  tilt_position: int | None = None,
72  device_class: CoverDeviceClass | None = None,
73  supported_features: CoverEntityFeature | None = None,
74  ) -> None:
75  """Initialize the cover."""
76  self.hasshasshass = hass
77  self._unique_id_unique_id = unique_id
78  self._position_position = position
79  self._attr_device_class_attr_device_class = device_class
80  self._attr_supported_features_attr_supported_features = supported_features
81  self._set_position_set_position: int | None = None
82  self._set_tilt_position_set_tilt_position: int | None = None
83  self._tilt_position_tilt_position = tilt_position
84  self._requested_closing_requested_closing = True
85  self._requested_closing_tilt_requested_closing_tilt = True
86  self._unsub_listener_cover_unsub_listener_cover: CALLBACK_TYPE | None = None
87  self._unsub_listener_cover_tilt_unsub_listener_cover_tilt: CALLBACK_TYPE | None = None
88  self._is_opening_is_opening = False
89  self._is_closing_is_closing = False
90  if position is None:
91  self._closed_closed = True
92  else:
93  self._closed_closed = position <= 0
94 
95  self._attr_device_info_attr_device_info = DeviceInfo(
96  identifiers={
97  # Serial numbers are unique identifiers within a specific domain
98  (DOMAIN, self.unique_idunique_idunique_id)
99  },
100  name=device_name,
101  )
102 
103  @property
104  def unique_id(self) -> str:
105  """Return unique ID for cover."""
106  return self._unique_id_unique_id
107 
108  @property
109  def current_cover_position(self) -> int | None:
110  """Return the current position of the cover."""
111  return self._position_position
112 
113  @property
114  def current_cover_tilt_position(self) -> int | None:
115  """Return the current tilt position of the cover."""
116  return self._tilt_position_tilt_position
117 
118  @property
119  def is_closed(self) -> bool:
120  """Return if the cover is closed."""
121  return self._closed_closed
122 
123  @property
124  def is_closing(self) -> bool:
125  """Return if the cover is closing."""
126  return self._is_closing_is_closing
127 
128  @property
129  def is_opening(self) -> bool:
130  """Return if the cover is opening."""
131  return self._is_opening_is_opening
132 
133  async def async_close_cover(self, **kwargs: Any) -> None:
134  """Close the cover."""
135  if self._position_position == 0:
136  return
137  if self._position_position is None:
138  self._closed_closed = True
139  self.async_write_ha_stateasync_write_ha_state()
140  return
141 
142  self._is_closing_is_closing = True
143  self._listen_cover_listen_cover()
144  self._requested_closing_requested_closing = True
145  self.async_write_ha_stateasync_write_ha_state()
146 
147  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
148  """Close the cover tilt."""
149  if self._tilt_position_tilt_position in (0, None):
150  return
151 
152  self._listen_cover_tilt_listen_cover_tilt()
153  self._requested_closing_tilt_requested_closing_tilt = True
154 
155  async def async_open_cover(self, **kwargs: Any) -> None:
156  """Open the cover."""
157  if self._position_position == 100:
158  return
159  if self._position_position is None:
160  self._closed_closed = False
161  self.async_write_ha_stateasync_write_ha_state()
162  return
163 
164  self._is_opening_is_opening = True
165  self._listen_cover_listen_cover()
166  self._requested_closing_requested_closing = False
167  self.async_write_ha_stateasync_write_ha_state()
168 
169  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
170  """Open the cover tilt."""
171  if self._tilt_position_tilt_position in (100, None):
172  return
173 
174  self._listen_cover_tilt_listen_cover_tilt()
175  self._requested_closing_tilt_requested_closing_tilt = False
176 
177  async def async_set_cover_position(self, **kwargs: Any) -> None:
178  """Move the cover to a specific position."""
179  position: int = kwargs[ATTR_POSITION]
180  self._set_position_set_position = round(position, -1)
181  if self._position_position == position:
182  return
183 
184  self._listen_cover_listen_cover()
185  self._requested_closing_requested_closing = (
186  self._position_position is not None and position < self._position_position
187  )
188 
189  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
190  """Move the cover til to a specific position."""
191  tilt_position: int = kwargs[ATTR_TILT_POSITION]
192  self._set_tilt_position_set_tilt_position = round(tilt_position, -1)
193  if self._tilt_position_tilt_position == tilt_position:
194  return
195 
196  self._listen_cover_tilt_listen_cover_tilt()
197  self._requested_closing_tilt_requested_closing_tilt = (
198  self._tilt_position_tilt_position is not None and tilt_position < self._tilt_position_tilt_position
199  )
200 
201  async def async_stop_cover(self, **kwargs: Any) -> None:
202  """Stop the cover."""
203  self._is_closing_is_closing = False
204  self._is_opening_is_opening = False
205  if self._position_position is None:
206  return
207  if self._unsub_listener_cover_unsub_listener_cover is not None:
208  self._unsub_listener_cover_unsub_listener_cover()
209  self._unsub_listener_cover_unsub_listener_cover = None
210  self._set_position_set_position = None
211 
212  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
213  """Stop the cover tilt."""
214  if self._tilt_position_tilt_position is None:
215  return
216 
217  if self._unsub_listener_cover_tilt_unsub_listener_cover_tilt is not None:
218  self._unsub_listener_cover_tilt_unsub_listener_cover_tilt()
219  self._unsub_listener_cover_tilt_unsub_listener_cover_tilt = None
220  self._set_tilt_position_set_tilt_position = None
221 
222  @callback
223  def _listen_cover(self) -> None:
224  """Listen for changes in cover."""
225  if self._unsub_listener_cover_unsub_listener_cover is None:
226  self._unsub_listener_cover_unsub_listener_cover = async_track_utc_time_change(
227  self.hasshasshass, self._time_changed_cover_time_changed_cover
228  )
229 
230  async def _time_changed_cover(self, now: datetime) -> None:
231  """Track time changes."""
232  if self._position_position is None:
233  return
234  if self._requested_closing_requested_closing:
235  self._position_position -= 10
236  else:
237  self._position_position += 10
238 
239  if self._position_position in (100, 0, self._set_position_set_position):
240  await self.async_stop_coverasync_stop_coverasync_stop_cover()
241 
242  self._closed_closed = (
244  )
245  self.async_write_ha_stateasync_write_ha_state()
246 
247  @callback
248  def _listen_cover_tilt(self) -> None:
249  """Listen for changes in cover tilt."""
250  if self._unsub_listener_cover_tilt_unsub_listener_cover_tilt is None:
251  self._unsub_listener_cover_tilt_unsub_listener_cover_tilt = async_track_utc_time_change(
252  self.hasshasshass, self._time_changed_cover_tilt_time_changed_cover_tilt
253  )
254 
255  async def _time_changed_cover_tilt(self, now: datetime) -> None:
256  """Track time changes."""
257  if self._tilt_position_tilt_position is None:
258  return
259  if self._requested_closing_tilt_requested_closing_tilt:
260  self._tilt_position_tilt_position -= 10
261  else:
262  self._tilt_position_tilt_position += 10
263 
264  if self._tilt_position_tilt_position in (100, 0, self._set_tilt_position_set_tilt_position):
265  await self.async_stop_cover_tiltasync_stop_cover_tiltasync_stop_cover_tilt()
266 
267  self.async_write_ha_stateasync_write_ha_state()
None async_stop_cover_tilt(self, **Any kwargs)
Definition: __init__.py:472
None async_stop_cover(self, **Any kwargs)
Definition: __init__.py:438
None async_set_cover_tilt_position(self, **Any kwargs)
Definition: cover.py:189
None async_open_cover(self, **Any kwargs)
Definition: cover.py:155
None _time_changed_cover_tilt(self, datetime now)
Definition: cover.py:255
None async_stop_cover_tilt(self, **Any kwargs)
Definition: cover.py:212
None async_stop_cover(self, **Any kwargs)
Definition: cover.py:201
None async_open_cover_tilt(self, **Any kwargs)
Definition: cover.py:169
None async_close_cover_tilt(self, **Any kwargs)
Definition: cover.py:147
None _time_changed_cover(self, datetime now)
Definition: cover.py:230
None __init__(self, HomeAssistant hass, str unique_id, str device_name, int|None position=None, int|None tilt_position=None, CoverDeviceClass|None device_class=None, CoverEntityFeature|None supported_features=None)
Definition: cover.py:74
None async_set_cover_position(self, **Any kwargs)
Definition: cover.py:177
None async_close_cover(self, **Any kwargs)
Definition: cover.py:133
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: cover.py:28
CALLBACK_TYPE async_track_utc_time_change(HomeAssistant hass, Callable[[datetime], Coroutine[Any, Any, None]|None] action, Any|None hour=None, Any|None minute=None, Any|None second=None, bool local=False)
Definition: event.py:1857