Home Assistant Unofficial Reference 2024.12.1
cover.py
Go to the documentation of this file.
1 """Support for Tasmota covers."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from hatasmota import const as tasmota_const, shutter as tasmota_shutter
8 from hatasmota.entity import TasmotaEntity as HATasmotaEntity
9 from hatasmota.models import DiscoveryHashType
10 
12  ATTR_POSITION,
13  ATTR_TILT_POSITION,
14  DOMAIN as COVER_DOMAIN,
15  CoverEntity,
16  CoverEntityFeature,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.dispatcher import async_dispatcher_connect
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 
23 from .const import DATA_REMOVE_DISCOVER_COMPONENT
24 from .discovery import TASMOTA_DISCOVERY_ENTITY_NEW
25 from .entity import TasmotaAvailability, TasmotaDiscoveryUpdate
26 
27 
29  hass: HomeAssistant,
30  config_entry: ConfigEntry,
31  async_add_entities: AddEntitiesCallback,
32 ) -> None:
33  """Set up Tasmota cover dynamically through discovery."""
34 
35  @callback
36  def async_discover(
37  tasmota_entity: HATasmotaEntity, discovery_hash: DiscoveryHashType
38  ) -> None:
39  """Discover and add a Tasmota cover."""
41  [TasmotaCover(tasmota_entity=tasmota_entity, discovery_hash=discovery_hash)]
42  )
43 
44  hass.data[DATA_REMOVE_DISCOVER_COMPONENT.format(COVER_DOMAIN)] = (
46  hass,
47  TASMOTA_DISCOVERY_ENTITY_NEW.format(COVER_DOMAIN),
48  async_discover,
49  )
50  )
51 
52 
54  TasmotaAvailability,
55  TasmotaDiscoveryUpdate,
56  CoverEntity,
57 ):
58  """Representation of a Tasmota cover."""
59 
60  _tasmota_entity: tasmota_shutter.TasmotaShutter
61 
62  def __init__(self, **kwds: Any) -> None:
63  """Initialize the Tasmota cover."""
64  self._direction_direction: int | None = None
65  self._position_position: int | None = None
66  self._tilt_position_tilt_position: int | None = None
67 
68  super().__init__(
69  **kwds,
70  )
71 
72  self._attr_supported_features_attr_supported_features = (
73  CoverEntityFeature.OPEN
74  | CoverEntityFeature.CLOSE
75  | CoverEntityFeature.STOP
76  | CoverEntityFeature.SET_POSITION
77  )
78  if self._tasmota_entity_tasmota_entity.supports_tilt:
79  self._attr_supported_features_attr_supported_features |= (
80  CoverEntityFeature.OPEN_TILT
81  | CoverEntityFeature.CLOSE_TILT
82  | CoverEntityFeature.STOP_TILT
83  | CoverEntityFeature.SET_TILT_POSITION
84  )
85 
86  async def async_added_to_hass(self) -> None:
87  """Subscribe to MQTT events."""
88  self._tasmota_entity_tasmota_entity.set_on_state_callback(self.cover_state_updatedcover_state_updated)
89  await super().async_added_to_hass()
90 
91  @callback
92  def cover_state_updated(self, state: bool, **kwargs: Any) -> None:
93  """Handle state updates."""
94  self._direction_direction = kwargs["direction"]
95  self._position_position = kwargs["position"]
96  self._tilt_position_tilt_position = kwargs["tilt"]
97  self.async_write_ha_stateasync_write_ha_state()
98 
99  @property
100  def current_cover_position(self) -> int | None:
101  """Return current position of cover.
102 
103  None is unknown, 0 is closed, 100 is fully open.
104  """
105  return self._position_position
106 
107  @property
108  def current_cover_tilt_position(self) -> int | None:
109  """Return current tilt position of cover.
110 
111  None is unknown, 0 is closed, 100 is fully open.
112  """
113  return self._tilt_position_tilt_position
114 
115  @property
116  def is_opening(self) -> bool:
117  """Return if the cover is opening or not."""
118  return self._direction_direction == tasmota_const.SHUTTER_DIRECTION_UP
119 
120  @property
121  def is_closing(self) -> bool:
122  """Return if the cover is closing or not."""
123  return self._direction_direction == tasmota_const.SHUTTER_DIRECTION_DOWN
124 
125  @property
126  def is_closed(self) -> bool | None:
127  """Return if the cover is closed or not."""
128  if self._position_position is None:
129  return None
130  return self._position_position == 0
131 
132  async def async_open_cover(self, **kwargs: Any) -> None:
133  """Open the cover."""
134  await self._tasmota_entity_tasmota_entity.open()
135 
136  async def async_close_cover(self, **kwargs: Any) -> None:
137  """Close cover."""
138  await self._tasmota_entity_tasmota_entity.close()
139 
140  async def async_set_cover_position(self, **kwargs: Any) -> None:
141  """Move the cover to a specific position."""
142  position = kwargs[ATTR_POSITION]
143  await self._tasmota_entity_tasmota_entity.set_position(position)
144 
145  async def async_stop_cover(self, **kwargs: Any) -> None:
146  """Stop the cover."""
147  await self._tasmota_entity_tasmota_entity.stop()
148 
149  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
150  """Open the cover tilt."""
151  await self._tasmota_entity_tasmota_entity.open_tilt()
152 
153  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
154  """Close cover tilt."""
155  await self._tasmota_entity_tasmota_entity.close_tilt()
156 
157  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
158  """Move the cover tilt to a specific position."""
159  tilt = kwargs[ATTR_TILT_POSITION]
160  await self._tasmota_entity_tasmota_entity.set_tilt_position(tilt)
161 
162  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
163  """Stop the cover tilt."""
164  await self._tasmota_entity_tasmota_entity.stop()
None async_set_cover_tilt_position(self, **Any kwargs)
Definition: cover.py:157
None async_close_cover(self, **Any kwargs)
Definition: cover.py:136
None async_close_cover_tilt(self, **Any kwargs)
Definition: cover.py:153
None async_stop_cover_tilt(self, **Any kwargs)
Definition: cover.py:162
None async_set_cover_position(self, **Any kwargs)
Definition: cover.py:140
None cover_state_updated(self, bool state, **Any kwargs)
Definition: cover.py:92
None async_open_cover_tilt(self, **Any kwargs)
Definition: cover.py:149
None async_discover(DiscoveryInfo discovery_info)
Definition: sensor.py:217
None open(self, **Any kwargs)
Definition: lock.py:86
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: cover.py:32
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103