mirror of
https://github.com/home-assistant/core.git
synced 2025-12-24 12:59:34 +00:00
Added toggle service to covers (#23198)
* Added toggle service to cover * Added toggle tilt service and tilt closed property * Added is_tilt_closed so tilt can be toggled * Added toggle services * Added toggle tilt service * Removed spaces * Added tests for tilt services * Updated tests * Added range conversion in comparison * Added tests to cover broken areas * Fixed open/close tilt values and added toggle function * Added default toggle behavior using tilt_position of 0, reverted other changes * blank space * Added constants and swapped assert comparisons * Fixed attribute name * Added mqtt responses in test * Added constants * Space * Fix tilt_optimistic flag being ignored if status topic set * Added more tests * Changed async toggle call * Updated group tilt test * Updated format of asserts * Updated states calls * Updated function variables * merge fixes * Added blank line * Changed calls to async * More async updates
This commit is contained in:
committed by
Paulus Schoutsen
parent
a02b69db38
commit
7564d1fb52
@@ -11,6 +11,7 @@ from homeassistant.const import (
|
||||
ATTR_ASSUMED_STATE, ATTR_ENTITY_ID, ATTR_FRIENDLY_NAME,
|
||||
ATTR_SUPPORTED_FEATURES, CONF_ENTITIES,
|
||||
SERVICE_CLOSE_COVER, SERVICE_CLOSE_COVER_TILT,
|
||||
SERVICE_TOGGLE, SERVICE_TOGGLE_COVER_TILT,
|
||||
SERVICE_OPEN_COVER, SERVICE_OPEN_COVER_TILT, SERVICE_SET_COVER_POSITION,
|
||||
SERVICE_SET_COVER_TILT_POSITION, SERVICE_STOP_COVER,
|
||||
SERVICE_STOP_COVER_TILT, STATE_OPEN, STATE_CLOSED)
|
||||
@@ -52,11 +53,11 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_CLOSED
|
||||
assert state.attributes.get(ATTR_FRIENDLY_NAME) == DEFAULT_NAME
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 0
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) is None
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) is None
|
||||
assert state.attributes[ATTR_FRIENDLY_NAME] == DEFAULT_NAME
|
||||
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
|
||||
|
||||
# Add Entity that supports open / close / stop
|
||||
hass.states.async_set(
|
||||
@@ -65,10 +66,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 11
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) is None
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) is None
|
||||
assert ATTR_ASSUMED_STATE not in state.attributes
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 11
|
||||
assert ATTR_CURRENT_POSITION not in state.attributes
|
||||
assert ATTR_CURRENT_TILT_POSITION not in state.attributes
|
||||
|
||||
# Add Entity that supports set_cover_position
|
||||
hass.states.async_set(
|
||||
@@ -78,10 +79,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 15
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 70
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) is None
|
||||
assert ATTR_ASSUMED_STATE not in state.attributes
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 15
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 70
|
||||
assert ATTR_CURRENT_TILT_POSITION not in state.attributes
|
||||
|
||||
# Add Entity that supports open tilt / close tilt / stop tilt
|
||||
hass.states.async_set(
|
||||
@@ -90,10 +91,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 127
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 70
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) is None
|
||||
assert ATTR_ASSUMED_STATE not in state.attributes
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 127
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 70
|
||||
assert ATTR_CURRENT_TILT_POSITION not in state.attributes
|
||||
|
||||
# Add Entity that supports set_tilt_position
|
||||
hass.states.async_set(
|
||||
@@ -103,10 +104,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 255
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 70
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 60
|
||||
assert ATTR_ASSUMED_STATE not in state.attributes
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 255
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 70
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 60
|
||||
|
||||
# ### Test assumed state ###
|
||||
# ##########################
|
||||
@@ -119,10 +120,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is True
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 244
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 100
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 60
|
||||
assert state.attributes[ATTR_ASSUMED_STATE] is True
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 244
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 60
|
||||
|
||||
hass.states.async_remove(DEMO_COVER)
|
||||
hass.states.async_remove(DEMO_COVER_POS)
|
||||
@@ -130,10 +131,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 240
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) is None
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 60
|
||||
assert ATTR_ASSUMED_STATE not in state.attributes
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 240
|
||||
assert ATTR_CURRENT_POSITION not in state.attributes
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 60
|
||||
|
||||
# For tilts
|
||||
hass.states.async_set(
|
||||
@@ -143,10 +144,10 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is True
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 128
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) is None
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 100
|
||||
assert state.attributes[ATTR_ASSUMED_STATE] is True
|
||||
assert state.attributes[ATTR_SUPPORTED_FEATURES] == 128
|
||||
assert ATTR_CURRENT_POSITION not in state.attributes
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
hass.states.async_remove(DEMO_COVER_TILT)
|
||||
hass.states.async_set(DEMO_TILT, STATE_CLOSED)
|
||||
@@ -154,17 +155,17 @@ async def test_attributes(hass):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_CLOSED
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is None
|
||||
assert state.attributes.get(ATTR_SUPPORTED_FEATURES) == 0
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) is None
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) is None
|
||||
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
|
||||
|
||||
hass.states.async_set(
|
||||
DEMO_TILT, STATE_CLOSED, {ATTR_ASSUMED_STATE: True})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.attributes.get(ATTR_ASSUMED_STATE) is True
|
||||
assert state.attributes[ATTR_ASSUMED_STATE] is True
|
||||
|
||||
|
||||
async def test_open_covers(hass, setup_comp):
|
||||
@@ -179,13 +180,13 @@ async def test_open_covers(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 100
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_OPEN
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 100
|
||||
.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 100
|
||||
.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
|
||||
|
||||
async def test_close_covers(hass, setup_comp):
|
||||
@@ -200,13 +201,66 @@ async def test_close_covers(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_CLOSED
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 0
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_CLOSED
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 0
|
||||
.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 0
|
||||
.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
|
||||
|
||||
async def test_toggle_covers(hass, setup_comp):
|
||||
"""Test toggle cover function."""
|
||||
# Start covers in open state
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_OPEN_COVER,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
|
||||
# Toggle will close covers
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_TOGGLE,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_CLOSED
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_CLOSED
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes[ATTR_CURRENT_POSITION] == 0
|
||||
|
||||
# Toggle again will open covers
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_TOGGLE,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_OPEN
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
|
||||
|
||||
async def test_stop_covers(hass, setup_comp):
|
||||
@@ -227,13 +281,13 @@ async def test_stop_covers(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 100
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_OPEN
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 20
|
||||
.attributes[ATTR_CURRENT_POSITION] == 20
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 80
|
||||
.attributes[ATTR_CURRENT_POSITION] == 80
|
||||
|
||||
|
||||
async def test_set_cover_position(hass, setup_comp):
|
||||
@@ -248,13 +302,13 @@ async def test_set_cover_position(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_POSITION) == 50
|
||||
assert state.attributes[ATTR_CURRENT_POSITION] == 50
|
||||
|
||||
assert hass.states.get(DEMO_COVER).state == STATE_CLOSED
|
||||
assert hass.states.get(DEMO_COVER_POS) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 50
|
||||
.attributes[ATTR_CURRENT_POSITION] == 50
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_POSITION) == 50
|
||||
.attributes[ATTR_CURRENT_POSITION] == 50
|
||||
|
||||
|
||||
async def test_open_tilts(hass, setup_comp):
|
||||
@@ -269,10 +323,10 @@ async def test_open_tilts(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 100
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_TILT_POSITION) == 100
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
|
||||
async def test_close_tilts(hass, setup_comp):
|
||||
@@ -287,10 +341,61 @@ async def test_close_tilts(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 0
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 0
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_TILT_POSITION) == 0
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 0
|
||||
|
||||
|
||||
async def test_toggle_tilts(hass, setup_comp):
|
||||
"""Test toggle tilt function."""
|
||||
# Start tilted open
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_OPEN_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
# Toggle will tilt closed
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_TOGGLE_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 0
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 0
|
||||
|
||||
# Toggle again will tilt open
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_TOGGLE_COVER_TILT,
|
||||
{ATTR_ENTITY_ID: COVER_GROUP}, blocking=True)
|
||||
for _ in range(10):
|
||||
future = dt_util.utcnow() + timedelta(seconds=1)
|
||||
async_fire_time_changed(hass, future)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 100
|
||||
|
||||
|
||||
async def test_stop_tilts(hass, setup_comp):
|
||||
@@ -311,10 +416,10 @@ async def test_stop_tilts(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 60
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 60
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_TILT_POSITION) == 60
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 60
|
||||
|
||||
|
||||
async def test_set_tilt_positions(hass, setup_comp):
|
||||
@@ -329,7 +434,7 @@ async def test_set_tilt_positions(hass, setup_comp):
|
||||
|
||||
state = hass.states.get(COVER_GROUP)
|
||||
assert state.state == STATE_OPEN
|
||||
assert state.attributes.get(ATTR_CURRENT_TILT_POSITION) == 80
|
||||
assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 80
|
||||
|
||||
assert hass.states.get(DEMO_COVER_TILT) \
|
||||
.attributes.get(ATTR_CURRENT_TILT_POSITION) == 80
|
||||
.attributes[ATTR_CURRENT_TILT_POSITION] == 80
|
||||
|
||||
Reference in New Issue
Block a user