mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 14:27:07 +00:00
Allow binary sensor template to return state unknown (#128861)
* Allow binary sensor template to return state unknown * Add tests * Adjust TriggerBinarySensorEntity * Add restore tests for BinarySensorTemplate * Add tests for TriggerBinarySensorEntity * Tweak * Tweak * Adjust tests * Adjust
This commit is contained in:
parent
97c1e21a69
commit
c17ee0d123
@ -303,11 +303,9 @@ class BinarySensorTemplate(TemplateEntity, BinarySensorEntity, RestoreEntity):
|
||||
self._delay_cancel()
|
||||
self._delay_cancel = None
|
||||
|
||||
state = (
|
||||
None
|
||||
if isinstance(result, TemplateError)
|
||||
else template.result_as_boolean(result)
|
||||
)
|
||||
state: bool | None = None
|
||||
if result is not None and not isinstance(result, TemplateError):
|
||||
state = template.result_as_boolean(result)
|
||||
|
||||
if state == self._attr_is_on:
|
||||
return
|
||||
@ -347,7 +345,7 @@ class TriggerBinarySensorEntity(TriggerEntity, BinarySensorEntity, RestoreEntity
|
||||
"""Initialize the entity."""
|
||||
super().__init__(hass, coordinator, config)
|
||||
|
||||
for key in (CONF_DELAY_ON, CONF_DELAY_OFF, CONF_AUTO_OFF):
|
||||
for key in (CONF_STATE, CONF_DELAY_ON, CONF_DELAY_OFF, CONF_AUTO_OFF):
|
||||
if isinstance(config.get(key), template.Template):
|
||||
self._to_render_simple.append(key)
|
||||
self._parse_result.add(key)
|
||||
@ -391,7 +389,9 @@ class TriggerBinarySensorEntity(TriggerEntity, BinarySensorEntity, RestoreEntity
|
||||
self._process_data()
|
||||
|
||||
raw = self._rendered.get(CONF_STATE)
|
||||
state = template.result_as_boolean(raw)
|
||||
state: bool | None = None
|
||||
if raw is not None:
|
||||
state = template.result_as_boolean(raw)
|
||||
|
||||
key = CONF_DELAY_ON if state else CONF_DELAY_OFF
|
||||
delay = self._rendered.get(key) or self._config.get(key)
|
||||
@ -417,8 +417,8 @@ class TriggerBinarySensorEntity(TriggerEntity, BinarySensorEntity, RestoreEntity
|
||||
self.async_write_ha_state()
|
||||
return
|
||||
|
||||
# state without delay. None means rendering failed.
|
||||
if self._attr_is_on == state or state is None or delay is None:
|
||||
# state without delay.
|
||||
if self._attr_is_on == state or delay is None:
|
||||
self._set_state(state)
|
||||
return
|
||||
|
||||
|
@ -253,7 +253,7 @@ async def test_setup_invalid_sensors(hass: HomeAssistant, count: int) -> None:
|
||||
@pytest.mark.parametrize(
|
||||
("state_template", "expected_result"),
|
||||
[
|
||||
("{{ None }}", STATE_OFF),
|
||||
("{{ None }}", STATE_UNKNOWN),
|
||||
("{{ True }}", STATE_ON),
|
||||
("{{ False }}", STATE_OFF),
|
||||
("{{ 1 }}", STATE_ON),
|
||||
@ -263,7 +263,7 @@ async def test_setup_invalid_sensors(hass: HomeAssistant, count: int) -> None:
|
||||
"{% else %}"
|
||||
"{{ states('binary_sensor.three') == 'off' }}"
|
||||
"{% endif %}",
|
||||
STATE_OFF,
|
||||
STATE_UNKNOWN,
|
||||
),
|
||||
("{{ 1 / 0 == 10 }}", STATE_UNAVAILABLE),
|
||||
],
|
||||
@ -1090,18 +1090,18 @@ async def test_availability_icon_picture(hass: HomeAssistant, entity_id: str) ->
|
||||
({"delay_on": 5}, STATE_ON, STATE_OFF, STATE_OFF),
|
||||
({"delay_on": 5}, STATE_ON, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
({"delay_on": 5}, STATE_ON, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||
({}, None, STATE_ON, STATE_OFF),
|
||||
({}, None, STATE_OFF, STATE_OFF),
|
||||
({}, None, STATE_UNAVAILABLE, STATE_OFF),
|
||||
({}, None, STATE_UNKNOWN, STATE_OFF),
|
||||
({"delay_off": 5}, None, STATE_ON, STATE_ON),
|
||||
({"delay_off": 5}, None, STATE_OFF, STATE_OFF),
|
||||
({}, None, STATE_ON, STATE_UNKNOWN),
|
||||
({}, None, STATE_OFF, STATE_UNKNOWN),
|
||||
({}, None, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
({}, None, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||
({"delay_off": 5}, None, STATE_ON, STATE_UNKNOWN),
|
||||
({"delay_off": 5}, None, STATE_OFF, STATE_UNKNOWN),
|
||||
({"delay_off": 5}, None, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
({"delay_off": 5}, None, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||
({"delay_on": 5}, None, STATE_ON, STATE_OFF),
|
||||
({"delay_on": 5}, None, STATE_OFF, STATE_OFF),
|
||||
({"delay_on": 5}, None, STATE_UNAVAILABLE, STATE_OFF),
|
||||
({"delay_on": 5}, None, STATE_UNKNOWN, STATE_OFF),
|
||||
({"delay_on": 5}, None, STATE_ON, STATE_UNKNOWN),
|
||||
({"delay_on": 5}, None, STATE_OFF, STATE_UNKNOWN),
|
||||
({"delay_on": 5}, None, STATE_UNAVAILABLE, STATE_UNKNOWN),
|
||||
({"delay_on": 5}, None, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||
],
|
||||
)
|
||||
async def test_restore_state(
|
||||
@ -1209,7 +1209,7 @@ async def test_restore_state(
|
||||
[
|
||||
(2, STATE_ON, "mdi:pirate", "/local/dogs.png", 3, 1, "si"),
|
||||
(1, STATE_OFF, "mdi:pirate", "/local/dogs.png", 2, 1, "si"),
|
||||
(0, STATE_OFF, "mdi:pirate", "/local/dogs.png", 1, 1, "si"),
|
||||
(0, STATE_UNKNOWN, "mdi:pirate", "/local/dogs.png", 1, 1, "si"),
|
||||
(-1, STATE_UNAVAILABLE, None, None, None, None, None),
|
||||
],
|
||||
)
|
||||
@ -1273,6 +1273,22 @@ async def test_trigger_entity(
|
||||
assert state.state == final_state
|
||||
assert state.attributes.get("another") == another_attr_update
|
||||
|
||||
# Check None values
|
||||
hass.bus.async_fire("test_event", {"beer": 0})
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.hello_name")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
state = hass.states.get("binary_sensor.via_list")
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
# Check impossible values
|
||||
hass.bus.async_fire("test_event", {"beer": -1})
|
||||
await hass.async_block_till_done()
|
||||
state = hass.states.get("binary_sensor.hello_name")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
state = hass.states.get("binary_sensor.via_list")
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
|
||||
@pytest.mark.parametrize(
|
||||
@ -1298,7 +1314,7 @@ async def test_trigger_entity(
|
||||
[
|
||||
(2, STATE_UNKNOWN, STATE_ON, STATE_OFF),
|
||||
(1, STATE_OFF, STATE_OFF, STATE_OFF),
|
||||
(0, STATE_OFF, STATE_OFF, STATE_OFF),
|
||||
(0, STATE_UNKNOWN, STATE_UNKNOWN, STATE_UNKNOWN),
|
||||
(-1, STATE_UNAVAILABLE, STATE_UNAVAILABLE, STATE_UNAVAILABLE),
|
||||
],
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user