core/tests/components/cover/test_template.py

759 lines
26 KiB
Python

"""The tests the cover command line platform."""
import logging
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,
STATE_CLOSED, STATE_OPEN)
from tests.common import assert_setup_component, async_mock_service
_LOGGER = logging.getLogger(__name__)
ENTITY_COVER = 'cover.test_template_cover'
@pytest.fixture
def calls(hass):
"""Track calls to a mock serivce."""
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_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_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."""
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_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 = dict()
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_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_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_start()
await hass.async_block_till_done()
assert hass.states.async_all() == []
async def test_template_open_or_position(hass, calls):
"""Test that at least one of open_cover or set_position is used."""
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 }}",
}
}
}
})
await hass.async_start()
await hass.async_block_till_done()
assert hass.states.async_all() == []
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_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_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_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_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_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_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_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_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_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_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
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_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
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_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_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'