Support unknown state, position or tilt for template cover (#91172)

* Support unknown state for template cover

* Remove not related changes
This commit is contained in:
Jan Bouwhuis 2023-04-12 21:23:24 +02:00 committed by GitHub
parent 1ef6391e9c
commit 722b991234
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 16 deletions

View file

@ -52,6 +52,7 @@ _VALID_STATES = [
STATE_CLOSING, STATE_CLOSING,
"true", "true",
"false", "false",
"none",
] ]
CONF_POSITION_TEMPLATE = "position_template" CONF_POSITION_TEMPLATE = "position_template"
@ -238,6 +239,10 @@ class CoverTemplate(TemplateEntity, CoverEntity):
@callback @callback
def _update_position(self, result): def _update_position(self, result):
if result is None:
self._position = None
return
try: try:
state = float(result) state = float(result)
except ValueError as err: except ValueError as err:
@ -256,6 +261,10 @@ class CoverTemplate(TemplateEntity, CoverEntity):
@callback @callback
def _update_tilt(self, result): def _update_tilt(self, result):
if result is None:
self._tilt_value = None
return
try: try:
state = float(result) state = float(result)
except ValueError as err: except ValueError as err:

View file

@ -1,4 +1,6 @@
"""The tests for the Template cover platform.""" """The tests for the Template cover platform."""
from typing import Any
import pytest import pytest
from homeassistant import setup from homeassistant import setup
@ -149,6 +151,72 @@ async def test_template_state_text(
assert text in caplog.text assert text in caplog.text
@pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)])
@pytest.mark.parametrize(
("config", "entity", "set_state", "test_state", "attr"),
[
(
{
DOMAIN: {
"platform": "template",
"covers": {
"test_template_cover": {
**OPEN_CLOSE_COVER_CONFIG,
"position_template": (
"{{ states.cover.test.attributes.position }}"
),
"value_template": "{{ states.cover.test_state.state }}",
}
},
}
},
"cover.test_state",
"",
STATE_UNKNOWN,
{},
),
(
{
DOMAIN: {
"platform": "template",
"covers": {
"test_template_cover": {
**OPEN_CLOSE_COVER_CONFIG,
"position_template": (
"{{ states.cover.test.attributes.position }}"
),
"value_template": "{{ states.cover.test_state.state }}",
}
},
}
},
"cover.test_state",
None,
STATE_UNKNOWN,
{},
),
],
)
async def test_template_state_text_ignored_if_none_or_empty(
hass: HomeAssistant,
entity: str,
set_state: str,
test_state: str,
attr: dict[str, Any],
start_ha,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test ignoring an empty state text of a template."""
state = hass.states.get("cover.test_template_cover")
assert state.state == STATE_UNKNOWN
hass.states.async_set(entity, set_state, attributes=attr)
await hass.async_block_till_done()
state = hass.states.get("cover.test_template_cover")
assert state.state == test_state
assert "ERROR" not in caplog.text
@pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)]) @pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)])
@pytest.mark.parametrize( @pytest.mark.parametrize(
"config", "config",
@ -191,7 +259,9 @@ async def test_template_state_boolean(hass: HomeAssistant, start_ha) -> None:
}, },
], ],
) )
async def test_template_position(hass: HomeAssistant, start_ha) -> None: async def test_template_position(
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture
) -> None:
"""Test the position_template attribute.""" """Test the position_template attribute."""
hass.states.async_set("cover.test", STATE_OPEN) hass.states.async_set("cover.test", STATE_OPEN)
attrs = {} attrs = {}
@ -199,6 +269,7 @@ async def test_template_position(hass: HomeAssistant, start_ha) -> None:
for set_state, pos, test_state in [ for set_state, pos, test_state in [
(STATE_CLOSED, 42, STATE_OPEN), (STATE_CLOSED, 42, STATE_OPEN),
(STATE_OPEN, 0.0, STATE_CLOSED), (STATE_OPEN, 0.0, STATE_CLOSED),
(STATE_CLOSED, None, STATE_UNKNOWN),
]: ]:
attrs["position"] = pos attrs["position"] = pos
hass.states.async_set("cover.test", set_state, attributes=attrs) hass.states.async_set("cover.test", set_state, attributes=attrs)
@ -206,6 +277,7 @@ async def test_template_position(hass: HomeAssistant, start_ha) -> None:
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_position") == pos assert state.attributes.get("current_position") == pos
assert state.state == test_state assert state.state == test_state
assert "ValueError" not in caplog.text
@pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)]) @pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)])
@ -233,26 +305,46 @@ async def test_template_not_optimistic(hass: HomeAssistant, start_ha) -> None:
@pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)]) @pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)])
@pytest.mark.parametrize( @pytest.mark.parametrize(
"config", ("config", "tilt_position"),
[ [
{ (
DOMAIN: { {
"platform": "template", DOMAIN: {
"covers": { "platform": "template",
"test_template_cover": { "covers": {
**OPEN_CLOSE_COVER_CONFIG, "test_template_cover": {
"value_template": "{{ 1 == 1 }}", **OPEN_CLOSE_COVER_CONFIG,
"tilt_template": "{{ 42 }}", "value_template": "{{ 1 == 1 }}",
} "tilt_template": "{{ 42 }}",
}, }
} },
}, }
},
42.0,
),
(
{
DOMAIN: {
"platform": "template",
"covers": {
"test_template_cover": {
**OPEN_CLOSE_COVER_CONFIG,
"value_template": "{{ 1 == 1 }}",
"tilt_template": "{{ None }}",
}
},
}
},
None,
),
], ],
) )
async def test_template_tilt(hass: HomeAssistant, start_ha) -> None: async def test_template_tilt(
hass: HomeAssistant, tilt_position: float | None, start_ha
) -> None:
"""Test the tilt_template attribute.""" """Test the tilt_template attribute."""
state = hass.states.get("cover.test_template_cover") state = hass.states.get("cover.test_template_cover")
assert state.attributes.get("current_tilt_position") == 42.0 assert state.attributes.get("current_tilt_position") == tilt_position
@pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)]) @pytest.mark.parametrize(("count", "domain"), [(1, DOMAIN)])