Untangle conditions

HI.
while I had my alarm clock automation trigger on time (pattern) before, this worked nicely (have it commented out so you can see the previous setup). Was pointed by @Pippyn here to the processor abuse of that method… so changed to this template trigger checking for the time:

automation:
  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
#      platform: time
#      minutes: '/1'
#      seconds: 00
    condition:
      condition: or
      conditions:
        - condition: and
          conditions:
#          - condition: template
#            value_template: >
#              {{ now().time().strftime("%H:%M") == 
#                states('sensor.alarmclock_wd_time_template')}}
          - condition: template
            value_template: >
              {{ is_state('input_boolean.alarmclock_wd_enabled','on')}}
          - condition: template
            value_template: >
              {{ is_state('binary_sensor.workday_sensor','on')}}
        - condition: and
          conditions:
#          - condition: template
#            value_template: >
#              {{ now().time().strftime("%H:%M") == 
#                 states('sensor.alarmclock_we_time_template')}}
          - condition: template
            value_template: >
              {{ is_state('input_boolean.alarmclock_we_enabled','on')}}
          - condition: template
            value_template: >
              {{ is_state('binary_sensor.workday_sensor','off')}}
    action:
      service: script.alarmclock_ring

but it now triggers on both times for weekdays and weekend days. Probably my conditions aren’t nested correctly (always a mess with these mixed and/or’s), but I don’t spot the error.
Please have a look with me?
I know I could probably spilt this up into 2 separate automations, but it should be possible shouldn’t it?

either weekday And wd_enabled,
or weekendday And we_enabled.

Which is what I thought a had…

wrote it shorter:

automation:
  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
    condition:
      condition: or
      conditions:
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_wd_enabled','on') and
               is_state('binary_sensor.workday_sensor','on')}}
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_we_enabled','on') and
             is_state('binary_sensor.workday_sensor','off')}}
    action:
      service: script.alarmclock_ring

The automation looks correct. It should trigger on weekdays if input_boolean.alarmclock_wd_enabled is enabled. and trigger in the weekend when input_boolean.alarmclock_we_enabled is enabled. But this is not the case?

the first automation triggers on both set times for weekdays and weekend days. Somehow the consecutive Ands aren’t And-ed…
While in the original setup that always worked flawlessly.

second automation with the compressed conditions does the same I fear. Which is to be expected really: it only checkes the conditions and if either set evaluates to true, it fires the action. I think both conditions should be in the trigger template…

  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') and
              is_state('input_boolean.alarmclock_we_enabled','on') and
              is_state('binary_sensor.workday_sensor','off')}}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') and 
              is_state('input_boolean.alarmclock_wd_enabled','on') and
              is_state('binary_sensor.workday_sensor','on')}}
    condition: []
    action:
      service: script.alarmclock_ring

which brings us back to the original automation really, with the automation triggering each minutes checking all conditions, and not only the time ;-(

Triggers are OR not and. Either will trigger it…

sure, that’s what I wanted. And have the conditions check for validity.
But since I or’ed these too, the automation fires the action for both times on each day, workday or not.

Maybe I have to try this:

  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
    condition:
      condition: or
      conditions:
        -  condition: template
           value_template: >
             {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') and
                is_state('input_boolean.alarmclock_we_enabled','on') and
                is_state('binary_sensor.workday_sensor','off')}}
        -  condition: template
           value_template: >
             {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') and 
                is_state('input_boolean.alarmclock_wd_enabled','on') and
                is_state('binary_sensor.workday_sensor','on')}}
    action:
      service: script.alarmclock_ring

this will check if the times are met and triggers. If so, it checks for the full set of conditions, including the correct time setting.?

No that should not be necessary. You have the binary_sensor.workday_sensor to check if it;s a weekday or not. Does this sensor work properly?
TBH I still don’t get what the automation is doing wrong… your alarm went off on a workday even tough input_boolean.alarmclock_we_enabled was off?

exactly. The goal is to have it fire on weekday time, on weekdays, and on weekend time on weekend days. Not on weekend time on weekdays… which is what is does now. Because it triggers correctly on the weekend time, and one of the conditions is evaluated to true, namely the weekdays set.

by combining that again in the condition sets (adding the correct time) should be prevented.

