Support this variable in template cover actions ()

pull/71821/head
Erik Montnemery 2022-05-13 18:34:00 +02:00 committed by GitHub
parent a17fa6d6d5
commit 83080dbba8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 81 deletions
homeassistant/components/template
tests/components/template

View File

@ -323,10 +323,12 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_open_cover(self, **kwargs): async def async_open_cover(self, **kwargs):
"""Move the cover up.""" """Move the cover up."""
if self._open_script: if self._open_script:
await self._open_script.async_run(context=self._context) await self.async_run_script(self._open_script, context=self._context)
elif self._position_script: elif self._position_script:
await self._position_script.async_run( await self.async_run_script(
{"position": 100}, context=self._context self._position_script,
run_variables={"position": 100},
context=self._context,
) )
if self._optimistic: if self._optimistic:
self._position = 100 self._position = 100
@ -335,10 +337,12 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_close_cover(self, **kwargs): async def async_close_cover(self, **kwargs):
"""Move the cover down.""" """Move the cover down."""
if self._close_script: if self._close_script:
await self._close_script.async_run(context=self._context) await self.async_run_script(self._close_script, context=self._context)
elif self._position_script: elif self._position_script:
await self._position_script.async_run( await self.async_run_script(
{"position": 0}, context=self._context self._position_script,
run_variables={"position": 0},
context=self._context,
) )
if self._optimistic: if self._optimistic:
self._position = 0 self._position = 0
@ -347,13 +351,15 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_stop_cover(self, **kwargs): async def async_stop_cover(self, **kwargs):
"""Fire the stop action.""" """Fire the stop action."""
if self._stop_script: if self._stop_script:
await self._stop_script.async_run(context=self._context) await self.async_run_script(self._stop_script, context=self._context)
async def async_set_cover_position(self, **kwargs): async def async_set_cover_position(self, **kwargs):
"""Set cover position.""" """Set cover position."""
self._position = kwargs[ATTR_POSITION] self._position = kwargs[ATTR_POSITION]
await self._position_script.async_run( await self.async_run_script(
{"position": self._position}, context=self._context self._position_script,
run_variables={"position": self._position},
context=self._context,
) )
if self._optimistic: if self._optimistic:
self.async_write_ha_state() self.async_write_ha_state()
@ -361,8 +367,10 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_open_cover_tilt(self, **kwargs): async def async_open_cover_tilt(self, **kwargs):
"""Tilt the cover open.""" """Tilt the cover open."""
self._tilt_value = 100 self._tilt_value = 100
await self._tilt_script.async_run( await self.async_run_script(
{"tilt": self._tilt_value}, context=self._context self._tilt_script,
run_variables={"tilt": self._tilt_value},
context=self._context,
) )
if self._tilt_optimistic: if self._tilt_optimistic:
self.async_write_ha_state() self.async_write_ha_state()
@ -370,8 +378,10 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_close_cover_tilt(self, **kwargs): async def async_close_cover_tilt(self, **kwargs):
"""Tilt the cover closed.""" """Tilt the cover closed."""
self._tilt_value = 0 self._tilt_value = 0
await self._tilt_script.async_run( await self.async_run_script(
{"tilt": self._tilt_value}, context=self._context self._tilt_script,
run_variables={"tilt": self._tilt_value},
context=self._context,
) )
if self._tilt_optimistic: if self._tilt_optimistic:
self.async_write_ha_state() self.async_write_ha_state()
@ -379,8 +389,10 @@ class CoverTemplate(TemplateEntity, CoverEntity):
async def async_set_cover_tilt_position(self, **kwargs): async def async_set_cover_tilt_position(self, **kwargs):
"""Move the cover tilt to a specific position.""" """Move the cover tilt to a specific position."""
self._tilt_value = kwargs[ATTR_TILT_POSITION] self._tilt_value = kwargs[ATTR_TILT_POSITION]
await self._tilt_script.async_run( await self.async_run_script(
{"tilt": self._tilt_value}, context=self._context self._tilt_script,
run_variables={"tilt": self._tilt_value},
context=self._context,
) )
if self._tilt_optimistic: if self._tilt_optimistic:
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -4,10 +4,7 @@ import pytest
from homeassistant import setup from homeassistant import setup
from homeassistant.components.cover import ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN from homeassistant.components.cover import ATTR_POSITION, ATTR_TILT_POSITION, DOMAIN
from homeassistant.const import ( from homeassistant.const import (
ATTR_DOMAIN,
ATTR_ENTITY_ID, ATTR_ENTITY_ID,
ATTR_SERVICE_DATA,
EVENT_CALL_SERVICE,
SERVICE_CLOSE_COVER, SERVICE_CLOSE_COVER,
SERVICE_CLOSE_COVER_TILT, SERVICE_CLOSE_COVER_TILT,
SERVICE_OPEN_COVER, SERVICE_OPEN_COVER,
@ -25,40 +22,26 @@ from homeassistant.const import (
STATE_OPENING, STATE_OPENING,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
) )
from homeassistant.core import callback
from tests.common import assert_setup_component from tests.common import assert_setup_component
ENTITY_COVER = "cover.test_template_cover" ENTITY_COVER = "cover.test_template_cover"
@pytest.fixture
def service_calls(hass):
"""Track service call events for cover.test_state."""
events = []
entity_id = "cover.test_state"
@callback
def capture_events(event):
if event.data[ATTR_DOMAIN] != DOMAIN:
return
if event.data[ATTR_SERVICE_DATA][ATTR_ENTITY_ID] != [entity_id]:
return
events.append(event)
hass.bus.async_listen(EVENT_CALL_SERVICE, capture_events)
return events
OPEN_CLOSE_COVER_CONFIG = { OPEN_CLOSE_COVER_CONFIG = {
"open_cover": { "open_cover": {
"service": "cover.open_cover", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"action": "open_cover",
"caller": "{{ this.entity_id }}",
},
}, },
"close_cover": { "close_cover": {
"service": "cover.close_cover", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"action": "close_cover",
"caller": "{{ this.entity_id }}",
},
}, },
} }
@ -299,8 +282,11 @@ async def test_template_out_of_bounds(hass, start_ha):
"test_template_cover": { "test_template_cover": {
"value_template": "{{ 1 == 1 }}", "value_template": "{{ 1 == 1 }}",
"open_cover": { "open_cover": {
"service": "cover.open_cover", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"action": "open_cover",
"caller": "{{ this.entity_id }}",
},
}, },
} }
}, },
@ -331,7 +317,7 @@ async def test_template_open_or_position(hass, start_ha, caplog_setup_text):
}, },
], ],
) )
async def test_open_action(hass, start_ha, service_calls): async def test_open_action(hass, start_ha, calls):
"""Test the open_cover command.""" """Test the open_cover command."""
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.state == STATE_CLOSED assert state.state == STATE_CLOSED
@ -341,8 +327,9 @@ async def test_open_action(hass, start_ha, service_calls):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(service_calls) == 1 assert len(calls) == 1
assert service_calls[0].data["service"] == "open_cover" assert calls[0].data["action"] == "open_cover"
assert calls[0].data["caller"] == "cover.test_template_cover"
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @pytest.mark.parametrize("count,domain", [(1, DOMAIN)])
@ -357,8 +344,11 @@ async def test_open_action(hass, start_ha, service_calls):
**OPEN_CLOSE_COVER_CONFIG, **OPEN_CLOSE_COVER_CONFIG,
"position_template": "{{ 100 }}", "position_template": "{{ 100 }}",
"stop_cover": { "stop_cover": {
"service": "cover.stop_cover", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"action": "stop_cover",
"caller": "{{ this.entity_id }}",
},
}, },
} }
}, },
@ -366,7 +356,7 @@ async def test_open_action(hass, start_ha, service_calls):
}, },
], ],
) )
async def test_close_stop_action(hass, start_ha, service_calls): async def test_close_stop_action(hass, start_ha, calls):
"""Test the close-cover and stop_cover commands.""" """Test the close-cover and stop_cover commands."""
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.state == STATE_OPEN assert state.state == STATE_OPEN
@ -381,9 +371,11 @@ async def test_close_stop_action(hass, start_ha, service_calls):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(service_calls) == 2 assert len(calls) == 2
assert service_calls[0].data["service"] == "close_cover" assert calls[0].data["action"] == "close_cover"
assert service_calls[1].data["service"] == "stop_cover" assert calls[0].data["caller"] == "cover.test_template_cover"
assert calls[1].data["action"] == "stop_cover"
assert calls[1].data["caller"] == "cover.test_template_cover"
@pytest.mark.parametrize("count,domain", [(1, "input_number")]) @pytest.mark.parametrize("count,domain", [(1, "input_number")])
@ -393,7 +385,7 @@ async def test_close_stop_action(hass, start_ha, service_calls):
{"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}}, {"input_number": {"test": {"min": "0", "max": "100", "initial": "42"}}},
], ],
) )
async def test_set_position(hass, start_ha, service_calls): async def test_set_position(hass, start_ha, calls):
"""Test the set_position command.""" """Test the set_position command."""
with assert_setup_component(1, "cover"): with assert_setup_component(1, "cover"):
assert await setup.async_setup_component( assert await setup.async_setup_component(
@ -405,9 +397,12 @@ async def test_set_position(hass, start_ha, service_calls):
"covers": { "covers": {
"test_template_cover": { "test_template_cover": {
"set_cover_position": { "set_cover_position": {
"service": "cover.set_cover_position", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"data_template": {"position": "{{ position }}"}, "action": "set_cover_position",
"caller": "{{ this.entity_id }}",
"position": "{{ position }}",
},
}, },
} }
}, },
@ -430,9 +425,10 @@ async def test_set_position(hass, start_ha, service_calls):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == 100.0 assert state.attributes.get("current_position") == 100.0
assert len(service_calls) == 1 assert len(calls) == 1
assert service_calls[-1].data["service"] == "set_cover_position" assert calls[-1].data["action"] == "set_cover_position"
assert service_calls[-1].data["service_data"]["position"] == 100 assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["position"] == 100
await hass.services.async_call( await hass.services.async_call(
DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True DOMAIN, SERVICE_CLOSE_COVER, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
@ -440,9 +436,10 @@ async def test_set_position(hass, start_ha, service_calls):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == 0.0 assert state.attributes.get("current_position") == 0.0
assert len(service_calls) == 2 assert len(calls) == 2
assert service_calls[-1].data["service"] == "set_cover_position" assert calls[-1].data["action"] == "set_cover_position"
assert service_calls[-1].data["service_data"]["position"] == 0 assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["position"] == 0
await hass.services.async_call( await hass.services.async_call(
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
@ -450,9 +447,10 @@ async def test_set_position(hass, start_ha, service_calls):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == 100.0 assert state.attributes.get("current_position") == 100.0
assert len(service_calls) == 3 assert len(calls) == 3
assert service_calls[-1].data["service"] == "set_cover_position" assert calls[-1].data["action"] == "set_cover_position"
assert service_calls[-1].data["service_data"]["position"] == 100 assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["position"] == 100
await hass.services.async_call( await hass.services.async_call(
DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True DOMAIN, SERVICE_TOGGLE, {ATTR_ENTITY_ID: ENTITY_COVER}, blocking=True
@ -460,9 +458,10 @@ async def test_set_position(hass, start_ha, service_calls):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == 0.0 assert state.attributes.get("current_position") == 0.0
assert len(service_calls) == 4 assert len(calls) == 4
assert service_calls[-1].data["service"] == "set_cover_position" assert calls[-1].data["action"] == "set_cover_position"
assert service_calls[-1].data["service_data"]["position"] == 0 assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["position"] == 0
await hass.services.async_call( await hass.services.async_call(
DOMAIN, DOMAIN,
@ -473,9 +472,10 @@ async def test_set_position(hass, start_ha, service_calls):
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == 25.0 assert state.attributes.get("current_position") == 25.0
assert len(service_calls) == 5 assert len(calls) == 5
assert service_calls[-1].data["service"] == "set_cover_position" assert calls[-1].data["action"] == "set_cover_position"
assert service_calls[-1].data["service_data"]["position"] == 25 assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["position"] == 25
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @pytest.mark.parametrize("count,domain", [(1, DOMAIN)])
@ -489,9 +489,12 @@ async def test_set_position(hass, start_ha, service_calls):
"test_template_cover": { "test_template_cover": {
**OPEN_CLOSE_COVER_CONFIG, **OPEN_CLOSE_COVER_CONFIG,
"set_cover_tilt_position": { "set_cover_tilt_position": {
"service": "cover.set_cover_tilt_position", "service": "test.automation",
"entity_id": "cover.test_state", "data_template": {
"data_template": {"tilt_position": "{{ tilt }}"}, "action": "set_cover_tilt_position",
"caller": "{{ this.entity_id }}",
"tilt_position": "{{ tilt }}",
},
}, },
} }
}, },
@ -511,9 +514,7 @@ async def test_set_position(hass, start_ha, service_calls):
(SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, 0), (SERVICE_CLOSE_COVER_TILT, {ATTR_ENTITY_ID: ENTITY_COVER}, 0),
], ],
) )
async def test_set_tilt_position( async def test_set_tilt_position(hass, service, attr, start_ha, calls, tilt_position):
hass, service, attr, start_ha, service_calls, tilt_position
):
"""Test the set_tilt_position command.""" """Test the set_tilt_position command."""
await hass.services.async_call( await hass.services.async_call(
DOMAIN, DOMAIN,
@ -523,9 +524,10 @@ async def test_set_tilt_position(
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert len(service_calls) == 1 assert len(calls) == 1
assert service_calls[-1].data["service"] == "set_cover_tilt_position" assert calls[-1].data["action"] == "set_cover_tilt_position"
assert service_calls[-1].data["service_data"]["tilt_position"] == tilt_position assert calls[-1].data["caller"] == "cover.test_template_cover"
assert calls[-1].data["tilt_position"] == tilt_position
@pytest.mark.parametrize("count,domain", [(1, DOMAIN)]) @pytest.mark.parametrize("count,domain", [(1, DOMAIN)])