Are multiple Triggers an "or" or an "and"?

Triggers defines when your conditions will be checked.

Triggers are always OR
Conditions are AND unless you explicitly add an OR condition.

In your case, door opening OR windows opening are your triggers, you away is the condition to run the automation.
The automation will never run while you are at home, and won’t check if you are away until a door or window is opened.

For this case you can have a state trigger checking all of your windows (OR) changing states to “opened”, then in your conditions you should check if all windows are open (AND).

1 Like

You’re right, of course. I should have spelled that out better above.

Thanks for clarifying it.

As mentioned by others, you cannot logically AND triggers.

One way to fulfill your “four windows open” requirement is by using a Template Trigger.

alias: example
description: Turn off climate system when all four windows are opened
trigger:
  - platform: template
    value_template: >
      {{ expand('binary_sensor.window1', 'binary_sensor.window2',
         'binary_sensor.window3', 'binary_sensor.window4')
         | selectattr('state', 'eq', 'on') | list | count == 4 }}
condition: []
action:
  - service: climate.turn_off
    target:
      entity_id: climate.main
1 Like

That’s why I suggested to use a template sensor, like group sensor you can use it as a trigger

Why?
Why can’t you use the condition section?

Hello All

If condition are always AND why is there and “AND” condiftion where you can add specific condition test ?

My need is to set a boolean to “away” when both me and my wife are not home.
So I was also looking for an AND trigger, but ended up with this.

Do I need to use the AND condiftion ? or just 2 conditions ?

Another question :
how does the time “for” works ?

let assume this scenario:

  • I leave the home at 7h (the automation should not go to the end)
  • then, my wife leave the home 1h hour after me, at 8h (both condition should match, after she’s been away for 10min or more) then the action should be activated.

What do you think ? would this work ?
thx a lot

alias: Leave home
description: ""
trigger:
  - platform: device
    device_id: 37bf5688103ed10747dadedc04220675
    domain: device_tracker
    entity_id: device_tracker.vog_l29
    type: leaves
    zone: zone.home
  - platform: device
    device_id: fb1895cf0550c3a8100600b12f9e7282
    domain: device_tracker
    entity_id: 5cacd7ca62429a6e102df673eaab23cd
    type: leaves
    zone: zone.home
condition:
  - condition: and
    conditions:
      - condition: state
        entity_id: device_tracker.vog_l29
        state: not_home
        for:
          hours: 0
          minutes: 10
          seconds: 0
      - condition: state
        entity_id: device_tracker.sm_a415fanny
        state: not_home
        for:
          hours: 0
          minutes: 10
          seconds: 0
action:
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id:
        - input_boolean.away_etage