which should be the same as this split setup:

  - alias: Alarm Clock WE
    id: 'Alarm Clock WE'
    initial_state: 'on'
    trigger:
       platform: template
       value_template: >
         {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
    condition:
       condition: template
       value_template: >
         {{ is_state('input_boolean.alarmclock_we_enabled','on') and
            is_state('binary_sensor.workday_sensor','off')}}
    action:
      service: script.alarmclock_ring

  - alias: Alarm Clock Wd
    id: 'Alarm Clock Wd'
    initial_state: 'on'
    trigger:
       platform: template
       value_template: >
         {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
    condition:
       condition: template
       value_template: >
         {{ is_state('input_boolean.alarmclock_wd_enabled','on') and
            is_state('binary_sensor.workday_sensor','on')}}
    action:
      service: script.alarmclock_ring

which is also a valid solution, albeit in 2 automations…Not sure if this would be even better for the processor

ohhh i see the problem. This should work;

automation:
  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') and states('binary_sensor.workday_sensor') == 'on' }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') and states('binary_sensor.workday_sensor') == 'off' }}
    condition:
      condition: or
      conditions:
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_wd_enabled','on') }}
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_we_enabled','on') }}
    action:
      service: script.alarmclock_ring

But I would go for the 2 separate automations because it’s more clear what they do.

yes, that would do it also.
Still , it has the disadvantage of added conditions checked in the trigger, thus causing more processor stress each minute this is evaluated. The reason we started to change the original automation in the first place :wink:

You could also refer to the trigger in the condition and check if the correct trigger is activated for each condition.

I’m not sure if this is correct, but somthing link this;

automation:
  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
    condition:
      condition: or
      conditions:
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_wd_enabled','on') and
               is_state('binary_sensor.workday_sensor','on') and
               trigger.entity_id == 'sensor.alarmclock_wd_time_template' }}
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_we_enabled','on') and
             is_state('binary_sensor.workday_sensor','off')and
               trigger.entity_id == 'sensor.alarmclock_we_time_template' }}
    action:
      service: script.alarmclock_ring

or even more simple is to repeat the trigger in the automation;

automation:
  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
      -  platform: template
         value_template: >
           {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
    condition:
      condition: or
      conditions:
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_wd_enabled','on') and
               is_state('binary_sensor.workday_sensor','on') and
               states('sensor.time') == states('sensor.alarmclock_wd_time_template') }}
        - condition: template
          value_template: >
            {{ is_state('input_boolean.alarmclock_we_enabled','on') and
               is_state('binary_sensor.workday_sensor','off') and
               states('sensor.time') == states('sensor.alarmclock_we_time_template') }}
    action:
      service: script.alarmclock_ring

yes, that was my now solution above. It does work, but seems redundant.

Somehow all of these ‘better’ automations compared to my original suffer a rather big lag of up to 35 seconds for now. Cant point it down just yet, but it is unexpected.

About the trigger: wouldn’t the trigger entity_id be the sensor.time? In which case this would be of no consequence.

35 seconds? What system are you running HA on?

yes could be, I’m not sure.

yes, about that, I can check since I have a notification sent, and log all notifications.
Rpi3b+

That could also just be lag in your notifications. Not necessarily the cause of the automations.

yes, you’re right I guess, no other way of checking that. Still, I have the log of the notification service, not the notification reception on my device.
Might very well be I never noticed during waking up ;-}}

Why even have the conditions, let the triggers do the work…

  - alias: Alarm Clock
    id: 'Alarm Clock'
    initial_state: 'on'
    trigger:
      -  platform: template
         value_template: >
             {{ states('sensor.time') == states('sensor.alarmclock_we_time_template') and
                is_state('input_boolean.alarmclock_we_enabled','on') and
                is_state('binary_sensor.workday_sensor','off')}}
      -  platform: template
         value_template: >
             {{ states('sensor.time') == states('sensor.alarmclock_wd_time_template') and 
                is_state('input_boolean.alarmclock_wd_enabled','on') and
                is_state('binary_sensor.workday_sensor','on')}}
    action:
      service: script.alarmclock_ring
1 Like

Hi!

yes, that’s what I had as first rewrite of my original in post 3 but the reason I started to rewrite my automation was based on the thought that having all these conditions in the trigger causes a lot of processor power, since it has to evaluate all that each minute.

While it should only have to trigger on both times set. Having it use the sensor.time still triggers each minute of course, but only for the time and only then that passes, it will evaluate the conditions. Which is supposed to be lighter on the processor.

triggering every minute is what causes the slowdowns, not what it’s executing. It may create more listeners, but the intensive listener is the sensor.time one, so it doesn’t really matter. Also, order of operation matters. Your first test is time == time. If that returns false, jinja won’t even look at the other tests because the first and failed, so the whole statement will fail. So no slowdown whatsoever.

example:

{{  1 == 1 and 1 == 2 and 1 == 3 }}
    \    /     \    /     \    /
     \  /       \  /       \  / 
      \/         \/         \/ 
    passes      fails     not checked because 2nd condition fails.

It’s the opposite for or

{{  1 == 1 or 1 == 2 or 1 == 3 }}
    \    /    \    /    \    /
     \  /      \  /      \  / 
      \/        \/        \/ 
    passes   not checked  not checked because 1st condition passes.
``