core/tests/components/template/test_light.py

1476 lines
51 KiB
Python
Raw Normal View History

"""The tests for the Template light platform."""
import logging
import pytest
import homeassistant.components.light as light
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_EFFECT,
ATTR_HS_COLOR,
ATTR_TRANSITION,
ATTR_WHITE_VALUE,
SUPPORT_TRANSITION,
)
from homeassistant.const import (
ATTR_ENTITY_ID,
SERVICE_TURN_OFF,
SERVICE_TURN_ON,
STATE_OFF,
STATE_ON,
STATE_UNAVAILABLE,
)
_LOGGER = logging.getLogger(__name__)
# Represent for light's availability
_STATE_AVAILABILITY_BOOLEAN = "availability_boolean.state"
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{states.test['big.fat...']}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
],
)
async def test_template_state_invalid(hass, start_ha):
"""Test template state with render error."""
assert hass.states.get("light.test_template_light").state == STATE_OFF
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{ states.light.test_state.state }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
],
)
async def test_template_state_text(hass, start_ha):
"""Test the state text of a template."""
for set_state in [STATE_ON, STATE_OFF]:
hass.states.async_set("light.test_state", set_state)
await hass.async_block_till_done()
assert hass.states.get("light.test_template_light").state == set_state
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config_addon,expected_state",
[
({"replace1": '"{{ 1 == 1 }}"'}, STATE_ON),
({"replace1": '"{{ 1 == 2 }}"'}, STATE_OFF),
],
)
@pytest.mark.parametrize(
"config",
[
"""{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": replace1,
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state"
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state"
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}"
}
}
}
}
}
}""",
],
)
async def test_templatex_state_boolean(hass, expected_state, start_ha):
"""Test the setting of the state with boolean on."""
assert hass.states.get("light.test_template_light").state == expected_state
@pytest.mark.parametrize("count,domain", [(0, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{%- if false -%}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
{
"light": {
"platform": "template",
"lights": {
"bad name here": {
"value_template": "{{ 1== 1}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
{
"light": {
"platform": "template",
"switches": {"test_template_light": "Invalid"},
}
},
],
)
async def test_template_syntax_error(hass, start_ha):
"""Test templating syntax error."""
assert hass.states.async_all("light") == []
SET_VAL1 = '"value_template": "{{ 1== 1}}",'
SET_VAL2 = '"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},'
SET_VAL3 = '"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},'
@pytest.mark.parametrize("domain", [light.DOMAIN])
@pytest.mark.parametrize(
"config_addon, count",
[
({"replace2": f"{SET_VAL2}{SET_VAL3}"}, 1),
({"replace2": f"{SET_VAL1}{SET_VAL2}"}, 0),
({"replace2": f"{SET_VAL2}{SET_VAL3}"}, 1),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template", "lights": {
"light_one": {
replace2
"set_level": {"service": "light.turn_on",
"data_template": {"entity_id": "light.test_state","brightness": "{{brightness}}"
}}}}}}"""
],
)
async def test_missing_key(hass, count, start_ha):
"""Test missing template."""
if count:
assert hass.states.async_all("light") != []
else:
assert hass.states.async_all("light") == []
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{states.light.test_state.state}}",
"turn_on": {"service": "test.automation"},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
2019-07-31 19:25:30 +00:00
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_on_action(hass, start_ha, calls):
"""Test on action."""
hass.states.async_set("light.test_state", STATE_OFF)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.state == STATE_OFF
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light"},
blocking=True,
)
assert len(calls) == 1
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{states.light.test_state.state}}",
"turn_on": {
"service": "test.automation",
"data_template": {
"transition": "{{transition}}",
},
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"supports_transition_template": "{{true}}",
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
"transition": "{{transition}}",
},
},
}
},
}
},
],
)
async def test_on_action_with_transition(hass, start_ha, calls):
"""Test on action with transition."""
hass.states.async_set("light.test_state", STATE_OFF)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.state == STATE_OFF
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_TRANSITION: 5},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["transition"] == 5
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"turn_on": {"service": "test.automation"},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
2019-07-31 19:25:30 +00:00
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_on_action_optimistic(hass, start_ha, calls):
"""Test on action with optimistic state."""
hass.states.async_set("light.test_state", STATE_OFF)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.state == STATE_OFF
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light"},
blocking=True,
)
state = hass.states.get("light.test_template_light")
assert len(calls) == 1
assert state.state == STATE_ON
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{states.light.test_state.state}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "test.automation",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
2019-07-31 19:25:30 +00:00
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_off_action(hass, start_ha, calls):
"""Test off action."""
hass.states.async_set("light.test_state", STATE_ON)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.state == STATE_ON
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.test_template_light"},
blocking=True,
)
assert len(calls) == 1
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{states.light.test_state.state}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "test.automation",
"data_template": {
"transition": "{{transition}}",
},
},
"supports_transition_template": "{{true}}",
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
"transition": "{{transition}}",
},
},
}
},
}
},
],
)
async def test_off_action_with_transition(hass, start_ha, calls):
"""Test off action with transition."""
hass.states.async_set("light.test_state", STATE_ON)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.state == STATE_ON
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_TRANSITION: 2},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["transition"] == 2
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {"service": "test.automation"},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
2019-07-31 19:25:30 +00:00
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_off_action_optimistic(hass, start_ha, calls):
"""Test off action with optimistic state."""
state = hass.states.get("light.test_template_light")
assert state.state == STATE_OFF
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_OFF,
{ATTR_ENTITY_ID: "light.test_template_light"},
blocking=True,
)
assert len(calls) == 1
state = hass.states.get("light.test_template_light")
assert state.state == STATE_OFF
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{1 == 1}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_white_value": {
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"white_value": "{{white_value}}",
},
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_white_value_action_no_template(hass, start_ha, calls):
"""Test setting white value with optimistic template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("white_value") is None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_WHITE_VALUE: 124},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["white_value"] == 124
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("white_value") == 124
@pytest.mark.parametrize(
"expected_white_value,config_addon",
[
(255, {"replace3": "{{255}}"}),
(None, {"replace3": "{{256}}"}),
(None, {"replace3": "{{x - 12}}"}),
(None, {"replace3": "{{ none }}"}),
(None, {"replace3": ""}),
],
)
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
"""{
"light": {"platform": "template","lights": {
"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_white_value": {"service": "light.turn_on",
"data_template": {"entity_id": "light.test_state",
"white_value": "{{white_value}}"}},
"white_value_template": "replace3"
}}}}""",
],
)
async def test_white_value_template(hass, expected_white_value, start_ha):
"""Test the template for the white value."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("white_value") == expected_white_value
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{1 == 1}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
2019-07-31 19:25:30 +00:00
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
2019-07-31 19:25:30 +00:00
},
"set_level": {
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"brightness": "{{brightness}}",
},
2019-07-31 19:25:30 +00:00
},
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_level_action_no_template(hass, start_ha, calls):
"""Test setting brightness with optimistic template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("brightness") is None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_BRIGHTNESS: 124},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["brightness"] == 124
state = hass.states.get("light.test_template_light")
_LOGGER.info(str(state.attributes))
assert state is not None
assert state.attributes.get("brightness") == 124
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_level,config_addon",
[
(255, {"replace4": '"{{255}}"'}),
(None, {"replace4": '"{{256}}"'}),
(None, {"replace4": '"{{x - 12}}"'}),
(None, {"replace4": '"{{ none }}"'}),
(None, {"replace4": '""'}),
(None, {"replace4": "\"{{ state_attr('light.nolight', 'brightness') }}\""}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template", "lights": {
"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_level": {"service": "light.turn_on","data_template": {
"entity_id": "light.test_state","brightness": "{{brightness}}"}},
"level_template": replace4
}}}}""",
],
)
async def test_level_template(hass, expected_level, start_ha):
"""Test the template for the level."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("brightness") == expected_level
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_temp,config_addon",
[
(500, {"replace5": '"{{500}}"'}),
(None, {"replace5": '"{{501}}"'}),
(None, {"replace5": '"{{x - 12}}"'}),
(None, {"replace5": '"None"'}),
(None, {"replace5": '"{{ none }}"'}),
(None, {"replace5": '""'}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{
2019-07-31 19:25:30 +00:00
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{ 1 == 1 }}",
2019-07-31 19:25:30 +00:00
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state"
2019-07-31 19:25:30 +00:00
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state"
},
"set_temperature": {
2019-07-31 19:25:30 +00:00
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"color_temp": "{{color_temp}}"
}
2019-07-31 19:25:30 +00:00
},
"temperature_template": replace5
}
}
}
}"""
],
)
async def test_temperature_template(hass, expected_temp, start_ha):
"""Test the template for the temperature."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("color_temp") == expected_temp
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{1 == 1}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_temperature": {
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"color_temp": "{{color_temp}}",
},
},
}
},
}
},
],
)
async def test_temperature_action_no_template(hass, start_ha, calls):
"""Test setting temperature with optimistic template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("color_template") is None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_COLOR_TEMP: 345},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["color_temp"] == 345
state = hass.states.get("light.test_template_light")
_LOGGER.info(str(state.attributes))
assert state is not None
assert state.attributes.get("color_temp") == 345
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"friendly_name": "Template light",
"value_template": "{{ 1 == 1 }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
],
)
async def test_friendly_name(hass, start_ha):
"""Test the accessibility of the friendly_name attribute."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("friendly_name") == "Template light"
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"friendly_name": "Template light",
"value_template": "{{ 1 == 1 }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
"icon_template": "{% if states.light.test_state.state %}"
"mdi:check"
"{% endif %}",
}
},
}
},
],
)
async def test_icon_template(hass, start_ha):
"""Test icon template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("icon") == ""
state = hass.states.async_set("light.test_state", STATE_ON)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.attributes["icon"] == "mdi:check"
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"friendly_name": "Template light",
"value_template": "{{ 1 == 1 }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
2019-07-31 19:25:30 +00:00
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
2019-07-31 19:25:30 +00:00
},
},
"entity_picture_template": "{% if states.light.test_state.state %}"
"/local/light.png"
"{% endif %}",
}
},
}
},
],
)
async def test_entity_picture_template(hass, start_ha):
"""Test entity_picture template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("entity_picture") == ""
state = hass.states.async_set("light.test_state", STATE_ON)
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state.attributes["entity_picture"] == "/local/light.png"
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{1 == 1}}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_color": [
{
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"h": "{{h}}",
"s": "{{s}}",
},
},
{
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"s": "{{s}}",
"h": "{{h}}",
2019-07-31 19:25:30 +00:00
},
},
],
}
2019-07-31 19:25:30 +00:00
},
}
},
],
)
async def test_color_action_no_template(hass, start_ha, calls):
"""Test setting color with optimistic template."""
state = hass.states.get("light.test_template_light")
assert state.attributes.get("hs_color") is None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_HS_COLOR: (40, 50)},
blocking=True,
)
assert len(calls) == 2
assert calls[0].data["h"] == 40
assert calls[0].data["s"] == 50
assert calls[1].data["h"] == 40
assert calls[1].data["s"] == 50
state = hass.states.get("light.test_template_light")
_LOGGER.info(str(state.attributes))
assert state is not None
assert calls[0].data["h"] == 40
assert calls[0].data["s"] == 50
assert calls[1].data["h"] == 40
assert calls[1].data["s"] == 50
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_hs,config_addon",
[
((360, 100), {"replace6": '"{{(360, 100)}}"'}),
((359.9, 99.9), {"replace6": '"{{(359.9, 99.9)}}"'}),
(None, {"replace6": '"{{(361, 100)}}"'}),
(None, {"replace6": '"{{(360, 101)}}"'}),
(None, {"replace6": '"{{x - 12}}"'}),
(None, {"replace6": '""'}),
(None, {"replace6": '"{{ none }}"'}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_color": [{"service": "input_number.set_value",
"data_template": {"entity_id": "input_number.h","color_temp": "{{h}}"
}}],
"color_template": replace6
}}}}"""
],
)
async def test_color_template(hass, expected_hs, start_ha):
"""Test the template for the color."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("hs_color") == expected_hs
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{true}}",
"turn_on": {"service": "test.automation"},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
"set_effect": {
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"effect": "{{effect}}",
},
},
"effect_list_template": "{{ ['Disco', 'Police'] }}",
"effect_template": "{{ 'Disco' }}",
}
},
}
},
],
)
async def test_effect_action_valid_effect(hass, start_ha, calls):
"""Test setting valid effect with template."""
state = hass.states.get("light.test_template_light")
assert state is not None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_EFFECT: "Disco"},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["effect"] == "Disco"
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("effect") == "Disco"
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"value_template": "{{true}}",
"turn_on": {"service": "test.automation"},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
"set_effect": {
"service": "test.automation",
"data_template": {
"entity_id": "test.test_state",
"effect": "{{effect}}",
},
},
"effect_list_template": "{{ ['Disco', 'Police'] }}",
"effect_template": "{{ None }}",
}
},
}
},
],
)
async def test_effect_action_invalid_effect(hass, start_ha, calls):
"""Test setting invalid effect with template."""
state = hass.states.get("light.test_template_light")
assert state is not None
await hass.services.async_call(
light.DOMAIN,
SERVICE_TURN_ON,
{ATTR_ENTITY_ID: "light.test_template_light", ATTR_EFFECT: "RGB"},
blocking=True,
)
assert len(calls) == 1
assert calls[0].data["effect"] == "RGB"
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("effect") is None
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_effect_list,config_addon",
[
(
["Strobe color", "Police", "Christmas", "RGB", "Random Loop"],
{
"replace7": "\"{{ ['Strobe color', 'Police', 'Christmas', 'RGB', 'Random Loop'] }}\""
},
),
(
["Police", "RGB", "Random Loop"],
{"replace7": "\"{{ ['Police', 'RGB', 'Random Loop'] }}\""},
),
(None, {"replace7": '"{{ [] }}"'}),
(None, {"replace7": "\"{{ '[]' }}\""}),
(None, {"replace7": '"{{ 124 }}"'}),
(None, {"replace7": "\"{{ '124' }}\""}),
(None, {"replace7": '"{{ none }}"'}),
(None, {"replace7": '""'}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_effect": {"service": "test.automation",
"data_template": {"entity_id": "test.test_state","effect": "{{effect}}"}},
"effect_template": "{{ None }}",
"effect_list_template": replace7
}}}}""",
],
)
async def test_effect_list_template(hass, expected_effect_list, start_ha):
"""Test the template for the effect list."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("effect_list") == expected_effect_list
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_effect,config_addon",
[
(None, {"replace8": '"Disco"'}),
(None, {"replace8": '"None"'}),
(None, {"replace8": '"{{ None }}"'}),
("Police", {"replace8": '"Police"'}),
("Strobe color", {"replace8": "\"{{ 'Strobe color' }}\""}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_effect": {"service": "test.automation","data_template": {
"entity_id": "test.test_state","effect": "{{effect}}"}},
"effect_list_template": "{{ ['Strobe color', 'Police', 'Christmas', 'RGB', 'Random Loop'] }}",
"effect_template": replace8
}}}}""",
],
)
async def test_effect_template(hass, expected_effect, start_ha):
"""Test the template for the effect."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("effect") == expected_effect
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_min_mireds,config_addon",
[
(118, {"replace9": '"{{118}}"'}),
(153, {"replace9": '"{{x - 12}}"'}),
(153, {"replace9": '"None"'}),
(153, {"replace9": '"{{ none }}"'}),
(153, {"replace9": '""'}),
(153, {"replace9": "\"{{ 'a' }}\""}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_temperature": {"service": "light.turn_on","data_template": {
"entity_id": "light.test_state","color_temp": "{{color_temp}}"}},
"temperature_template": "{{200}}",
"min_mireds_template": replace9
}}}}""",
],
)
async def test_min_mireds_template(hass, expected_min_mireds, start_ha):
"""Test the template for the min mireds."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("min_mireds") == expected_min_mireds
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_max_mireds,config_addon",
[
(488, {"template1": '"{{488}}"'}),
(500, {"template1": '"{{x - 12}}"'}),
(500, {"template1": '"None"'}),
(500, {"template1": '"{{ none }}"'}),
(500, {"template1": '""'}),
(500, {"template1": "\"{{ 'a' }}\""}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_temperature": {"service": "light.turn_on","data_template": {
"entity_id": "light.test_state","color_temp": "{{color_temp}}"}},
"temperature_template": "{{200}}",
"max_mireds_template": template1
}}}}""",
],
)
async def test_max_mireds_template(hass, expected_max_mireds, start_ha):
"""Test the template for the max mireds."""
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("max_mireds") == expected_max_mireds
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"expected_supports_transition,config_addon",
[
(True, {"template2": '"{{true}}"'}),
(True, {"template2": '"{{1 == 1}}"'}),
(False, {"template2": '"{{false}}"'}),
(False, {"template2": '"{{ none }}"'}),
(False, {"template2": '""'}),
(False, {"template2": '"None"'}),
],
)
@pytest.mark.parametrize(
"config",
[
"""{"light": {"platform": "template","lights": {"test_template_light": {
"value_template": "{{ 1 == 1 }}",
"turn_on": {"service": "light.turn_on","entity_id": "light.test_state"},
"turn_off": {"service": "light.turn_off","entity_id": "light.test_state"},
"set_temperature": {"service": "light.turn_on","data_template": {
"entity_id": "light.test_state","color_temp": "{{color_temp}}"}},
"supports_transition_template": template2
}}}}""",
],
)
async def test_supports_transition_template(
hass, expected_supports_transition, start_ha
):
"""Test the template for the supports transition."""
state = hass.states.get("light.test_template_light")
expected_value = 1
if expected_supports_transition is True:
expected_value = 0
assert state is not None
assert (
int(state.attributes.get("supported_features")) & SUPPORT_TRANSITION
) != expected_value
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"availability_template": "{{ is_state('availability_boolean.state', 'on') }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
],
)
async def test_available_template_with_entities(hass, start_ha):
"""Test availability templates with values from other entities."""
# When template returns true..
hass.states.async_set(_STATE_AVAILABILITY_BOOLEAN, STATE_ON)
await hass.async_block_till_done()
# Device State should not be unavailable
assert hass.states.get("light.test_template_light").state != STATE_UNAVAILABLE
# When Availability template returns false
hass.states.async_set(_STATE_AVAILABILITY_BOOLEAN, STATE_OFF)
await hass.async_block_till_done()
# device state should be unavailable
assert hass.states.get("light.test_template_light").state == STATE_UNAVAILABLE
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light": {
"availability_template": "{{ x - 12 }}",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
"entity_id": "light.test_state",
"brightness": "{{brightness}}",
},
},
}
},
}
},
],
)
async def test_invalid_availability_template_keeps_component_available(
hass, start_ha, caplog_setup_text
):
"""Test that an invalid availability keeps the device available."""
assert hass.states.get("light.test_template_light").state != STATE_UNAVAILABLE
assert ("UndefinedError: 'x' is undefined") in caplog_setup_text
@pytest.mark.parametrize("count,domain", [(1, light.DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"light": {
"platform": "template",
"lights": {
"test_template_light_01": {
"unique_id": "not-so-unique-anymore",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
},
"test_template_light_02": {
"unique_id": "not-so-unique-anymore",
"turn_on": {
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {
"service": "light.turn_off",
"entity_id": "light.test_state",
},
},
},
}
},
],
)
async def test_unique_id(hass, start_ha):
"""Test unique_id option only creates one light per id."""
assert len(hass.states.async_all("light")) == 1