mode: single```

If you are the only two on the system, that’s a template binary sensor:

template:
  - binary_sensor:
      - name: "Noone at home"
        state: "{{ states('zone.home') == '0' }}"
        device_class: presence

The and condition is provided for complicated AND / OR constructions, such as “(a AND b) OR (c AND d)”

For your automation, use state triggers instead of device triggers, and do it like this:

trigger:
  - platform: state
    entity_id: device_tracker.vog_l29
    from: 'home'
    for: "00:10:00"
  - platform: state
    entity_id: device_tracker.sm_a415fanny
    from: 'home'
    for: "00:10:00"
condition:
  - condition: state
    entity_id: device_tracker.vog_l29
    state: 'not_home'
  - condition: state
    entity_id: device_tracker.sm_a415fanny
    state: 'not_home'

Triggers ten minutes after each leaving, only proceeds to the action if both of you are not_home.

Thx a lot,

I’m leaving home in 15min, I’ll be testing that :slight_smile:

EDIT : It works like a charm ^^ thx a lot

Whilst you can’t have true ‘AND’ triggers, you can chain multiple triggers together, but the order of execution would determine whether or not the automation fires, such as:

description: ""
mode: single
trigger:
  - platform: state
    entity_id:
      - binary_sensor.lumi_lumi_motion_ac02_iaszone_2
    to: "on"
condition: []
action:
  - wait_for_trigger:
      - platform: state
        entity_id:
          - light.all_kitchen_light_group
        to: "on"

In this case, motion has to be detected, and then some lights turned on. You could put a timeout on the wait_for_trigger if the lights are not turned on within a specified period.

you can if you use a template trigger.

Just create the ‘and’ in the template.

If you mean a trigger template then i don’t think thats how they work.

if I reference 2 entities and combine them with an AND, then iirc, whenever either entities state changes, the trigger template will fire, and the state of both entities at that time will be evaluated. So its not the smae as two triggers firing at once.

I think I’ll say the same.

If you create a template that has an ‘and’ in the logic then it means that it needs both parts to be true before the template (and ultimately the trigger) turns true.

example:

{{ is_state('binary_sensor.sensor_1', 'on') and is_state('binary_sensor.sensor_2', 'on') }}

Since the logic is ‘and’ this will only return true when both sensors are ‘on’.

the template doesn’t need to look for a state change on both entities at the same instant. it just needs to evaluate both entities at a particular moment (which technically is when either entity’s state changes) and if they are both ‘on’ then the logic is satisfied and the template evaluates to true. That in turn sets the trigger to true and the trigger fires.

2 Likes

Having to resort to template triggers or repeating yourself in conditions to do logical ‘and’ is a UI stink, classic case of “you’re holding it wrong”. This should be high on Home Assistant priority list to resolve so conditions, triggers, and actions have a more uniform and intuitive interface.

That said, template triggers (as @finity examples) seem to be the best workaround until HA team gets around to brushing up the UI.

2 Likes

All very interesting.

Does anybody have an actual use case for the optional and?

At 3 pm turn the light off, and five minutes later do it again in case someone turned it on again?
I’m hypothesising…

Plenty of use cases.

I came to this topic because I have stairs, then a landing, a right angle, then a corridor. So this needs at least 3 motion sensors (good thing they’re 3€ each)

  1. Obviously, the lights must turn on when any motion sensor detects someone.

  2. Then they must remain on as long as there’s someone around.

  3. After the occupants are gone, there’s the usual timer, then the lights turn off.

Battery powered motion sensors report “occupancy” once when they detect motion. Then they report “clear” when they no longer detect motion. Between the two, they don’t waste their batteries reporting the same state over and over again.

Thus step 2 requires a trigger on “all sensors report occupancy: clear”.

But that does not require that triggers be logically AND…

What you have described can be accomplished with a State trigger based on a Group, a Template trigger (see Post 17), or a State trigger and state condition that contain all three sensors (see Post 12).

1 Like

OK I tried the group approach. The group works fine, but the trigger does not work.

Note “DM escalier” means “Motion Detector Stairs”

I see “When DM Escalier changes from any state to Clear for 1:00”. This has no meaning. I assume it means “When DM Escalier changes from any state to Clear and remains at state Clear for 1:00”. If this is the intended meaning, then it does not work: when I exit the stairs, wait for the motion detector to clear, then quickly return to the stairs, it turns off the light instead of restarting the automation as it should, since the automation’s starting trigger should be… well, triggered.

This seems to work (initial trigger is the same as previous)

OK. I gave up and installed AppDaemon, it is so much simpler and quicker to implement functional “motion detection light with 1 button UI” behavior:

  • If someone is in the stairs, turn light on
  • If no-one is in the stairs for 2 min, turn light off
  • If light is on and button is pushed, turn light off
  • If light is off and button is pushed, turn light on for 1 hour, prolong if someone is in the stairs
import appdaemon.plugins.hass.hassapi as hassapi
import time

# Args:
# sensor: binary sensor to use as trigger
# light : entity to turn on when detecting motion
# delay: amount of time after turning on to turn off again. If not specified defaults to 60 seconds.
#

class MotionLightButtonActor:
    def __init__( self, api, name, sensor, light, delay, button_delay, **kwargs ):
        self.api    = api
        self.name   = name
        self.timer  = None
        self.light  = light
        self.delay  = delay
        self.button_delay   = button_delay
        self.expiry = 0
        self.light_state_set = None
        
        api.listen_state( self.on_sensor, sensor )
        api.listen_state( self.on_light, light )
        api.log( "initialize %s" % kwargs )

    def cancel(self):
        self.cancel_timer()
    
    def cancel_timer( self ):
        api = self.api
        if self.timer:
            api.cancel_timer( self.timer )
            self.timer = None
    
    def set_timer( self, delay ):
        api = self.api
        self.cancel_timer()
        t = time.monotonic()
        self.expiry = max( self.expiry, t+delay )
        delay = self.expiry-t
        api.log( "set_timer %s", delay )
        self.timer = api.run_in( self.light_off, delay )

    def light_off( self, kwargs ):
        api = self.api
        api.log( "light_off" )
        self.timer = None
        self.light_state_set = "off"      # used in on_light()
        api.turn_off( self.light )
    
    # sensor state change
    def on_sensor( self, entity, attribute, old, new, kwargs ):
        api = self.api
        api.log( "on_sensor(%s -> %s)" % (old, new) )
        if new == "on":
            self.cancel_timer()           # no countdown when sensor detects
            self.light_state_set = "on"   # used in on_light()
            api.log( "light_on" )
            api.turn_on( self.light )
        elif api.get_state( self.light ) == "on":
            self.set_timer( self.delay )  # begin countdown

    # relay state change
    def on_light( self, entity, attribute, old, new, kwargs ):
        api = self.api
        if new != self.light_state_set:
            # triggered by button wired directly to relay (relay is retarded and does not report button state, only its own state)
            self.light_state_set = None
            api.log( "on_light(%s -> %s)" % (old, new) )
            if new == "on":
                # light turned on by button
                self.set_timer( self.button_delay )
            else:
                # light turned off by button
                self.expiry = 0
                self.cancel_timer()

class MotionLightButton(hassapi.Hass):
    def initialize(self):
        self.__actor = MotionLightButtonActor( self, **self.args )

    def cancel(self):
        self.__actor.cancel()

Default mode for automations is single. If you try to retrigger it while it’s still in the 1 minute timeout for clear, nothing will happen because the automation is still running.

If you want your automation to retrigger, all you have to do is add mode: restart at the bottom of the automation and job done.
There’s an option to do this in the UI too, but I can’t remember where it is or what it’s called.

Mode was set to “restart”