For-statement for automation with numeric state

Are you sure that the second one doesn’t work or does it just not work as you imagined?

If you have it in a condition it will act like this:
Automation triggered -> check if temperature was below 25 for the last 5 seconds

However, I assume you want the following behaviour:
Automation triggered -> check if temperature stays below 25 for the next 5 second

To achieve the second you need a wait_for_trigger. I just had a discussion on this in a different topic, see here and here and here.

1 Like

It doesn’t work, it gives an error message because for the syntax.

Thanks for the tips on the wait for trigger (which is a very useful new function, I have already used it for several automations), but I still want to be able to use the “for:” in conditions, not just automations.

Ah, could be that it’s only available for state conditions, not for numeric state conditions.

And how do you want it to behave? if you want the same behaviour as the wait_for_trigger, this is not going to happen, because then it would be inconsistent. If you want the same behaviour as the state condition currently has then it’ a valid Feature Request in my opinion.

I want it to behave the same as in state conditions, I think that would be the most consistent behavior.

Edit: This post was written for a response to someone wanting a ‘numeric state for’ as a ‘condition’ following a different trigger. Tink tidied up some threads and this response appears strange here now

This is a huge problem.
When used as a trigger it sees that the required threshold is 25 and when it goes below (as stated in the trigger) then it counts the required time and the trigger ‘for’ is met.
A condition is a completely different beast.
No trigger action has occurred so nothing can be evaluated.
The trigger action occurs and now its time to check the condition, what condition ?
Well below 25 (in this case)
For how long ?
Well for 5 seconds (but it Cound be for 5 hours or 5 days)

So you are asking HA to maintain a FULL history of all sensor readings (every changed value and the time of that change) for almost an indefinite period). So that when a trigger occurs HA can look at the condition, then go back in time (with the Value) and see if the condition is met.
This will just not work.

What would work is if you reversed the trigger and conditions

Alternatively you need to track ALL your required ‘for’ tests, then evaluate them in the proper sequence.
I suspect you’d need to be very familiar with templating to do this as well

See, but then what’s the difference between just making a binary_sensor that is on/off at that threshold and then checking the for how long on that? It’s the same principle but with so many extra steps.

Because for is allowed as a condition if it’s a state condition. I don’t understand the difference between a numeric_state and a state here. They both have true/false values and have a history to them. And isn’t HA already maintaining a full history of all sensor readings?

Exactly,
Creating binary sensors is a cleaner way of doing it (but needs a good understanding of sensor set up, akin to templating perhaps)
I was just explaining in the context the question was asked.
I don’t have that level of history (I have none) any history I keep is stored in specific sensors

Home assistant always knows how long an entity has been in its current state regardless of your recorder: settings (and that’s what it uses in a state condition–the current state of the entity you define). However, depending on your recorder: settings, home assistant might not have enough history to know that an entity has been below or above a certain number for the period of time that you specify. It would have to look back at the previous values instead of just looking at the current state like in a state condition. Muttley touched on this but just said it in a different way I think.

Two things that seems similar to me :

The first one works :

  action:
    - delay: "00:{{ states('input_number.interval') | int }}:00"

The second one doesn’t work :

    - condition: state
      entity_id: binary_sensor.XXXXX
      state: "off"
      for: "00:{{ states('input_number.interval') | int }}:00"

This could be useful to enable a little more interactivity in fine tuning of automation without having to return changing yaml config file.

Have you tried this?

    - condition: state
      entity_id: binary_sensor.XXXXX
      state: "off"
      for:
        minutes: "{{ states('input_number.interval') | int }}"

Yes, I tried, it returns :

Invalid config for [automation]: expected float for dictionary value @ data['condition'][3]['for']['minutes']. Got None. (See /config/configuration.yaml, line 8). 

tried also:

for:
  minutes: "{{ states('input_number.interval') | float }}

returns the same error

I thought it was a bug, but frenck said it was the expected behaviour, so I trust him :smiley:

maybe try this:

      - >
          {{is_state('binary_sensor.XXXXX','off') and
            (now() - states.binary_sensor.XXXXX.last_changed).total_seconds() >
             states('input_number.interval')|int}}

unless you’re specifically interested in the syntax request, this would come close to what you are looking for?

got to remember though this is a condition checked on the moment of the trigger. It won’t wait for the time being set in the input_number if it hadn’t yet reached that. It would simply be false.

if you want to check that, you got to reference the last_changed.

It appears that you can template for when used in a State Trigger but not when used in a State Condition.

This passes Check Configuration:

- alias: junk1
  trigger:
    platform: state
    entity_id: input_boolean.switch1
    for:
      minutes: "{{ states('input_number.interval') | int }}"
  condition:
    - condition: state
      entity_id: binary_sensor.whatever
      state: "off"
  action:
    service: persistent_notification.create
    data:
      title: foo
      message: bar

This does not:

- alias: junk1
  trigger:
    platform: state
    entity_id: input_boolean.switch1
  condition:
    - condition: state
      entity_id: binary_sensor.whatever
      state: "off"
      for:
        minutes: "{{ states('input_number.interval') | int }}"
  action:
    service: persistent_notification.create
    data:
      title: foo
      message: bar

Yes I tried this and it worked,
but there is a problem doing the “elapsed time check” in the trigger,
because if I remember, if HA restarts in-between (after the on-off state change),
it doesn’t work anymore, or the time is not respected (I don’t remember the exact effect)

Hum, OK, I’m gonna test this, thank you… I don’t see exactly where to embed it…

I’m not specifically interested in the syntax request if you found a way to do it (but I think it would be cool if it worked with this simple syntax)

At startup, the entity’s last_changed is set to the startup time so that screws up ‘elapsed time’ calculations. There’s been a long-standing request to preserve the entity’s last_changed time (like its state) but, for whatever reason, it’s never been implemented. I believe the most recent request was made during the Month of What the Heck.

I think you’re right, must be that…
so I use a periodic trigger instead :

trigger:
    - platform: time_pattern
      minutes: "/1"

Edit : ow wait… well I think it won’t work neither, in fact !

Given that you can’t template for in a State Condition and elapsed-time calculation based on last_changed can be unreliable, can you explain how you are using the Time Pattern Trigger as a way of getting around those two limitations? I’m not seeing how a Time Pattern Trigger can do that …


EDIT

Here you go:

225 votes in favor of the proposal to allow last_changed to survive a restart.

Yes, my analysis of the cause of the problem was wrong !

And maybe I didn’t test if it works with this change… my bad

(now 226 votes)

OK, so since there is no way to overcome the last_changed problem anyway (for the moment) :

trigger:
    - platform: state
      entity_id: binary_sensor.XXXXX
      to: "off"
      for: "00:{{ states('input_number.interval') | int }}:00"

So, no need for the “for” template in condition (even if it would be nice)

Thank you guys for your eyes-opening help :slight_smile:

EDIT: ah, there is a problem when this is a trigger and not a condition :
the automation must be ON when the state is changing, if not, it won’t go and check the ‘last_changed’.
(so the time trigger is an improvement in my case, even if the HA reboot problem remains )