Clarify cover toggle logic; prevent opening when already open (#107920)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
3299bc5ddc
commit
8ba1340c2e
2 changed files with 27 additions and 3 deletions
|
@ -480,15 +480,30 @@ class CoverEntity(Entity, cached_properties=CACHED_PROPERTIES_WITH_ATTR_):
|
|||
def _get_toggle_function(
|
||||
self, fns: dict[str, Callable[_P, _R]]
|
||||
) -> Callable[_P, _R]:
|
||||
# If we are opening or closing and we support stopping, then we should stop
|
||||
if self.supported_features & CoverEntityFeature.STOP and (
|
||||
self.is_closing or self.is_opening
|
||||
):
|
||||
return fns["stop"]
|
||||
if self.is_closed:
|
||||
|
||||
# If we are fully closed or in the process of closing, then we should open
|
||||
if self.is_closed or self.is_closing:
|
||||
return fns["open"]
|
||||
if self._cover_is_last_toggle_direction_open:
|
||||
|
||||
# If we are fully open or in the process of opening, then we should close
|
||||
if self.current_cover_position == 100 or self.is_opening:
|
||||
return fns["close"]
|
||||
return fns["open"]
|
||||
|
||||
# We are any of:
|
||||
# * fully open but do not report `current_cover_position`
|
||||
# * stopped partially open
|
||||
# * either opening or closing, but do not report them
|
||||
# If we previously reported opening/closing, we should move in the opposite direction.
|
||||
# Otherwise, we must assume we are (partially) open and should always close.
|
||||
# Note: _cover_is_last_toggle_direction_open will always remain True if we never report opening/closing.
|
||||
return (
|
||||
fns["close"] if self._cover_is_last_toggle_direction_open else fns["open"]
|
||||
)
|
||||
|
||||
|
||||
# These can be removed if no deprecated constant are in this module anymore
|
||||
|
|
|
@ -108,6 +108,15 @@ async def test_services(
|
|||
await call_service(hass, SERVICE_TOGGLE, ent6)
|
||||
assert is_opening(hass, ent6)
|
||||
|
||||
# After the unusual state transition: closing -> fully open, toggle should close
|
||||
set_state(ent5, STATE_OPEN)
|
||||
await call_service(hass, SERVICE_TOGGLE, ent5) # Start closing
|
||||
assert is_closing(hass, ent5)
|
||||
set_state(ent5, STATE_OPEN) # Unusual state transition from closing -> fully open
|
||||
set_cover_position(ent5, 100)
|
||||
await call_service(hass, SERVICE_TOGGLE, ent5) # Should close, not open
|
||||
assert is_closing(hass, ent5)
|
||||
|
||||
|
||||
def call_service(hass, service, ent):
|
||||
"""Call any service on entity."""
|
||||
|
|
Loading…
Add table
Reference in a new issue