Add support for effects, transition/brightness parameters to template light, min_mireds and max_mireds templates (#43850)

* Add support for effects, transition/brightness parameters to template light, min_mireds and max_mireds templates

* code fixes

* min_mireds, max_mireds fixes

* test fixes

* more fixes

* format fix

* style fix

* _update_effect_list change

* style fix

* Fixes after review

* additional fixes

* duplicated lines removed

* fixes after CI run

* test fixes

* code and test fixes

* supports transition change, added test cases
pull/51031/head
jacekpaszkowski 2021-05-24 13:31:57 +02:00 committed by GitHub
parent c497c0eadd
commit 85495c08b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 772 additions and 11 deletions

View File

@ -6,12 +6,16 @@ import voluptuous as vol
from homeassistant.components.light import (
ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP,
ATTR_EFFECT,
ATTR_HS_COLOR,
ATTR_TRANSITION,
ATTR_WHITE_VALUE,
ENTITY_ID_FORMAT,
SUPPORT_BRIGHTNESS,
SUPPORT_COLOR,
SUPPORT_COLOR_TEMP,
SUPPORT_EFFECT,
SUPPORT_TRANSITION,
SUPPORT_WHITE_VALUE,
LightEntity,
)
@ -49,6 +53,12 @@ CONF_COLOR_TEMPLATE = "color_template"
CONF_COLOR_ACTION = "set_color"
CONF_WHITE_VALUE_TEMPLATE = "white_value_template"
CONF_WHITE_VALUE_ACTION = "set_white_value"
CONF_EFFECT_ACTION = "set_effect"
CONF_EFFECT_LIST_TEMPLATE = "effect_list_template"
CONF_EFFECT_TEMPLATE = "effect_template"
CONF_MAX_MIREDS_TEMPLATE = "max_mireds_template"
CONF_MIN_MIREDS_TEMPLATE = "min_mireds_template"
CONF_SUPPORTS_TRANSITION = "supports_transition_template"
LIGHT_SCHEMA = vol.All(
cv.deprecated(CONF_ENTITY_ID),
@ -70,6 +80,12 @@ LIGHT_SCHEMA = vol.All(
vol.Optional(CONF_COLOR_ACTION): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_WHITE_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_WHITE_VALUE_ACTION): cv.SCRIPT_SCHEMA,
vol.Inclusive(CONF_EFFECT_LIST_TEMPLATE, "effect"): cv.template,
vol.Inclusive(CONF_EFFECT_TEMPLATE, "effect"): cv.template,
vol.Inclusive(CONF_EFFECT_ACTION, "effect"): cv.SCRIPT_SCHEMA,
vol.Optional(CONF_MAX_MIREDS_TEMPLATE): cv.template,
vol.Optional(CONF_MIN_MIREDS_TEMPLATE): cv.template,
vol.Optional(CONF_SUPPORTS_TRANSITION): cv.template,
vol.Optional(CONF_UNIQUE_ID): cv.string,
}
),
@ -108,6 +124,15 @@ async def _async_create_entities(hass, config):
white_value_action = device_config.get(CONF_WHITE_VALUE_ACTION)
white_value_template = device_config.get(CONF_WHITE_VALUE_TEMPLATE)
effect_action = device_config.get(CONF_EFFECT_ACTION)
effect_list_template = device_config.get(CONF_EFFECT_LIST_TEMPLATE)
effect_template = device_config.get(CONF_EFFECT_TEMPLATE)
max_mireds_template = device_config.get(CONF_MAX_MIREDS_TEMPLATE)
min_mireds_template = device_config.get(CONF_MIN_MIREDS_TEMPLATE)
supports_transition_template = device_config.get(CONF_SUPPORTS_TRANSITION)
lights.append(
LightTemplate(
hass,
@ -127,6 +152,12 @@ async def _async_create_entities(hass, config):
color_template,
white_value_action,
white_value_template,
effect_action,
effect_list_template,
effect_template,
max_mireds_template,
min_mireds_template,
supports_transition_template,
unique_id,
)
)
@ -161,6 +192,12 @@ class LightTemplate(TemplateEntity, LightEntity):
color_template,
white_value_action,
white_value_template,
effect_action,
effect_list_template,
effect_template,
max_mireds_template,
min_mireds_template,
supports_transition_template,
unique_id,
):
"""Initialize the light."""
@ -197,12 +234,25 @@ class LightTemplate(TemplateEntity, LightEntity):
hass, white_value_action, friendly_name, domain
)
self._white_value_template = white_value_template
self._effect_script = None
if effect_action is not None:
self._effect_script = Script(hass, effect_action, friendly_name, domain)
self._effect_list_template = effect_list_template
self._effect_template = effect_template
self._max_mireds_template = max_mireds_template
self._min_mireds_template = min_mireds_template
self._supports_transition_template = supports_transition_template
self._state = False
self._brightness = None
self._temperature = None
self._color = None
self._white_value = None
self._effect = None
self._effect_list = None
self._max_mireds = None
self._min_mireds = None
self._supports_transition = False
self._unique_id = unique_id
@property
@ -215,6 +265,22 @@ class LightTemplate(TemplateEntity, LightEntity):
"""Return the CT color value in mireds."""
return self._temperature
@property
def max_mireds(self):
"""Return the max mireds value in mireds."""
if self._max_mireds is not None:
return self._max_mireds
return super().max_mireds
@property
def min_mireds(self):
"""Return the min mireds value in mireds."""
if self._min_mireds is not None:
return self._min_mireds
return super().min_mireds
@property
def white_value(self):
"""Return the white value."""
@ -225,6 +291,16 @@ class LightTemplate(TemplateEntity, LightEntity):
"""Return the hue and saturation color value [float, float]."""
return self._color
@property
def effect(self):
"""Return the effect."""
return self._effect
@property
def effect_list(self):
"""Return the effect list."""
return self._effect_list
@property
def name(self):
"""Return the display name of this light."""
@ -247,6 +323,10 @@ class LightTemplate(TemplateEntity, LightEntity):
supported_features |= SUPPORT_COLOR
if self._white_value_script is not None:
supported_features |= SUPPORT_WHITE_VALUE
if self._effect_script is not None:
supported_features |= SUPPORT_EFFECT
if self._supports_transition is True:
supported_features |= SUPPORT_TRANSITION
return supported_features
@property
@ -268,6 +348,22 @@ class LightTemplate(TemplateEntity, LightEntity):
self._update_brightness,
none_on_template_error=True,
)
if self._max_mireds_template:
self.add_template_attribute(
"_max_mireds_template",
self._max_mireds_template,
None,
self._update_max_mireds,
none_on_template_error=True,
)
if self._min_mireds_template:
self.add_template_attribute(
"_min_mireds_template",
self._min_mireds_template,
None,
self._update_min_mireds,
none_on_template_error=True,
)
if self._temperature_template:
self.add_template_attribute(
"_temperature",
@ -292,6 +388,30 @@ class LightTemplate(TemplateEntity, LightEntity):
self._update_white_value,
none_on_template_error=True,
)
if self._effect_list_template:
self.add_template_attribute(
"_effect_list",
self._effect_list_template,
None,
self._update_effect_list,
none_on_template_error=True,
)
if self._effect_template:
self.add_template_attribute(
"_effect",
self._effect_template,
None,
self._update_effect,
none_on_template_error=True,
)
if self._supports_transition_template:
self.add_template_attribute(
"_supports_transition_template",
self._supports_transition_template,
None,
self._update_supports_transition,
none_on_template_error=True,
)
await super().async_added_to_hass()
async def async_turn_on(self, **kwargs):
@ -324,33 +444,65 @@ class LightTemplate(TemplateEntity, LightEntity):
self._temperature = kwargs[ATTR_COLOR_TEMP]
optimistic_set = True
if ATTR_BRIGHTNESS in kwargs and self._level_script:
await self._level_script.async_run(
{"brightness": kwargs[ATTR_BRIGHTNESS]}, context=self._context
)
elif ATTR_COLOR_TEMP in kwargs and self._temperature_script:
common_params = {}
if ATTR_BRIGHTNESS in kwargs:
common_params["brightness"] = kwargs[ATTR_BRIGHTNESS]
if ATTR_TRANSITION in kwargs and self._supports_transition is True:
common_params["transition"] = kwargs[ATTR_TRANSITION]
if ATTR_COLOR_TEMP in kwargs and self._temperature_script:
common_params["color_temp"] = kwargs[ATTR_COLOR_TEMP]
await self._temperature_script.async_run(
{"color_temp": kwargs[ATTR_COLOR_TEMP]}, context=self._context
common_params, context=self._context
)
elif ATTR_WHITE_VALUE in kwargs and self._white_value_script:
common_params["white_value"] = kwargs[ATTR_WHITE_VALUE]
await self._white_value_script.async_run(
{"white_value": kwargs[ATTR_WHITE_VALUE]}, context=self._context
common_params, context=self._context
)
elif ATTR_EFFECT in kwargs and self._effect_script:
effect = kwargs[ATTR_EFFECT]
if effect not in self._effect_list:
_LOGGER.error(
"Received invalid effect: %s. Expected one of: %s",
effect,
self._effect_list,
exc_info=True,
)
common_params["effect"] = effect
await self._effect_script.async_run(common_params, context=self._context)
elif ATTR_HS_COLOR in kwargs and self._color_script:
hs_value = kwargs[ATTR_HS_COLOR]
common_params["hs"] = hs_value
common_params["h"] = int(hs_value[0])
common_params["s"] = int(hs_value[1])
await self._color_script.async_run(
{"hs": hs_value, "h": int(hs_value[0]), "s": int(hs_value[1])},
common_params,
context=self._context,
)
elif ATTR_BRIGHTNESS in kwargs and self._level_script:
await self._level_script.async_run(common_params, context=self._context)
else:
await self._on_script.async_run(context=self._context)
await self._on_script.async_run(common_params, context=self._context)
if optimistic_set:
self.async_write_ha_state()
async def async_turn_off(self, **kwargs):
"""Turn the light off."""
await self._off_script.async_run(context=self._context)
if ATTR_TRANSITION in kwargs and self._supports_transition is True:
await self._off_script.async_run(
{"transition": kwargs[ATTR_TRANSITION]}, context=self._context
)
else:
await self._off_script.async_run(context=self._context)
if self._template is None:
self._state = False
self.async_write_ha_state()
@ -397,6 +549,45 @@ class LightTemplate(TemplateEntity, LightEntity):
)
self._white_value = None
@callback
def _update_effect_list(self, effect_list):
"""Update the effect list from the template."""
if effect_list in ("None", ""):
self._effect_list = None
return
if not isinstance(effect_list, list):
_LOGGER.error(
"Received invalid effect list: %s. Expected list of strings",
effect_list,
)
self._effect_list = None
return
if len(effect_list) == 0:
self._effect_list = None
return
self._effect_list = effect_list
@callback
def _update_effect(self, effect):
"""Update the effect from the template."""
if effect in ("None", ""):
self._effect = None
return
if effect not in self._effect_list:
_LOGGER.error(
"Received invalid effect: %s. Expected one of: %s",
effect,
self._effect_list,
)
self._effect = None
return
self._effect = effect
@callback
def _update_state(self, result):
"""Update the state from the template."""
@ -479,3 +670,42 @@ class LightTemplate(TemplateEntity, LightEntity):
else:
_LOGGER.error("Received invalid hs_color : (%s)", render)
self._color = None
@callback
def _update_max_mireds(self, render):
"""Update the max mireds from the template."""
try:
if render in ("None", ""):
self._max_mireds = None
return
self._max_mireds = int(render)
except ValueError:
_LOGGER.error(
"Template must supply an integer temperature within the range for this light, or 'None'",
exc_info=True,
)
self._max_mireds = None
@callback
def _update_min_mireds(self, render):
"""Update the min mireds from the template."""
try:
if render in ("None", ""):
self._min_mireds = None
return
self._min_mireds = int(render)
except ValueError:
_LOGGER.error(
"Template must supply an integer temperature within the range for this light, or 'None'",
exc_info=True,
)
self._min_mireds = None
@callback
def _update_supports_transition(self, render):
"""Update the supports transition from the template."""
if render in ("None", ""):
self._supports_transition = False
return
self._supports_transition = bool(render)

