Inconsistency between time trigger and condition?

I have several automations which I throttle to prevent them toggling too often.

I do this by having an input datetime *_pause_until, which does exactly what it sounds like. The automation is triggered on its usual events, but also on said datetime, and with a condition to skip the automation if we’re before pause_until.

As a result, the start of each automation looks like this:

trigger:
  - at: input_datetime.dehumidifier_pump_pause_until
    platform: time
[...]
condition:
  - condition: template
    value_template: >-
      {{now().timestamp() >=
      state_attr('input_datetime.dehumidifier_pump_pause_until', 'timestamp')}}

(Related WTH: why is there no condition: [date]time?)

…only, sometimes (not always; not never) the automation ends up with the following bizarre & inconsistent trace:

  1. Triggered by said time trigger.
  2. Condition fails (???)

…and then of course the automation misses updates and I’m sad.

This is inconsistent. Triggering due to the time trigger indicates that we’re at (or after) input_datetime.dehumidifier_pump_pause_until, but failing the condition means that we’re before input_datetime.dehumidifier_pump_pause_until.

For now I’m working around this by adding a clause to the condition to check if the input trigger was said pause ((trigger.platform == 'time') or ..., at least assuming no other time triggers), but this seems incorrect regardless.

(Two other things I checked for the sake of argument: pause_until wasn’t updated during the automation run, and the system time didn’t change.)

Am I missing something here?

I’m not sure I understand the logic here.
The trigger fires when the datetime helper is ‘now’, so the condition is always going to evaluate to true ?

There are other triggers to the automation too, where the condition won’t always hold.

In this case it’s the time trigger that triggers, which “should” always result in the condition being true as you mention… and yet sometimes the condition evaluates to false.

Have you checked the history of the datetime helpers value ?
I can’t remember if they persist after (say) a home assistant restart

(EDIT:- I believe they do now, so thats probably not it)

I’m not sure how that’d be relevant here unless HA was restarted in the middle of the automation (which I’ve checked: it wasn’t - and if it was the automation wouldn’t resume in the middle anyway).

Nevertheless: the input_datetime remained the same.

This is an inconstancy between either a) the input_datetime or b) now(), read in two subsequent steps of the same automation run.

It is strange that this seems to be intermittent.
Not sure if anything from this thread will help you:-

There are suggestions on how to evaluate dateimes that are slightly different from yours.

By how much off are they?
If it is not by much, then it could happen due to rounding, if the two values use different internal precision.

What type of Input Datetime are you using?

Post the full automation, please, or at least the full trigger and condition blocks.

Is there a way to tell? The trace merely shows that the condition failed, not every step in the calculation.

Sure:

alias: Dehumidifier Pump Control
trigger:
  - at: input_datetime.dehumidifier_pump_pause_until
    platform: time
  - entity_id: sensor.151732605496952_tank
    platform: state
  - entity_id: input_number.dehumidifier_pump_threshold
    platform: state
  - event: start
    platform: homeassistant
condition:
  - condition: template
    value_template: |-
      {{now().timestamp() >=
      state_attr('input_datetime.dehumidifier_pump_pause_until', 'timestamp')}}
action:
  - if:
      - above: input_number.dehumidifier_pump_threshold
        condition: numeric_state
        entity_id: sensor.151732605496952_tank
    then:
      if:
        condition: state
        entity_id: switch.dehumidifier_pump_switch
        state: "off"
      then:
        - service: switch.turn_on
          target:
            entity_id: switch.dehumidifier_pump_switch
        - data:
            timestamp: "{{ now().timestamp() + 1*60 }}"
          service: input_datetime.set_datetime
          target:
            entity_id: input_datetime.dehumidifier_pump_pause_until
    else:
      if:
        condition: state
        entity_id: switch.dehumidifier_pump_switch
        state: "on"
      then:
        - service: switch.turn_off
          target:
            entity_id: switch.dehumidifier_pump_switch
        - data:
            timestamp: "{{ now().timestamp() + 10*60 }}"
          service: input_datetime.set_datetime
          target:
            entity_id: input_datetime.dehumidifier_pump_pause_until

(I have reformatted this slightly. For some reason the YAML copy/paste had the if/then/else out of order. I know it doesn’t technically make a difference, but it certainly makes it more difficult to read…)
Note that this is not the only automation that adjusts input_datetime.dehumidifier_pump_pause_until.

Add variables before the condition and store the two sides in separate variables. This should show in traces.

I changed the automation to:

condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {{now().timestamp() >=
          state_attr('input_datetime.dehumidifier_pump_pause_until',
          'timestamp')}}
      - condition: template
        value_template: "{{trigger.platform == 'time'}}"

…which works around the behavior while making it visible in the trace if this behavior occurs.

By manually doing a service call to update pause_until I’m able to trigger this behavior:

service: input_datetime.set_datetime
data:
  timestamp: "{{ now().timestamp() + 1 }}"
target:
  entity_id: input_datetime.dehumidifier_pump_pause_until

Will do…

I changed it to the following:

condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {% set now_timestamp = now().timestamp() %}
          {% set pause_timestamp =
          state_attr('input_datetime.dehumidifier_pump_pause_time', 'timestamp')
          %}
          {{ now_timestamp >=  pause_timestamp }}
      - condition: template
        value_template: "{{trigger.platform == 'time'}}"

…but the trace does not have any information about the variables.

Am I misunderstanding something?

If you mean adding a variables action - I can’t do so because this is the condition block of the automation, which is run before any actions.

I can try turning the condition block into an initial if/else return in the automation actions I suppose, though that’s a more major change to the automation.

Suggestions?

No, not the action, just add variables before condition section. You have to do it through YAML, there’s no UI for it.

1 Like

I think what Artur meant was something like:

condition:
  - variables:
      now_timestamp: "{{ now().timestamp() }}"
      pause_timestamp: "{{state_attr('input_datetime.dehumidifier_pump_pause_time', 'timestamp') }}"
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {{ now_timestamp >=  pause_timestamp }}
      - condition: template
        value_template: "{{trigger.platform == 'time'}}"
1 Like

Oh interesting!

I didn’t know you could define variables in the condition block. This appears to be undocumented. Is it something I can rely on, or should I just use it for debugging?

I’ll try that and get back to you.

I’m not sure this is correct. I meant like that:

variables:
  now_timestamp: "{{ now().timestamp() }}"
  pause_timestamp: "{{state_attr('input_datetime.dehumidifier_pump_pause_time', 'timestamp') }}"
condition:
  - condition: or
    conditions:
      - condition: template
        value_template: >-
          {{ now_timestamp >=  pause_timestamp }}
      - condition: template
        value_template: "{{trigger.platform == 'time'}}"

It is documented, but in unexpected place.

Please make sure to read a thread you’re commenting before saying something unneeded. Thank you.