Home Assistant Unofficial Reference 2024.12.1
cover.py
Go to the documentation of this file.
1 """Support for MySensors covers."""
2 
3 from __future__ import annotations
4 
5 from enum import Enum, unique
6 from typing import Any
7 
8 from homeassistant.components.cover import ATTR_POSITION, CoverEntity
9 from homeassistant.config_entries import ConfigEntry
10 from homeassistant.const import STATE_OFF, STATE_ON, Platform
11 from homeassistant.core import HomeAssistant
12 from homeassistant.helpers.dispatcher import async_dispatcher_connect
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 
15 from . import setup_mysensors_platform
16 from .const import MYSENSORS_DISCOVERY, DiscoveryInfo
17 from .entity import MySensorsChildEntity
18 from .helpers import on_unload
19 
20 
21 @unique
22 class CoverState(Enum):
23  """An enumeration of the standard cover states."""
24 
25  OPEN = 0
26  OPENING = 1
27  CLOSING = 2
28  CLOSED = 3
29 
30 
32  hass: HomeAssistant,
33  config_entry: ConfigEntry,
34  async_add_entities: AddEntitiesCallback,
35 ) -> None:
36  """Set up this platform for a specific ConfigEntry(==Gateway)."""
37 
38  async def async_discover(discovery_info: DiscoveryInfo) -> None:
39  """Discover and add a MySensors cover."""
41  hass,
42  Platform.COVER,
43  discovery_info,
44  MySensorsCover,
45  async_add_entities=async_add_entities,
46  )
47 
48  on_unload(
49  hass,
50  config_entry.entry_id,
52  hass,
53  MYSENSORS_DISCOVERY.format(config_entry.entry_id, Platform.COVER),
54  async_discover,
55  ),
56  )
57 
58 
60  """Representation of the value of a MySensors Cover child node."""
61 
62  def get_cover_state(self) -> CoverState:
63  """Return a CoverState enum representing the state of the cover."""
64  set_req = self.gateway.const.SetReq
65  v_up = self._values.get(set_req.V_UP) == STATE_ON
66  v_down = self._values.get(set_req.V_DOWN) == STATE_ON
67  v_stop = self._values.get(set_req.V_STOP) == STATE_ON
68 
69  # If a V_DIMMER or V_PERCENTAGE is available, that is the amount
70  # the cover is open. Otherwise, use 0 or 100 based on the V_LIGHT
71  # or V_STATUS.
72  amount = 100
73  if set_req.V_DIMMER in self._values:
74  amount = self._values[set_req.V_DIMMER]
75  else:
76  amount = 100 if self._values.get(set_req.V_LIGHT) == STATE_ON else 0
77 
78  if amount == 0:
79  return CoverState.CLOSED
80  if v_up and not v_down and not v_stop:
81  return CoverState.OPENING
82  if not v_up and v_down and not v_stop:
83  return CoverState.CLOSING
84  return CoverState.OPEN
85 
86  @property
87  def is_closed(self) -> bool:
88  """Return True if the cover is closed."""
89  return self.get_cover_stateget_cover_state() == CoverState.CLOSED
90 
91  @property
92  def is_closing(self) -> bool:
93  """Return True if the cover is closing."""
94  return self.get_cover_stateget_cover_state() == CoverState.CLOSING
95 
96  @property
97  def is_opening(self) -> bool:
98  """Return True if the cover is opening."""
99  return self.get_cover_stateget_cover_state() == CoverState.OPENING
100 
101  @property
102  def current_cover_position(self) -> int | None:
103  """Return current position of cover.
104 
105  None is unknown, 0 is closed, 100 is fully open.
106  """
107  set_req = self.gateway.const.SetReq
108  return self._values.get(set_req.V_DIMMER)
109 
110  async def async_open_cover(self, **kwargs: Any) -> None:
111  """Move the cover up."""
112  set_req = self.gateway.const.SetReq
113  self.gateway.set_child_value(
114  self.node_id, self.child_id, set_req.V_UP, 1, ack=1
115  )
116  if self.assumed_stateassumed_state:
117  # Optimistically assume that cover has changed state.
118  if set_req.V_DIMMER in self._values:
119  self._values[set_req.V_DIMMER] = 100
120  else:
121  self._values[set_req.V_LIGHT] = STATE_ON
122  self.async_write_ha_stateasync_write_ha_state()
123 
124  async def async_close_cover(self, **kwargs: Any) -> None:
125  """Move the cover down."""
126  set_req = self.gateway.const.SetReq
127  self.gateway.set_child_value(
128  self.node_id, self.child_id, set_req.V_DOWN, 1, ack=1
129  )
130  if self.assumed_stateassumed_state:
131  # Optimistically assume that cover has changed state.
132  if set_req.V_DIMMER in self._values:
133  self._values[set_req.V_DIMMER] = 0
134  else:
135  self._values[set_req.V_LIGHT] = STATE_OFF
136  self.async_write_ha_stateasync_write_ha_state()
137 
138  async def async_set_cover_position(self, **kwargs: Any) -> None:
139  """Move the cover to a specific position."""
140  position = kwargs.get(ATTR_POSITION)
141  set_req = self.gateway.const.SetReq
142  self.gateway.set_child_value(
143  self.node_id, self.child_id, set_req.V_DIMMER, position, ack=1
144  )
145  if self.assumed_stateassumed_state:
146  # Optimistically assume that cover has changed state.
147  self._values[set_req.V_DIMMER] = position
148  self.async_write_ha_stateasync_write_ha_state()
149 
150  async def async_stop_cover(self, **kwargs: Any) -> None:
151  """Stop the device."""
152  set_req = self.gateway.const.SetReq
153  self.gateway.set_child_value(
154  self.node_id, self.child_id, set_req.V_STOP, 1, ack=1
155  )
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: cover.py:35
None on_unload(HomeAssistant hass, GatewayId gateway_id, Callable fnct)
Definition: helpers.py:45
None async_discover(DiscoveryInfo discovery_info)
Definition: sensor.py:217
list[MySensorsChildEntity]|None setup_mysensors_platform(HomeAssistant hass, Platform domain, DiscoveryInfo discovery_info, type[MySensorsChildEntity]|Mapping[SensorType, type[MySensorsChildEntity]] device_class,(tuple|None) device_args=None, Callable|None async_add_entities=None)
Definition: __init__.py:112
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103