Improve state of cover groups (#57313)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Erik Montnemery 2021-10-08 18:52:58 +02:00 committed by GitHub
parent 7f966613bd
commit 7e34860615
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 111 additions and 4 deletions

View File

@ -259,25 +259,31 @@ class CoverGroup(GroupEntity, CoverEntity):
"""Update state and attributes."""
self._attr_assumed_state = False
self._attr_is_closed = None
self._attr_is_closed = True
self._attr_is_closing = False
self._attr_is_opening = False
has_valid_state = False
for entity_id in self._entities:
state = self.hass.states.get(entity_id)
if not state:
continue
if state.state == STATE_OPEN:
self._attr_is_closed = False
has_valid_state = True
continue
if state.state == STATE_CLOSED:
self._attr_is_closed = True
has_valid_state = True
continue
if state.state == STATE_CLOSING:
self._attr_is_closing = True
has_valid_state = True
continue
if state.state == STATE_OPENING:
self._attr_is_opening = True
has_valid_state = True
continue
if not has_valid_state:
self._attr_is_closed = None
position_covers = self._covers[KEY_POSITION]
all_position_states = [self.hass.states.get(x) for x in position_covers]

View File

@ -96,6 +96,106 @@ async def setup_comp(hass, config_count):
await hass.async_block_till_done()
@pytest.mark.parametrize("config_count", [(CONFIG_ATTRIBUTES, 1)])
async def test_state(hass, setup_comp):
"""Test handling of state."""
state = hass.states.get(COVER_GROUP)
# No entity has a valid state -> group state unknown
assert state.state == STATE_UNKNOWN
assert state.attributes[ATTR_FRIENDLY_NAME] == DEFAULT_NAME
assert state.attributes[ATTR_ENTITY_ID] == [
DEMO_COVER,
DEMO_COVER_POS,
DEMO_COVER_TILT,
DEMO_TILT,
]
assert ATTR_ASSUMED_STATE not in state.attributes
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0
assert ATTR_CURRENT_POSITION not in state.attributes
assert ATTR_CURRENT_TILT_POSITION not in state.attributes
# Set all entities as closed -> group state closed
hass.states.async_set(DEMO_COVER, STATE_CLOSED, {})
hass.states.async_set(DEMO_COVER_POS, STATE_CLOSED, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSED, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_CLOSED
# Set all entities as open -> group state open
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_OPEN, {})
hass.states.async_set(DEMO_TILT, STATE_OPEN, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPEN
# Set first entity as open -> group state open
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_CLOSED, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSED, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPEN
# Set last entity as open -> group state open
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_CLOSED, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSED, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPEN
# Set conflicting valid states -> opening state has priority
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_OPENING, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSING, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPENING
# Set all entities to unknown state -> group state unknown
hass.states.async_set(DEMO_COVER, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_TILT, STATE_UNKNOWN, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_UNKNOWN
# Set one entity to unknown state -> open state has priority
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSED, {})
hass.states.async_set(DEMO_TILT, STATE_OPEN, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPEN
# Set one entity to unknown state -> opening state has priority
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_OPENING, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_OPENING
# Set one entity to unknown state -> closing state has priority
hass.states.async_set(DEMO_COVER, STATE_OPEN, {})
hass.states.async_set(DEMO_COVER_POS, STATE_UNKNOWN, {})
hass.states.async_set(DEMO_COVER_TILT, STATE_CLOSING, {})
hass.states.async_set(DEMO_TILT, STATE_CLOSED, {})
await hass.async_block_till_done()
state = hass.states.get(COVER_GROUP)
assert state.state == STATE_CLOSING
@pytest.mark.parametrize("config_count", [(CONFIG_ATTRIBUTES, 1)])
async def test_attributes(hass, setup_comp):
"""Test handling of state attributes."""
@ -196,7 +296,7 @@ async def test_attributes(hass, setup_comp):
# ### Test assumed state ###
# ##########################
# For covers
# For covers - assumed state set true if position differ
hass.states.async_set(
DEMO_COVER, STATE_OPEN, {ATTR_SUPPORTED_FEATURES: 4, ATTR_CURRENT_POSITION: 100}
)
@ -220,7 +320,7 @@ async def test_attributes(hass, setup_comp):
assert ATTR_CURRENT_POSITION not in state.attributes
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 60
# For tilts
# For tilts - assumed state set true if tilt position differ
hass.states.async_set(
DEMO_TILT,
STATE_OPEN,
@ -252,6 +352,7 @@ async def test_attributes(hass, setup_comp):
state = hass.states.get(COVER_GROUP)
assert state.attributes[ATTR_ASSUMED_STATE] is True
# Test entity registry integration
entity_registry = er.async_get(hass)
entry = entity_registry.async_get(COVER_GROUP)
assert entry