Support this variable in template fan actions (#71795)
This commit is contained in:
parent
8b412acc98
commit
a17fa6d6d5
2 changed files with 152 additions and 57 deletions
|
@ -251,8 +251,9 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Turn on the fan."""
|
"""Turn on the fan."""
|
||||||
await self._on_script.async_run(
|
await self.async_run_script(
|
||||||
{
|
self._on_script,
|
||||||
|
run_variables={
|
||||||
ATTR_PERCENTAGE: percentage,
|
ATTR_PERCENTAGE: percentage,
|
||||||
ATTR_PRESET_MODE: preset_mode,
|
ATTR_PRESET_MODE: preset_mode,
|
||||||
},
|
},
|
||||||
|
@ -267,7 +268,7 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
|
|
||||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||||
"""Turn off the fan."""
|
"""Turn off the fan."""
|
||||||
await self._off_script.async_run(context=self._context)
|
await self.async_run_script(self._off_script, context=self._context)
|
||||||
self._state = STATE_OFF
|
self._state = STATE_OFF
|
||||||
|
|
||||||
async def async_set_percentage(self, percentage: int) -> None:
|
async def async_set_percentage(self, percentage: int) -> None:
|
||||||
|
@ -277,8 +278,10 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
self._preset_mode = None
|
self._preset_mode = None
|
||||||
|
|
||||||
if self._set_percentage_script:
|
if self._set_percentage_script:
|
||||||
await self._set_percentage_script.async_run(
|
await self.async_run_script(
|
||||||
{ATTR_PERCENTAGE: self._percentage}, context=self._context
|
self._set_percentage_script,
|
||||||
|
run_variables={ATTR_PERCENTAGE: self._percentage},
|
||||||
|
context=self._context,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||||
|
@ -297,8 +300,10 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
self._percentage = None
|
self._percentage = None
|
||||||
|
|
||||||
if self._set_preset_mode_script:
|
if self._set_preset_mode_script:
|
||||||
await self._set_preset_mode_script.async_run(
|
await self.async_run_script(
|
||||||
{ATTR_PRESET_MODE: self._preset_mode}, context=self._context
|
self._set_preset_mode_script,
|
||||||
|
run_variables={ATTR_PRESET_MODE: self._preset_mode},
|
||||||
|
context=self._context,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_oscillate(self, oscillating: bool) -> None:
|
async def async_oscillate(self, oscillating: bool) -> None:
|
||||||
|
@ -307,8 +312,10 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
return
|
return
|
||||||
|
|
||||||
self._oscillating = oscillating
|
self._oscillating = oscillating
|
||||||
await self._set_oscillating_script.async_run(
|
await self.async_run_script(
|
||||||
{ATTR_OSCILLATING: oscillating}, context=self._context
|
self._set_oscillating_script,
|
||||||
|
run_variables={ATTR_OSCILLATING: self.oscillating},
|
||||||
|
context=self._context,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_set_direction(self, direction: str) -> None:
|
async def async_set_direction(self, direction: str) -> None:
|
||||||
|
@ -318,8 +325,10 @@ class TemplateFan(TemplateEntity, FanEntity):
|
||||||
|
|
||||||
if direction in _VALID_DIRECTIONS:
|
if direction in _VALID_DIRECTIONS:
|
||||||
self._direction = direction
|
self._direction = direction
|
||||||
await self._set_direction_script.async_run(
|
await self.async_run_script(
|
||||||
{ATTR_DIRECTION: direction}, context=self._context
|
self._set_direction_script,
|
||||||
|
run_variables={ATTR_DIRECTION: direction},
|
||||||
|
context=self._context,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
|
|
@ -383,20 +383,25 @@ async def test_invalid_availability_template_keeps_component_available(
|
||||||
assert "x" in caplog_setup_text
|
assert "x" in caplog_setup_text
|
||||||
|
|
||||||
|
|
||||||
async def test_on_off(hass):
|
async def test_on_off(hass, calls):
|
||||||
"""Test turn on and turn off."""
|
"""Test turn on and turn off."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
expected_calls = 0
|
||||||
|
|
||||||
for func, state in [
|
for func, state, action in [
|
||||||
(common.async_turn_on, STATE_ON),
|
(common.async_turn_on, STATE_ON, "turn_on"),
|
||||||
(common.async_turn_off, STATE_OFF),
|
(common.async_turn_off, STATE_OFF, "turn_off"),
|
||||||
]:
|
]:
|
||||||
await func(hass, _TEST_FAN)
|
await func(hass, _TEST_FAN)
|
||||||
assert hass.states.get(_STATE_INPUT_BOOLEAN).state == state
|
assert hass.states.get(_STATE_INPUT_BOOLEAN).state == state
|
||||||
_verify(hass, state, 0, None, None, None)
|
_verify(hass, state, 0, None, None, None)
|
||||||
|
expected_calls += 1
|
||||||
|
assert len(calls) == expected_calls
|
||||||
|
assert calls[-1].data["action"] == action
|
||||||
|
assert calls[-1].data["caller"] == _TEST_FAN
|
||||||
|
|
||||||
|
|
||||||
async def test_set_invalid_direction_from_initial_stage(hass):
|
async def test_set_invalid_direction_from_initial_stage(hass, calls):
|
||||||
"""Test set invalid direction when fan is in initial state."""
|
"""Test set invalid direction when fan is in initial state."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
|
||||||
|
@ -407,29 +412,43 @@ async def test_set_invalid_direction_from_initial_stage(hass):
|
||||||
_verify(hass, STATE_ON, 0, None, None, None)
|
_verify(hass, STATE_ON, 0, None, None, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_set_osc(hass):
|
async def test_set_osc(hass, calls):
|
||||||
"""Test set oscillating."""
|
"""Test set oscillating."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
expected_calls = 0
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN)
|
await common.async_turn_on(hass, _TEST_FAN)
|
||||||
|
expected_calls += 1
|
||||||
for state in [True, False]:
|
for state in [True, False]:
|
||||||
await common.async_oscillate(hass, _TEST_FAN, state)
|
await common.async_oscillate(hass, _TEST_FAN, state)
|
||||||
assert hass.states.get(_OSC_INPUT).state == str(state)
|
assert hass.states.get(_OSC_INPUT).state == str(state)
|
||||||
_verify(hass, STATE_ON, 0, state, None, None)
|
_verify(hass, STATE_ON, 0, state, None, None)
|
||||||
|
expected_calls += 1
|
||||||
|
assert len(calls) == expected_calls
|
||||||
|
assert calls[-1].data["action"] == "set_oscillating"
|
||||||
|
assert calls[-1].data["caller"] == _TEST_FAN
|
||||||
|
assert calls[-1].data["option"] == state
|
||||||
|
|
||||||
|
|
||||||
async def test_set_direction(hass):
|
async def test_set_direction(hass, calls):
|
||||||
"""Test set valid direction."""
|
"""Test set valid direction."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
expected_calls = 0
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN)
|
await common.async_turn_on(hass, _TEST_FAN)
|
||||||
|
expected_calls += 1
|
||||||
for cmd in [DIRECTION_FORWARD, DIRECTION_REVERSE]:
|
for cmd in [DIRECTION_FORWARD, DIRECTION_REVERSE]:
|
||||||
await common.async_set_direction(hass, _TEST_FAN, cmd)
|
await common.async_set_direction(hass, _TEST_FAN, cmd)
|
||||||
assert hass.states.get(_DIRECTION_INPUT_SELECT).state == cmd
|
assert hass.states.get(_DIRECTION_INPUT_SELECT).state == cmd
|
||||||
_verify(hass, STATE_ON, 0, None, cmd, None)
|
_verify(hass, STATE_ON, 0, None, cmd, None)
|
||||||
|
expected_calls += 1
|
||||||
|
assert len(calls) == expected_calls
|
||||||
|
assert calls[-1].data["action"] == "set_direction"
|
||||||
|
assert calls[-1].data["caller"] == _TEST_FAN
|
||||||
|
assert calls[-1].data["option"] == cmd
|
||||||
|
|
||||||
|
|
||||||
async def test_set_invalid_direction(hass):
|
async def test_set_invalid_direction(hass, calls):
|
||||||
"""Test set invalid direction when fan has valid direction."""
|
"""Test set invalid direction when fan has valid direction."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
|
||||||
|
@ -440,30 +459,36 @@ async def test_set_invalid_direction(hass):
|
||||||
_verify(hass, STATE_ON, 0, None, DIRECTION_FORWARD, None)
|
_verify(hass, STATE_ON, 0, None, DIRECTION_FORWARD, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_preset_modes(hass):
|
async def test_preset_modes(hass, calls):
|
||||||
"""Test preset_modes."""
|
"""Test preset_modes."""
|
||||||
await _register_components(
|
await _register_components(
|
||||||
hass, ["off", "low", "medium", "high", "auto", "smart"], ["auto", "smart"]
|
hass, ["off", "low", "medium", "high", "auto", "smart"], ["auto", "smart"]
|
||||||
)
|
)
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN)
|
await common.async_turn_on(hass, _TEST_FAN)
|
||||||
for extra, state in [
|
for extra, state, expected_calls in [
|
||||||
("auto", "auto"),
|
("auto", "auto", 2),
|
||||||
("smart", "smart"),
|
("smart", "smart", 3),
|
||||||
("invalid", "smart"),
|
("invalid", "smart", 3),
|
||||||
]:
|
]:
|
||||||
await common.async_set_preset_mode(hass, _TEST_FAN, extra)
|
await common.async_set_preset_mode(hass, _TEST_FAN, extra)
|
||||||
assert hass.states.get(_PRESET_MODE_INPUT_SELECT).state == state
|
assert hass.states.get(_PRESET_MODE_INPUT_SELECT).state == state
|
||||||
|
assert len(calls) == expected_calls
|
||||||
|
assert calls[-1].data["action"] == "set_preset_mode"
|
||||||
|
assert calls[-1].data["caller"] == _TEST_FAN
|
||||||
|
assert calls[-1].data["option"] == state
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN, preset_mode="auto")
|
await common.async_turn_on(hass, _TEST_FAN, preset_mode="auto")
|
||||||
assert hass.states.get(_PRESET_MODE_INPUT_SELECT).state == "auto"
|
assert hass.states.get(_PRESET_MODE_INPUT_SELECT).state == "auto"
|
||||||
|
|
||||||
|
|
||||||
async def test_set_percentage(hass):
|
async def test_set_percentage(hass, calls):
|
||||||
"""Test set valid speed percentage."""
|
"""Test set valid speed percentage."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
expected_calls = 0
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN)
|
await common.async_turn_on(hass, _TEST_FAN)
|
||||||
|
expected_calls += 1
|
||||||
for state, value in [
|
for state, value in [
|
||||||
(STATE_ON, 100),
|
(STATE_ON, 100),
|
||||||
(STATE_ON, 66),
|
(STATE_ON, 66),
|
||||||
|
@ -472,13 +497,18 @@ async def test_set_percentage(hass):
|
||||||
await common.async_set_percentage(hass, _TEST_FAN, value)
|
await common.async_set_percentage(hass, _TEST_FAN, value)
|
||||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == value
|
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == value
|
||||||
_verify(hass, state, value, None, None, None)
|
_verify(hass, state, value, None, None, None)
|
||||||
|
expected_calls += 1
|
||||||
|
assert len(calls) == expected_calls
|
||||||
|
assert calls[-1].data["action"] == "set_value"
|
||||||
|
assert calls[-1].data["caller"] == _TEST_FAN
|
||||||
|
assert calls[-1].data["value"] == value
|
||||||
|
|
||||||
await common.async_turn_on(hass, _TEST_FAN, percentage=50)
|
await common.async_turn_on(hass, _TEST_FAN, percentage=50)
|
||||||
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == 50
|
assert int(float(hass.states.get(_PERCENTAGE_INPUT_NUMBER).state)) == 50
|
||||||
_verify(hass, STATE_ON, 50, None, None, None)
|
_verify(hass, STATE_ON, 50, None, None, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_increase_decrease_speed(hass):
|
async def test_increase_decrease_speed(hass, calls):
|
||||||
"""Test set valid increase and decrease speed."""
|
"""Test set valid increase and decrease speed."""
|
||||||
await _register_components(hass, speed_count=3)
|
await _register_components(hass, speed_count=3)
|
||||||
|
|
||||||
|
@ -495,7 +525,7 @@ async def test_increase_decrease_speed(hass):
|
||||||
_verify(hass, state, value, None, None, None)
|
_verify(hass, state, value, None, None, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_increase_decrease_speed_default_speed_count(hass):
|
async def test_increase_decrease_speed_default_speed_count(hass, calls):
|
||||||
"""Test set valid increase and decrease speed."""
|
"""Test set valid increase and decrease speed."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
|
||||||
|
@ -512,7 +542,7 @@ async def test_increase_decrease_speed_default_speed_count(hass):
|
||||||
_verify(hass, state, value, None, None, None)
|
_verify(hass, state, value, None, None, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_set_invalid_osc_from_initial_state(hass):
|
async def test_set_invalid_osc_from_initial_state(hass, calls):
|
||||||
"""Test set invalid oscillating when fan is in initial state."""
|
"""Test set invalid oscillating when fan is in initial state."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
|
||||||
|
@ -523,7 +553,7 @@ async def test_set_invalid_osc_from_initial_state(hass):
|
||||||
_verify(hass, STATE_ON, 0, None, None, None)
|
_verify(hass, STATE_ON, 0, None, None, None)
|
||||||
|
|
||||||
|
|
||||||
async def test_set_invalid_osc(hass):
|
async def test_set_invalid_osc(hass, calls):
|
||||||
"""Test set invalid oscillating when fan has valid osc."""
|
"""Test set invalid oscillating when fan has valid osc."""
|
||||||
await _register_components(hass)
|
await _register_components(hass)
|
||||||
|
|
||||||
|
@ -616,10 +646,19 @@ async def _register_components(
|
||||||
"percentage_template": "{{ states('input_number.percentage') }}",
|
"percentage_template": "{{ states('input_number.percentage') }}",
|
||||||
"oscillating_template": "{{ states('input_select.osc') }}",
|
"oscillating_template": "{{ states('input_select.osc') }}",
|
||||||
"direction_template": "{{ states('input_select.direction') }}",
|
"direction_template": "{{ states('input_select.direction') }}",
|
||||||
"turn_on": {
|
"turn_on": [
|
||||||
"service": "input_boolean.turn_on",
|
{
|
||||||
"entity_id": _STATE_INPUT_BOOLEAN,
|
"service": "input_boolean.turn_on",
|
||||||
},
|
"entity_id": _STATE_INPUT_BOOLEAN,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {
|
||||||
|
"action": "turn_on",
|
||||||
|
"caller": "{{ this.entity_id }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
"turn_off": [
|
"turn_off": [
|
||||||
{
|
{
|
||||||
"service": "input_boolean.turn_off",
|
"service": "input_boolean.turn_off",
|
||||||
|
@ -632,35 +671,82 @@ async def _register_components(
|
||||||
"value": 0,
|
"value": 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {
|
||||||
|
"action": "turn_off",
|
||||||
|
"caller": "{{ this.entity_id }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"set_preset_mode": {
|
"set_preset_mode": [
|
||||||
"service": "input_select.select_option",
|
{
|
||||||
"data_template": {
|
"service": "input_select.select_option",
|
||||||
"entity_id": _PRESET_MODE_INPUT_SELECT,
|
"data_template": {
|
||||||
"option": "{{ preset_mode }}",
|
"entity_id": _PRESET_MODE_INPUT_SELECT,
|
||||||
|
"option": "{{ preset_mode }}",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
"set_percentage": {
|
"service": "test.automation",
|
||||||
"service": "input_number.set_value",
|
"data_template": {
|
||||||
"data_template": {
|
"action": "set_preset_mode",
|
||||||
"entity_id": _PERCENTAGE_INPUT_NUMBER,
|
"caller": "{{ this.entity_id }}",
|
||||||
"value": "{{ percentage }}",
|
"option": "{{ preset_mode }}",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
"set_oscillating": {
|
"set_percentage": [
|
||||||
"service": "input_select.select_option",
|
{
|
||||||
"data_template": {
|
"service": "input_number.set_value",
|
||||||
"entity_id": _OSC_INPUT,
|
"data_template": {
|
||||||
"option": "{{ oscillating }}",
|
"entity_id": _PERCENTAGE_INPUT_NUMBER,
|
||||||
|
"value": "{{ percentage }}",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
{
|
||||||
"set_direction": {
|
"service": "test.automation",
|
||||||
"service": "input_select.select_option",
|
"data_template": {
|
||||||
"data_template": {
|
"action": "set_value",
|
||||||
"entity_id": _DIRECTION_INPUT_SELECT,
|
"caller": "{{ this.entity_id }}",
|
||||||
"option": "{{ direction }}",
|
"value": "{{ percentage }}",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
],
|
||||||
|
"set_oscillating": [
|
||||||
|
{
|
||||||
|
"service": "input_select.select_option",
|
||||||
|
"data_template": {
|
||||||
|
"entity_id": _OSC_INPUT,
|
||||||
|
"option": "{{ oscillating }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {
|
||||||
|
"action": "set_oscillating",
|
||||||
|
"caller": "{{ this.entity_id }}",
|
||||||
|
"option": "{{ oscillating }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"set_direction": [
|
||||||
|
{
|
||||||
|
"service": "input_select.select_option",
|
||||||
|
"data_template": {
|
||||||
|
"entity_id": _DIRECTION_INPUT_SELECT,
|
||||||
|
"option": "{{ direction }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"service": "test.automation",
|
||||||
|
"data_template": {
|
||||||
|
"action": "set_direction",
|
||||||
|
"caller": "{{ this.entity_id }}",
|
||||||
|
"option": "{{ direction }}",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
if preset_modes:
|
if preset_modes:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue