Home Assistant Unofficial Reference 2024.12.1
cover.py
Go to the documentation of this file.
1 """Support for HomematicIP Cloud cover devices."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from homematicip.aio.device import (
8  AsyncBlindModule,
9  AsyncDinRailBlind4,
10  AsyncFullFlushBlind,
11  AsyncFullFlushShutter,
12  AsyncGarageDoorModuleTormatic,
13  AsyncHoermannDrivesModule,
14 )
15 from homematicip.aio.group import AsyncExtendedLinkedShutterGroup
16 from homematicip.base.enums import DoorCommand, DoorState
17 
19  ATTR_POSITION,
20  ATTR_TILT_POSITION,
21  CoverDeviceClass,
22  CoverEntity,
23 )
24 from homeassistant.config_entries import ConfigEntry
25 from homeassistant.core import HomeAssistant
26 from homeassistant.helpers.entity_platform import AddEntitiesCallback
27 
28 from .const import DOMAIN
29 from .entity import HomematicipGenericEntity
30 from .hap import HomematicipHAP
31 
32 HMIP_COVER_OPEN = 0
33 HMIP_COVER_CLOSED = 1
34 HMIP_SLATS_OPEN = 0
35 HMIP_SLATS_CLOSED = 1
36 
37 
39  hass: HomeAssistant,
40  config_entry: ConfigEntry,
41  async_add_entities: AddEntitiesCallback,
42 ) -> None:
43  """Set up the HomematicIP cover from a config entry."""
44  hap = hass.data[DOMAIN][config_entry.unique_id]
45  entities: list[HomematicipGenericEntity] = [
47  for group in hap.home.groups
48  if isinstance(group, AsyncExtendedLinkedShutterGroup)
49  ]
50  for device in hap.home.devices:
51  if isinstance(device, AsyncBlindModule):
52  entities.append(HomematicipBlindModule(hap, device))
53  elif isinstance(device, AsyncDinRailBlind4):
54  entities.extend(
55  HomematicipMultiCoverSlats(hap, device, channel=channel)
56  for channel in range(1, 5)
57  )
58  elif isinstance(device, AsyncFullFlushBlind):
59  entities.append(HomematicipCoverSlats(hap, device))
60  elif isinstance(device, AsyncFullFlushShutter):
61  entities.append(HomematicipCoverShutter(hap, device))
62  elif isinstance(
63  device, (AsyncHoermannDrivesModule, AsyncGarageDoorModuleTormatic)
64  ):
65  entities.append(HomematicipGarageDoorModule(hap, device))
66 
67  async_add_entities(entities)
68 
69 
71  """Representation of the HomematicIP blind module."""
72 
73  _attr_device_class = CoverDeviceClass.BLIND
74 
75  @property
76  def current_cover_position(self) -> int | None:
77  """Return current position of cover."""
78  if self._device_device.primaryShadingLevel is not None:
79  return int((1 - self._device_device.primaryShadingLevel) * 100)
80  return None
81 
82  @property
83  def current_cover_tilt_position(self) -> int | None:
84  """Return current tilt position of cover."""
85  if self._device_device.secondaryShadingLevel is not None:
86  return int((1 - self._device_device.secondaryShadingLevel) * 100)
87  return None
88 
89  async def async_set_cover_position(self, **kwargs: Any) -> None:
90  """Move the cover to a specific position."""
91  position = kwargs[ATTR_POSITION]
92  # HmIP cover is closed:1 -> open:0
93  level = 1 - position / 100.0
94  await self._device_device.set_primary_shading_level(primaryShadingLevel=level)
95 
96  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
97  """Move the cover to a specific tilt position."""
98  position = kwargs[ATTR_TILT_POSITION]
99  # HmIP slats is closed:1 -> open:0
100  level = 1 - position / 100.0
101  await self._device_device.set_secondary_shading_level(
102  primaryShadingLevel=self._device_device.primaryShadingLevel,
103  secondaryShadingLevel=level,
104  )
105 
106  @property
107  def is_closed(self) -> bool | None:
108  """Return if the cover is closed."""
109  if self._device_device.primaryShadingLevel is not None:
110  return self._device_device.primaryShadingLevel == HMIP_COVER_CLOSED
111  return None
112 
113  async def async_open_cover(self, **kwargs: Any) -> None:
114  """Open the cover."""
115  await self._device_device.set_primary_shading_level(
116  primaryShadingLevel=HMIP_COVER_OPEN
117  )
118 
119  async def async_close_cover(self, **kwargs: Any) -> None:
120  """Close the cover."""
121  await self._device_device.set_primary_shading_level(
122  primaryShadingLevel=HMIP_COVER_CLOSED
123  )
124 
125  async def async_stop_cover(self, **kwargs: Any) -> None:
126  """Stop the device if in motion."""
127  await self._device_device.stop()
128 
129  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
130  """Open the slats."""
131  await self._device_device.set_secondary_shading_level(
132  primaryShadingLevel=self._device_device.primaryShadingLevel,
133  secondaryShadingLevel=HMIP_SLATS_OPEN,
134  )
135 
136  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
137  """Close the slats."""
138  await self._device_device.set_secondary_shading_level(
139  primaryShadingLevel=self._device_device.primaryShadingLevel,
140  secondaryShadingLevel=HMIP_SLATS_CLOSED,
141  )
142 
143  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
144  """Stop the device if in motion."""
145  await self._device_device.stop()
146 
147 
149  """Representation of the HomematicIP cover shutter."""
150 
151  _attr_device_class = CoverDeviceClass.SHUTTER
152 
153  def __init__(
154  self,
155  hap: HomematicipHAP,
156  device,
157  channel=1,
158  is_multi_channel=True,
159  ) -> None:
160  """Initialize the multi cover entity."""
161  super().__init__(
162  hap, device, channel=channel, is_multi_channel=is_multi_channel
163  )
164 
165  @property
166  def current_cover_position(self) -> int | None:
167  """Return current position of cover."""
168  if self._device_device.functionalChannels[self._channel_channel].shutterLevel is not None:
169  return int(
170  (1 - self._device_device.functionalChannels[self._channel_channel].shutterLevel) * 100
171  )
172  return None
173 
174  async def async_set_cover_position(self, **kwargs: Any) -> None:
175  """Move the cover to a specific position."""
176  position = kwargs[ATTR_POSITION]
177  # HmIP cover is closed:1 -> open:0
178  level = 1 - position / 100.0
179  await self._device_device.set_shutter_level(level, self._channel_channel)
180 
181  @property
182  def is_closed(self) -> bool | None:
183  """Return if the cover is closed."""
184  if self._device_device.functionalChannels[self._channel_channel].shutterLevel is not None:
185  return (
186  self._device_device.functionalChannels[self._channel_channel].shutterLevel
187  == HMIP_COVER_CLOSED
188  )
189  return None
190 
191  async def async_open_cover(self, **kwargs: Any) -> None:
192  """Open the cover."""
193  await self._device_device.set_shutter_level(HMIP_COVER_OPEN, self._channel_channel)
194 
195  async def async_close_cover(self, **kwargs: Any) -> None:
196  """Close the cover."""
197  await self._device_device.set_shutter_level(HMIP_COVER_CLOSED, self._channel_channel)
198 
199  async def async_stop_cover(self, **kwargs: Any) -> None:
200  """Stop the device if in motion."""
201  await self._device_device.set_shutter_stop(self._channel_channel)
202 
203 
205  """Representation of the HomematicIP cover shutter."""
206 
207  def __init__(self, hap: HomematicipHAP, device) -> None:
208  """Initialize the multi cover entity."""
209  super().__init__(hap, device, is_multi_channel=False)
210 
211 
213  """Representation of the HomematicIP multi cover slats."""
214 
215  def __init__(
216  self,
217  hap: HomematicipHAP,
218  device,
219  channel=1,
220  is_multi_channel=True,
221  ) -> None:
222  """Initialize the multi slats entity."""
223  super().__init__(
224  hap, device, channel=channel, is_multi_channel=is_multi_channel
225  )
226 
227  @property
228  def current_cover_tilt_position(self) -> int | None:
229  """Return current tilt position of cover."""
230  if self._device_device.functionalChannels[self._channel_channel].slatsLevel is not None:
231  return int(
232  (1 - self._device_device.functionalChannels[self._channel_channel].slatsLevel) * 100
233  )
234  return None
235 
236  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
237  """Move the cover to a specific tilt position."""
238  position = kwargs[ATTR_TILT_POSITION]
239  # HmIP slats is closed:1 -> open:0
240  level = 1 - position / 100.0
241  await self._device_device.set_slats_level(slatsLevel=level, channelIndex=self._channel_channel)
242 
243  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
244  """Open the slats."""
245  await self._device_device.set_slats_level(
246  slatsLevel=HMIP_SLATS_OPEN, channelIndex=self._channel_channel
247  )
248 
249  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
250  """Close the slats."""
251  await self._device_device.set_slats_level(
252  slatsLevel=HMIP_SLATS_CLOSED, channelIndex=self._channel_channel
253  )
254 
255  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
256  """Stop the device if in motion."""
257  await self._device_device.set_shutter_stop(self._channel_channel)
258 
259 
261  """Representation of the HomematicIP cover slats."""
262 
263  def __init__(self, hap: HomematicipHAP, device) -> None:
264  """Initialize the multi slats entity."""
265  super().__init__(hap, device, is_multi_channel=False)
266 
267 
269  """Representation of the HomematicIP Garage Door Module."""
270 
271  _attr_device_class = CoverDeviceClass.GARAGE
272 
273  @property
274  def current_cover_position(self) -> int | None:
275  """Return current position of cover."""
276  door_state_to_position = {
277  DoorState.CLOSED: 0,
278  DoorState.OPEN: 100,
279  DoorState.VENTILATION_POSITION: 10,
280  DoorState.POSITION_UNKNOWN: None,
281  }
282  return door_state_to_position.get(self._device_device.doorState)
283 
284  @property
285  def is_closed(self) -> bool | None:
286  """Return if the cover is closed."""
287  return self._device_device.doorState == DoorState.CLOSED
288 
289  async def async_open_cover(self, **kwargs: Any) -> None:
290  """Open the cover."""
291  await self._device_device.send_door_command(DoorCommand.OPEN)
292 
293  async def async_close_cover(self, **kwargs: Any) -> None:
294  """Close the cover."""
295  await self._device_device.send_door_command(DoorCommand.CLOSE)
296 
297  async def async_stop_cover(self, **kwargs: Any) -> None:
298  """Stop the cover."""
299  await self._device_device.send_door_command(DoorCommand.STOP)
300 
301 
303  """Representation of the HomematicIP cover shutter group."""
304 
305  _attr_device_class = CoverDeviceClass.SHUTTER
306 
307  def __init__(self, hap: HomematicipHAP, device, post: str = "ShutterGroup") -> None:
308  """Initialize switching group."""
309  device.modelType = f"HmIP-{post}"
310  super().__init__(hap, device, post, is_multi_channel=False)
311 
312  @property
313  def current_cover_position(self) -> int | None:
314  """Return current position of cover."""
315  if self._device_device.shutterLevel is not None:
316  return int((1 - self._device_device.shutterLevel) * 100)
317  return None
318 
319  @property
320  def current_cover_tilt_position(self) -> int | None:
321  """Return current tilt position of cover."""
322  if self._device_device.slatsLevel is not None:
323  return int((1 - self._device_device.slatsLevel) * 100)
324  return None
325 
326  @property
327  def is_closed(self) -> bool | None:
328  """Return if the cover is closed."""
329  if self._device_device.shutterLevel is not None:
330  return self._device_device.shutterLevel == HMIP_COVER_CLOSED
331  return None
332 
333  async def async_set_cover_position(self, **kwargs: Any) -> None:
334  """Move the cover to a specific position."""
335  position = kwargs[ATTR_POSITION]
336  # HmIP cover is closed:1 -> open:0
337  level = 1 - position / 100.0
338  await self._device_device.set_shutter_level(level)
339 
340  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
341  """Move the cover to a specific tilt position."""
342  position = kwargs[ATTR_TILT_POSITION]
343  # HmIP slats is closed:1 -> open:0
344  level = 1 - position / 100.0
345  await self._device_device.set_slats_level(level)
346 
347  async def async_open_cover(self, **kwargs: Any) -> None:
348  """Open the cover."""
349  await self._device_device.set_shutter_level(HMIP_COVER_OPEN)
350 
351  async def async_close_cover(self, **kwargs: Any) -> None:
352  """Close the cover."""
353  await self._device_device.set_shutter_level(HMIP_COVER_CLOSED)
354 
355  async def async_stop_cover(self, **kwargs: Any) -> None:
356  """Stop the group if in motion."""
357  await self._device_device.set_shutter_stop()
358 
359  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
360  """Open the slats."""
361  await self._device_device.set_slats_level(HMIP_SLATS_OPEN)
362 
363  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
364  """Close the slats."""
365  await self._device_device.set_slats_level(HMIP_SLATS_CLOSED)
366 
367  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
368  """Stop the group if in motion."""
369  await self._device_device.set_shutter_stop()
None __init__(self, HomematicipHAP hap, device, str post="ShutterGroup")
Definition: cover.py:307
None __init__(self, HomematicipHAP hap, device, channel=1, is_multi_channel=True)
Definition: cover.py:159
None __init__(self, HomematicipHAP hap, device, channel=1, is_multi_channel=True)
Definition: cover.py:221
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: cover.py:42