1165 lines
40 KiB
Python
1165 lines
40 KiB
Python
"""The tests the cover command line platform."""
|
|
import pytest
|
|
|
|
from homeassistant import setup
|
|
from homeassistant.components.cover import ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN
|
|
from homeassistant.const import (
|
|
ATTR_ENTITY_ID,
|
|
SERVICE_CLOSE_COVER,
|
|
SERVICE_CLOSE_COVER_TILT,
|
|
SERVICE_OPEN_COVER,
|
|
SERVICE_OPEN_COVER_TILT,
|
|
SERVICE_SET_COVER_POSITION,
|
|
SERVICE_SET_COVER_TILT_POSITION,
|
|
SERVICE_STOP_COVER,
|
|
SERVICE_TOGGLE,
|
|
SERVICE_TOGGLE_COVER_TILT,
|
|
STATE_CLOSED,
|
|
STATE_OFF,
|
|
STATE_ON,
|
|
STATE_OPEN,
|
|
STATE_UNAVAILABLE,
|
|
)
|
|
|
|
from tests.common import assert_setup_component, async_mock_service
|
|
|
|
ENTITY_COVER = "cover.test_template_cover"
|
|
|
|
|
|
@pytest.fixture(name="calls")
|
|
def calls_fixture(hass):
|
|
"""Track calls to a mock service."""
|
|
return async_mock_service(hass, "test", "automation")
|
|
|
|
|
|
async def test_template_state_text(hass, calls):
|
|
"""Test the state text of a template."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ states.cover.test_state.state }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.async_set("cover.test_state", STATE_OPEN)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
state = hass.states.async_set("cover.test_state", STATE_CLOSED)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_CLOSED
|
|
|
|
|
|
async def test_template_state_boolean(hass, calls):
|
|
"""Test the value_template attribute."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ 1 == 1 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
|
|
async def test_template_position(hass, calls):
|
|
"""Test the position_template attribute."""
|
|
hass.states.async_set("cover.test", STATE_OPEN)
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ states.cover.test.attributes.position }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.async_set("cover.test", STATE_CLOSED)
|
|
await hass.async_block_till_done()
|
|
|
|
entity = hass.states.get("cover.test")
|
|
attrs = {}
|
|
attrs["position"] = 42
|
|
hass.states.async_set(entity.entity_id, entity.state, attributes=attrs)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 42.0
|
|
assert state.state == STATE_OPEN
|
|
|
|
state = hass.states.async_set("cover.test", STATE_OPEN)
|
|
await hass.async_block_till_done()
|
|
entity = hass.states.get("cover.test")
|
|
attrs["position"] = 0.0
|
|
hass.states.async_set(entity.entity_id, entity.state, attributes=attrs)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 0.0
|
|
assert state.state == STATE_CLOSED
|
|
|
|
|
|
async def test_template_tilt(hass, calls):
|
|
"""Test the tilt_template attribute."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ 1 == 1 }}",
|
|
"tilt_template": "{{ 42 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 42.0
|
|
|
|
|
|
async def test_template_out_of_bounds(hass, calls):
|
|
"""Test template out-of-bounds condition."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ -1 }}",
|
|
"tilt_template": "{{ 110 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") is None
|
|
assert state.attributes.get("current_position") is None
|
|
|
|
|
|
async def test_template_mutex(hass, calls):
|
|
"""Test that only value or position template can be used."""
|
|
with assert_setup_component(0, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ 1 == 1 }}",
|
|
"position_template": "{{ 42 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"icon_template": "{% if states.cover.test_state.state %}"
|
|
"mdi:check"
|
|
"{% endif %}",
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.async_all() == []
|
|
|
|
|
|
async def test_template_open_or_position(hass, caplog):
|
|
"""Test that at least one of open_cover or set_position is used."""
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {"test_template_cover": {"value_template": "{{ 1 == 1 }}"}},
|
|
}
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.async_all() == []
|
|
assert "Invalid config for [cover.template]" in caplog.text
|
|
|
|
|
|
async def test_template_open_and_close(hass, calls):
|
|
"""Test that if open_cover is specified, close_cover is too."""
|
|
with assert_setup_component(0, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ 1 == 1 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.async_all() == []
|
|
|
|
|
|
async def test_template_non_numeric(hass, calls):
|
|
"""Test that tilt_template values are numeric."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ on }}",
|
|
"tilt_template": "{% if states.cover.test_state.state %}"
|
|
"on"
|
|
"{% else %}"
|
|
"off"
|
|
"{% endif %}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") is None
|
|
assert state.attributes.get("current_position") is None
|
|
|
|
|
|
async def test_open_action(hass, calls):
|
|
"""Test the open_cover command."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 0 }}",
|
|
"open_cover": {"service": "test.automation"},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_CLOSED
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 1
|
|
|
|
|
|
async def test_close_stop_action(hass, calls):
|
|
"""Test the close-cover and stop_cover commands."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 100 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {"service": "test.automation"},
|
|
"stop_cover": {"service": "test.automation"},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_STOP_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 2
|
|
|
|
|
|
async def test_set_position(hass, calls):
|
|
"""Test the set_position command."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"input_number",
|
|
{"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}},
|
|
)
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ states.input_number.test.state | int }}",
|
|
"set_cover_position": {
|
|
"service": "input_number.set_value",
|
|
"entity_id": "input_number.test",
|
|
"data_template": {"value": "{{ position }}"},
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.async_set("input_number.test", 42)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 100.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 0.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 100.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 0.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_SET_COVER_POSITION,
|
|
{ATTR_ENTITY_ID: ENTITY_COVER, ATTR_POSITION: 25},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 25.0
|
|
|
|
|
|
async def test_set_tilt_position(hass, calls):
|
|
"""Test the set_tilt_position command."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 100 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"set_cover_tilt_position": {"service": "test.automation"},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_SET_COVER_TILT_POSITION,
|
|
{ATTR_ENTITY_ID: ENTITY_COVER, ATTR_TILT_POSITION: 42},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 1
|
|
|
|
|
|
async def test_open_tilt_action(hass, calls):
|
|
"""Test the open_cover_tilt command."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 100 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"set_cover_tilt_position": {"service": "test.automation"},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 1
|
|
|
|
|
|
async def test_close_tilt_action(hass, calls):
|
|
"""Test the close_cover_tilt command."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 100 }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"set_cover_tilt_position": {"service": "test.automation"},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 1
|
|
|
|
|
|
async def test_set_position_optimistic(hass, calls):
|
|
"""Test optimistic position mode."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"set_cover_position": {"service": "test.automation"}
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") is None
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_SET_COVER_POSITION,
|
|
{ATTR_ENTITY_ID: ENTITY_COVER, ATTR_POSITION: 42},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_position") == 42.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_CLOSED
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_OPEN_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_CLOSED
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state == STATE_OPEN
|
|
|
|
|
|
async def test_set_tilt_position_optimistic(hass, calls):
|
|
"""Test the optimistic tilt_position mode."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"position_template": "{{ 100 }}",
|
|
"set_cover_position": {"service": "test.automation"},
|
|
"set_cover_tilt_position": {"service": "test.automation"},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") is None
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN,
|
|
SERVICE_SET_COVER_TILT_POSITION,
|
|
{ATTR_ENTITY_ID: ENTITY_COVER, ATTR_TILT_POSITION: 42},
|
|
blocking=True,
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 42.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 0.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_OPEN_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 100.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 0.0
|
|
|
|
await hass.services.async_call(
|
|
DOMAIN, SERVICE_TOGGLE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
|
|
)
|
|
await hass.async_block_till_done()
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("current_tilt_position") == 100.0
|
|
|
|
|
|
async def test_icon_template(hass, calls):
|
|
"""Test icon template."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ states.cover.test_state.state }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"icon_template": "{% if states.cover.test_state.state %}"
|
|
"mdi:check"
|
|
"{% endif %}",
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("icon") == ""
|
|
|
|
state = hass.states.async_set("cover.test_state", STATE_OPEN)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
|
|
assert state.attributes["icon"] == "mdi:check"
|
|
|
|
|
|
async def test_entity_picture_template(hass, calls):
|
|
"""Test icon template."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ states.cover.test_state.state }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"entity_picture_template": "{% if states.cover.test_state.state %}"
|
|
"/local/cover.png"
|
|
"{% endif %}",
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("entity_picture") == ""
|
|
|
|
state = hass.states.async_set("cover.test_state", STATE_OPEN)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
|
|
assert state.attributes["entity_picture"] == "/local/cover.png"
|
|
|
|
|
|
async def test_availability_template(hass, calls):
|
|
"""Test availability template."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "open",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"availability_template": "{{ is_state('availability_state.state','on') }}",
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
hass.states.async_set("availability_state.state", STATE_OFF)
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.get("cover.test_template_cover").state == STATE_UNAVAILABLE
|
|
|
|
hass.states.async_set("availability_state.state", STATE_ON)
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.get("cover.test_template_cover").state != STATE_UNAVAILABLE
|
|
|
|
|
|
async def test_availability_without_availability_template(hass, calls):
|
|
"""Test that component is available if there is no."""
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "open",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.state != STATE_UNAVAILABLE
|
|
|
|
|
|
async def test_invalid_availability_template_keeps_component_available(hass, caplog):
|
|
"""Test that an invalid availability keeps the device available."""
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"availability_template": "{{ x - 12 }}",
|
|
"value_template": "open",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert hass.states.get("cover.test_template_cover") != STATE_UNAVAILABLE
|
|
assert ("UndefinedError: 'x' is undefined") in caplog.text
|
|
|
|
|
|
async def test_device_class(hass, calls):
|
|
"""Test device class."""
|
|
with assert_setup_component(1, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ states.cover.test_state.state }}",
|
|
"device_class": "door",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert state.attributes.get("device_class") == "door"
|
|
|
|
|
|
async def test_invalid_device_class(hass, calls):
|
|
"""Test device class."""
|
|
with assert_setup_component(0, "cover"):
|
|
assert await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover": {
|
|
"value_template": "{{ states.cover.test_state.state }}",
|
|
"device_class": "barnacle_bill",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
}
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("cover.test_template_cover")
|
|
assert not state
|
|
|
|
|
|
async def test_unique_id(hass):
|
|
"""Test unique_id option only creates one cover per id."""
|
|
await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"test_template_cover_01": {
|
|
"unique_id": "not-so-unique-anymore",
|
|
"value_template": "{{ true }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
},
|
|
"test_template_cover_02": {
|
|
"unique_id": "not-so-unique-anymore",
|
|
"value_template": "{{ false }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(hass.states.async_all()) == 1
|
|
|
|
|
|
async def test_state_gets_lowercased(hass):
|
|
"""Test True/False is lowercased."""
|
|
|
|
hass.states.async_set("binary_sensor.garage_door_sensor", "off")
|
|
|
|
await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"garage_door": {
|
|
"friendly_name": "Garage Door",
|
|
"value_template": "{{ is_state('binary_sensor.garage_door_sensor', 'off') }}",
|
|
"open_cover": {
|
|
"service": "cover.open_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
"close_cover": {
|
|
"service": "cover.close_cover",
|
|
"entity_id": "cover.test_state",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(hass.states.async_all()) == 2
|
|
|
|
assert hass.states.get("cover.garage_door").state == STATE_OPEN
|
|
hass.states.async_set("binary_sensor.garage_door_sensor", "on")
|
|
await hass.async_block_till_done()
|
|
assert hass.states.get("cover.garage_door").state == STATE_CLOSED
|
|
|
|
|
|
async def test_self_referencing_icon_with_no_template_is_not_a_loop(hass, caplog):
|
|
"""Test a self referencing icon with no value template is not a loop."""
|
|
|
|
icon_template_str = """{% if is_state('cover.office', 'open') %}
|
|
mdi:window-shutter-open
|
|
{% else %}
|
|
mdi:window-shutter
|
|
{% endif %}"""
|
|
|
|
await setup.async_setup_component(
|
|
hass,
|
|
"cover",
|
|
{
|
|
"cover": {
|
|
"platform": "template",
|
|
"covers": {
|
|
"office": {
|
|
"icon_template": icon_template_str,
|
|
"open_cover": {
|
|
"service": "switch.turn_on",
|
|
"entity_id": "switch.office_blinds_up",
|
|
},
|
|
"close_cover": {
|
|
"service": "switch.turn_on",
|
|
"entity_id": "switch.office_blinds_down",
|
|
},
|
|
"stop_cover": {
|
|
"service": "switch.turn_on",
|
|
"entity_id": "switch.office_blinds_up",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
await hass.async_start()
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(hass.states.async_all()) == 1
|
|
|
|
assert "Template loop detected" not in caplog.text
|