View File

@ -8,8 +8,11 @@ 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,
@ -378,6 +381,64 @@ async def test_on_action(hass, calls):
assert len(calls) == 1
async def test_on_action_with_transition(hass, calls):
"""Test on action with transition."""
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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}}",
},
},
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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
print(calls[0].data)
assert calls[0].data["transition"] == 5
async def test_on_action_optimistic(hass, calls):
"""Test on action with optimistic state."""
assert await setup.async_setup_component(
@ -443,7 +504,9 @@ async def test_off_action(hass, calls):
"service": "light.turn_on",
"entity_id": "light.test_state",
},
"turn_off": {"service": "test.automation"},
"turn_off": {
"service": "test.automation",
},
"set_level": {
"service": "light.turn_on",
"data_template": {
@ -477,6 +540,63 @@ async def test_off_action(hass, calls):
assert len(calls) == 1
async def test_off_action_with_transition(hass, calls):
"""Test off action with transition."""
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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}}",
},
},
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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
async def test_off_action_optimistic(hass, calls):
"""Test off action with optimistic state."""
assert await setup.async_setup_component(
@ -1119,6 +1239,417 @@ async def test_color_template(hass, expected_hs, template):
assert state.attributes.get("hs_color") == expected_hs
async def test_effect_action_valid_effect(hass, calls):
"""Test setting valid effect with template."""
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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' }}",
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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"
async def test_effect_action_invalid_effect(hass, calls):
"""Test setting invalid effect with template."""
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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 }}",
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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(
"expected_effect_list,template",
[
(
["Strobe color", "Police", "Christmas", "RGB", "Random Loop"],
"{{ ['Strobe color', 'Police', 'Christmas', 'RGB', 'Random Loop'] }}",
),
(
["Police", "RGB", "Random Loop"],
"{{ ['Police', 'RGB', 'Random Loop'] }}",
),
(None, "{{ [] }}"),
(None, "{{ '[]' }}"),
(None, "{{ 124 }}"),
(None, "{{ '124' }}"),
(None, "{{ none }}"),
(None, ""),
],
)
async def test_effect_list_template(hass, expected_effect_list, template):
"""Test the template for the effect list."""
with assert_setup_component(1, light.DOMAIN):
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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": template,
"effect_template": "{{ None }}",
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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(
"expected_effect,template",
[
(None, "Disco"),
(None, "None"),
(None, "{{ None }}"),
("Police", "Police"),
("Strobe color", "{{ 'Strobe color' }}"),
],
)
async def test_effect_template(hass, expected_effect, template):
"""Test the template for the effect."""
with assert_setup_component(1, light.DOMAIN):
assert await setup.async_setup_component(
hass,
light.DOMAIN,
{
"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": template,
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
state = hass.states.get("light.test_template_light")
assert state is not None
assert state.attributes.get("effect") == expected_effect
@pytest.mark.parametrize(
"expected_min_mireds,template",
[
(118, "{{118}}"),
(153, "{{x - 12}}"),
(153, "None"),
(153, "{{ none }}"),
(153, ""),
(153, "{{ 'a' }}"),
],
)
async def test_min_mireds_template(hass, expected_min_mireds, template):
"""Test the template for the min mireds."""
with assert_setup_component(1, light.DOMAIN):
assert await setup.async_setup_component(
hass,
"light",
{
"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": template,
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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(
"expected_max_mireds,template",
[
(488, "{{488}}"),
(500, "{{x - 12}}"),
(500, "None"),
(500, "{{ none }}"),
(500, ""),
(500, "{{ 'a' }}"),
],
)
async def test_max_mireds_template(hass, expected_max_mireds, template):
"""Test the template for the max mireds."""
with assert_setup_component(1, light.DOMAIN):
assert await setup.async_setup_component(
hass,
"light",
{
"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": template,
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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(
"expected_supports_transition,template",
[
(True, "{{true}}"),
(True, "{{1 == 1}}"),
(False, "{{false}}"),
(False, "{{ none }}"),
(False, ""),
(False, "None"),
],
)
async def test_supports_transition_template(
hass, expected_supports_transition, template
):
"""Test the template for the supports transition."""
with assert_setup_component(1, light.DOMAIN):
assert await setup.async_setup_component(
hass,
"light",
{
"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": template,
}
},
}
},
)
await hass.async_block_till_done()
await hass.async_start()
await hass.async_block_till_done()
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
async def test_available_template_with_entities(hass):
"""Test availability templates with values from other entities."""
await setup.async_setup_component(