Open mekaneck opened 2 months ago
Hey there @phracturedblue, @tetienne, @home-assistant/core, mind taking a look at this issue as it has been labeled with an integration (template
) you are listed as a code owner for? Thanks!
(message by CodeOwnersMention)
template documentation template source (message by IssueLinks)
I noticed that even the comments in the code suggest this bug is present.
For a state-based binary template sensor, the comment is
Cancelled if template result changes
For a trigger-based binary template sensor, the comment is
Cancelled if new trigger received
The trigger-based binary sensor delay should only cancel if the template result changes, just like the state-based version does.
In general, the state trigger fires when the state of any of given entities changes. The behavior is as follows:
See: https://www.home-assistant.io/docs/automation/trigger#state-trigger
You probably want to use a numerical state trigger: https://www.home-assistant.io/docs/automation/trigger#numeric-state-trigger
I used the state trigger in this example because a trigger-based template sensor configured with a state trigger should behave exactly the same as a state-based template sensor, so the comparison is easy and direct. The delay should not be restarted when a new trigger is fired as long as the template continues to render the same value. This is (or at least is supposed to be) true for both trigger-based and state-based sensors.
I agree that, for the provided example, the bug could be worked around by specifying two numeric triggers (one above
and one below
). It does make it more complicated but it can be done. However, I'm not trying to solve the problem in the example; I'm trying to illustrate the bug.
All that notwithstanding, I'm happy to demonstrate the same bug exists with a numeric state trigger, though I have to create a new example:
Let's say we want a binary sensor that is true
when either input_number.test_a > 0
or input_number.test_b > 0
, and we want a turn on "debounce" of 20 seconds. So we can use the following code to create the two different versions of this sensor, the trigger-based one and the state-based one:
- trigger:
- platform: numeric_state
entity_id: input_number.test_a
above: 0
- platform: numeric_state
entity_id: input_number.test_b
above: 0
- platform: numeric_state
entity_id: input_number.test_a
below: 0.1
- platform: numeric_state
entity_id: input_number.test_b
below: 0.1
binary_sensor:
- name: "Test Delay: Numeric Trigger"
state: "{{ (states('input_number.test_a') | float > 0) or (states('input_number.test_b') | float > 0) }}"
delay_on: "0:00:20"
- binary_sensor:
- name: "Test Delay: State"
state: "{{ (states('input_number.test_a') | float > 0) or (states('input_number.test_b') | float > 0) }}"
delay_on: "0:00:20"
This is the result:
The delay should not be restarted when a new trigger is fired as long as the template continues to render the same value.
I'm actually not so sure about this statement. The documentation states:
Whenever the trigger fires, all related entities will re-render
I'm not sure if the delay_off
is considered a related entity, the documentation is not clear on that, but if it is this would explain the behaviour you're experiencing.
I think you're stretching a bit too far on this. It shouldn't matter whether the delays are considered related entities and are rendered again or not, their definition is pretty clear:
delay_off The amount of time the template state must be not met before this sensor will switch to off.
The time at which the template starts being not met starts with the first trigger that causes the template to render false
.
I'll pause here because I think we should be able to agree up to this point?
Subsequent re-renders of the template that continue to render false
don't change that starting time, per the documentation.
So whether or not the delay is re-calculated, it should be calculated from the same starting time. Hence my statement that it is irrelevant whether it is a related entity that is rendered again.
It should also be quite clear that no difference in behavior regarding the delay should be expected or desired between the trigger-based or state-based template sensors.
The problem
The
delay_on
anddelay_off
options for a trigger-based template binary sensor will restart the delay countdown after each trigger. If the trigger continues to fire after the template renders a new value, the state of the senor does not change until there has been a pause in the triggers long enough to finish the delay.The image below shows two sensors; a state-based template sensor and a trigger-based template sensor, both configured with
delay_on: '0:00:20'
. The state of both are set to change toon
(after the delay) when theTest
entity (graph shown) is greater than zero. The YAML code for the sensors is included in the YAML section further down in this issue.The state-based sensor turns ON 20 seconds after the value crosses zero. This is the desired behavior. The trigger-based sensor turns ON 20 seconds after the value stops changing, after crossing zero.
What version of Home Assistant Core has the issue?
core-2023.8.3
What was the last working version of Home Assistant Core?
No response
What type of installation are you running?
Home Assistant Container
Integration causing the issue
Template
Link to integration documentation on our website
https://www.home-assistant.io/integrations/template/
Diagnostics information
No response
Example YAML snippet
Anything in the logs that might be useful for us?
No response
Additional information
No response