Home Assistant Unofficial Reference 2024.12.1
cover.py
Go to the documentation of this file.
1 """Support for ZHA covers."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Mapping
6 import functools
7 import logging
8 from typing import Any
9 
10 from zha.application.platforms.cover import Shade as ZhaShade
11 from zha.application.platforms.cover.const import (
12  CoverEntityFeature as ZHACoverEntityFeature,
13 )
14 
16  ATTR_POSITION,
17  ATTR_TILT_POSITION,
18  CoverDeviceClass,
19  CoverEntity,
20  CoverEntityFeature,
21 )
22 from homeassistant.config_entries import ConfigEntry
23 from homeassistant.const import Platform
24 from homeassistant.core import HomeAssistant, State, callback
25 from homeassistant.helpers.dispatcher import async_dispatcher_connect
26 from homeassistant.helpers.entity_platform import AddEntitiesCallback
27 
28 from .entity import ZHAEntity
29 from .helpers import (
30  SIGNAL_ADD_ENTITIES,
31  EntityData,
32  async_add_entities as zha_async_add_entities,
33  convert_zha_error_to_ha_error,
34  get_zha_data,
35 )
36 
37 _LOGGER = logging.getLogger(__name__)
38 
39 
41  hass: HomeAssistant,
42  config_entry: ConfigEntry,
43  async_add_entities: AddEntitiesCallback,
44 ) -> None:
45  """Set up the Zigbee Home Automation cover from config entry."""
46  zha_data = get_zha_data(hass)
47  entities_to_create = zha_data.platforms[Platform.COVER]
48 
50  hass,
51  SIGNAL_ADD_ENTITIES,
52  functools.partial(
53  zha_async_add_entities, async_add_entities, ZhaCover, entities_to_create
54  ),
55  )
56  config_entry.async_on_unload(unsub)
57 
58 
60  """Representation of a ZHA cover."""
61 
62  def __init__(self, entity_data: EntityData) -> None:
63  """Initialize the ZHA cover."""
64  super().__init__(entity_data)
65 
66  if self.entity_data.entity.info_object.device_class is not None:
67  self._attr_device_class_attr_device_class = CoverDeviceClass(
68  self.entity_data.entity.info_object.device_class
69  )
70 
71  features = CoverEntityFeature(0)
72  zha_features: ZHACoverEntityFeature = self.entity_data.entity.supported_features
73 
74  if ZHACoverEntityFeature.OPEN in zha_features:
75  features |= CoverEntityFeature.OPEN
76  if ZHACoverEntityFeature.CLOSE in zha_features:
77  features |= CoverEntityFeature.CLOSE
78  if ZHACoverEntityFeature.SET_POSITION in zha_features:
79  features |= CoverEntityFeature.SET_POSITION
80  if ZHACoverEntityFeature.STOP in zha_features:
81  features |= CoverEntityFeature.STOP
82  if ZHACoverEntityFeature.OPEN_TILT in zha_features:
83  features |= CoverEntityFeature.OPEN_TILT
84  if ZHACoverEntityFeature.CLOSE_TILT in zha_features:
85  features |= CoverEntityFeature.CLOSE_TILT
86  if ZHACoverEntityFeature.STOP_TILT in zha_features:
87  features |= CoverEntityFeature.STOP_TILT
88  if ZHACoverEntityFeature.SET_TILT_POSITION in zha_features:
89  features |= CoverEntityFeature.SET_TILT_POSITION
90 
91  self._attr_supported_features_attr_supported_features = features
92 
93  @property
94  def extra_state_attributes(self) -> Mapping[str, Any] | None:
95  """Return entity specific state attributes."""
96  state = self.entity_data.entity.state
97  return {
98  "target_lift_position": state.get("target_lift_position"),
99  "target_tilt_position": state.get("target_tilt_position"),
100  }
101 
102  @property
103  def is_closed(self) -> bool | None:
104  """Return True if the cover is closed."""
105  return self.entity_data.entity.is_closed
106 
107  @property
108  def is_opening(self) -> bool:
109  """Return if the cover is opening or not."""
110  return self.entity_data.entity.is_opening
111 
112  @property
113  def is_closing(self) -> bool:
114  """Return if the cover is closing or not."""
115  return self.entity_data.entity.is_closing
116 
117  @property
118  def current_cover_position(self) -> int | None:
119  """Return the current position of ZHA cover."""
120  return self.entity_data.entity.current_cover_position
121 
122  @property
123  def current_cover_tilt_position(self) -> int | None:
124  """Return the current tilt position of the cover."""
125  return self.entity_data.entity.current_cover_tilt_position
126 
127  @convert_zha_error_to_ha_error
128  async def async_open_cover(self, **kwargs: Any) -> None:
129  """Open the cover."""
130  await self.entity_data.entity.async_open_cover()
131  self.async_write_ha_stateasync_write_ha_state()
132 
133  @convert_zha_error_to_ha_error
134  async def async_open_cover_tilt(self, **kwargs: Any) -> None:
135  """Open the cover tilt."""
136  await self.entity_data.entity.async_open_cover_tilt()
137  self.async_write_ha_stateasync_write_ha_state()
138 
139  @convert_zha_error_to_ha_error
140  async def async_close_cover(self, **kwargs: Any) -> None:
141  """Close the cover."""
142  await self.entity_data.entity.async_close_cover()
143  self.async_write_ha_stateasync_write_ha_state()
144 
145  @convert_zha_error_to_ha_error
146  async def async_close_cover_tilt(self, **kwargs: Any) -> None:
147  """Close the cover tilt."""
148  await self.entity_data.entity.async_close_cover_tilt()
149  self.async_write_ha_stateasync_write_ha_state()
150 
151  @convert_zha_error_to_ha_error
152  async def async_set_cover_position(self, **kwargs: Any) -> None:
153  """Move the cover to a specific position."""
154  await self.entity_data.entity.async_set_cover_position(
155  position=kwargs.get(ATTR_POSITION)
156  )
157  self.async_write_ha_stateasync_write_ha_state()
158 
159  @convert_zha_error_to_ha_error
160  async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
161  """Move the cover tilt to a specific position."""
162  await self.entity_data.entity.async_set_cover_tilt_position(
163  tilt_position=kwargs.get(ATTR_TILT_POSITION)
164  )
165  self.async_write_ha_stateasync_write_ha_state()
166 
167  @convert_zha_error_to_ha_error
168  async def async_stop_cover(self, **kwargs: Any) -> None:
169  """Stop the cover."""
170  await self.entity_data.entity.async_stop_cover()
171  self.async_write_ha_stateasync_write_ha_state()
172 
173  @convert_zha_error_to_ha_error
174  async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
175  """Stop the cover tilt."""
176  await self.entity_data.entity.async_stop_cover_tilt()
177  self.async_write_ha_stateasync_write_ha_state()
178 
179  @callback
180  def restore_external_state_attributes(self, state: State) -> None:
181  """Restore entity state."""
182 
183  # Shades are a subtype of cover that do not need external state restored
184  if isinstance(self.entity_data.entity, ZhaShade):
185  return
186 
187  # Same as `light`, some entity state is not derived from ZCL attributes
188  self.entity_data.entity.restore_external_state_attributes(
189  state=state.state,
190  target_lift_position=state.attributes.get("target_lift_position"),
191  target_tilt_position=state.attributes.get("target_tilt_position"),
192  )
None async_set_cover_position(self, **Any kwargs)
Definition: cover.py:152
None async_set_cover_tilt_position(self, **Any kwargs)
Definition: cover.py:160
None async_open_cover(self, **Any kwargs)
Definition: cover.py:128
None __init__(self, EntityData entity_data)
Definition: cover.py:62
None async_stop_cover(self, **Any kwargs)
Definition: cover.py:168
None async_stop_cover_tilt(self, **Any kwargs)
Definition: cover.py:174
None async_close_cover_tilt(self, **Any kwargs)
Definition: cover.py:146
None async_close_cover(self, **Any kwargs)
Definition: cover.py:140
Mapping[str, Any]|None extra_state_attributes(self)
Definition: cover.py:94
None restore_external_state_attributes(self, State state)
Definition: cover.py:180
None async_open_cover_tilt(self, **Any kwargs)
Definition: cover.py:134
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: cover.py:44
HAZHAData get_zha_data(HomeAssistant hass)
Definition: helpers.py:1020
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103