How to use multiple triggers and "triggered by" in a if / elif / else automation

New to YAML so bear with me, all help appreciated.
I have multiple cameras that I want to use as triggers in an automation. Depending on witch camera that triggered the automation, sun, and light status different actions should happen.
I have started with what I thought would be simple automation to learn how to do this in YAML but after a number of different versions and as many failures I have to humbly ask her for guidance.
YAML

  alias: Larm Bromma
  description: ''
  trigger:
  - type: motion
    platform: device
    device_id: 7c5b567f14da4049ba6d261db27ff050
    entity_id: binary_sensor.motion_bromma_entre
    id: cam_en
    domain: binary_sensor
  - type: motion
    platform: device
    device_id: e80f398638484344b6b9d3f588443946
    entity_id: binary_sensor.motion_bromma_kallartrappa
    id: cam_ka
    domain: binary_sensor
  condition:
  - condition: sun
    before: sunrise
    after: sunset
  action:
  - if:
    condition:
    - condition: trigger
      id: cam_en
    - condition: device
      type: is_off
      device_id: d45406a6785a914bb6fd80253cc92e89
      entity_id: switch.koksfonster
      domain: switch
    then:
    - type: turn_on
      device_id: d45406a6785a914bb6fd80253cc92e89
      entity_id: switch.koksfonster
      domain: switch
  - if:
    condition:
    - condition: trigger
      id: cam_ka
    - condition: device
      type: is_off
      device_id: 1c4a115fa85b98304d806e241b814a2f
      entity_id: switch.kallare_entredorr
      domain: switch
    then:
    - type: turn_on
      device_id: 1c4a115fa85b98304d806e241b814a2f
      entity_id: switch.kallare_entredorr
      domain: switch
  mode: restart

The first condition is supposed to be valid for any following if statement. The two if statements (I have tried elif but no success on the second) have to conditions that is meant to be “and” i.e. {{ triggered by trigger id AND light is off }}

This as I mentioned above only a start if I can get it to work I will have 5 cameras as triggers with different action as result.
Hoping for some enlightenment :wink: / Lennart

This may not suit the direction you are trying to go in but I’d suggest:

  • Use the UI to create your automation - it makes getting the yaml right so much easier
  • Use a Choose action instead of all the if/elif/else/endif construct. It makes picking off each trigger and other conditions soo much easier.
  • Use AND blocks within the conditions for the Choose options to ensure the correct logic is being used.

Just my thoughts

Thx @templeton_nash I might have to look at that but since I’m used to if statements it would be easier for me to understand and translate from the LUA scripts I have in Domoticz but perhaps Choose is a better option. The UI option I do understand that it will work but most likely will hamper me later on when I’m a bit more in to the YAML, anyhow thanks for suggestion.

I don’t use the UI personally, however I agree with @templeton_nash because the UI generates yaml in the background, which you can copy and modify. The option might be a great way to get you started on your yaml journey :wink:

Depending on witch camera that triggered the automation, sun, and light status different actions should happen.

This depends a bit on your actual automation wishes BUT my big recommendation would be to separate these out into numerous small automation! This will be easier to maintain and more flexible to extend in future.

So instead of a set of convoluted nested conditions, just go with “if trigger camera 1 detected motion → when condition camera 2 no motion detected and sun is up → do specific action A”.
Followed by automations for “specific action B” etc.

Generally this will help you to concentrate on the expected effects (“specific action”) rather than dealing with all possible combinations of triggers and conditions, which most probably will change and become more complex over time. Let me know how it goes!!

I understand your desire to write this in yaml, and there is nothing wrong with that and learning and understanding the yaml will undoubtedly assist you moving forward.

However as others have said, it may be worth you initially using the Ui to start the process here and then edit it or at least look at it in yaml once you have a solid starting point.

I am not sure if any of it or all of it is a cut and paste issue, but pretty much all off your indentation is wrong here:

trigger:
- type: motion

## SHOULD BE

trigger:
  - type: motion

Also:

- if:
  condition:  # THIS DOES NOT BELONG
  - condition: trigger
    id: cam_ka
  - condition: device
    ....
    ....

## SHOULD BE

- if: 
  - condition: trigger
    id: cam_ka
  - condition: device
    ....
    .... 

Start with the Ui and let it help you learn the correct yaml structure and spacing etc and then work from there would be my best advice.

EDIT: Also its advisable to use states rather than devices where possible.

1 Like

If I understand your automation correctly, it does this:

When a camera’s motion sensor turns on, and the sun is below the horizon, a corresponding switch is turned on (but only if it’s currently off).

Is that exactly what you want to do for all five cameras (i.e. turn on an associated switch)? Or will some of the five cameras require a different action?

@rossk thx, think it some of it is cut / paste issue but I’ll try your other suggsetions

@123 In this automation it is more or less the same for all 5 cameras but I have a couple of others that will need different action depending on trigger.

alias: Larm Bromma
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.motion_bromma_entre
    to: "on"
    from: "off"
    id: switch.koksfonster
  - platform: state
    entity_id: binary_sensor.motion_bromma_kallartrappa
    to: "on"
    from: "off"
    id: switch.kallare_entredorr
condition:
  - condition: sun
    before: sunrise
    after: sunset
action:
  - if:
      - condition: template
        value_template: '{{ is_state(trigger.id,"off") }}'
    then:
      - service: homeassistant.turn_on
        data: {}
        target:
          entity_id: '{{ trigger.id }}'
mode: parallel

You could do something like this for the ones that are exactly the same. You could expand the logic for the ones that are different as well.

I prefer not to use ‘devices’ unless I must. entities are easier to work with.

I didn’t test the above. Just demonstrating the use of variables instead


btw, you use ‘restart’ in your definition but is that really what you want? that could impede another motion’s action if they both trigger at the same time.

1 Like

@calisro will try that, thx!

You can streamline it a bit more by replacing the if with an equivalent condition. The advantage is that if the condition isn’t fulfilled then the automation never executes its action (and its last_triggered remains unchanged).

alias: Larm Bromma
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.motion_bromma_entre
    to: "on"
    from: "off"
    id: switch.koksfonster
  - platform: state
    entity_id: binary_sensor.motion_bromma_kallartrappa
    to: "on"
    from: "off"
    id: switch.kallare_entredorr
condition:
  - "{{ is_state('sun.sun', 'below_horizon') }}"
  - "{{ is_state(trigger.id, 'off') }}"
action:
  - service: homeassistant.turn_on
    target:
      entity_id: '{{ trigger.id }}'
mode: parallel

However, leby confirmed that some cameras won’t have the same action:

Therefore the complexity of the automation’s action is likely to increase in order to accomodate the “others that will need different action”.

@leby

What sort of actions will the other cameras require?

@123 I have one or actually two camorras in a remote location (holiday home) where I have different automations depending on if the house is empty or if I’m there.
I have a “boolean” that should be checked in the condition and If I’m not at the house all lights in the house should turn on. I also had a plan to send a notification in this second case but not that important.
Just checking so I understood, - “{{ is_state(‘sun.sun’, ‘below_horizon’) }}” is equal to that it is after sunset and before sunrise “nighttime”, right?

Correct. Between sunset and sunrise the sun is below the horizon so the Template Condition I posted is equivalent to the Sun Condition you posted.

1 Like

Ok, now i thought I understood some more but hit the wall immediately I tried to extend the function to also turn off the triggered light after 5 minutes :frowning: I added this code.

  - delay:
      minutes: 5
  - service: homeassistant.turn_on
    target: null
    entity_id: '{{ trigger.id }}'

And the complete code now looks like this:

alias: Larm Bromma
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.motion_bromma_entre
    to: 'on'
    from: 'off'
    id: switch.koksfonster
  - platform: state
    entity_id: binary_sensor.motion_bromma_kallartrappa
    to: 'on'
    from: 'off'
    id: switch.kallare_entredorr
condition:
  - condition: template
    value_template: '{{ is_state(''sun.sun'', ''below_horizon'') }}'
  - condition: template
    value_template: '{{ is_state(trigger.id, ''off'') }}'
action:
  - service: homeassistant.turn_on
    target: null
    entity_id: '{{ trigger.id }}'
  - delay:
      minutes: 5
  - service: homeassistant.turn_on
    target: null
    entity_id: '{{ trigger.id }}'
mode: parallel

The purpose was to first turn on the lite and after 5 minutes turn off. The delay part of the action should not happen if the first part didn’t got triggered, i.e if the light was on to start with the automation should not turn it off , only if the cameras trigger had turned it on.

@123 example:

Yours:

Hmm, when I format as you suggest I get “Message malformed: expected a dictionary for dictionary value @ data[‘action’][0][‘target’]” error. Can’t get this to work
 It look logical but still.

This suggest you have a problem with the first action sequence with reference to the target!

Did you correct both actions above? Can you repost the complete corrected yaml that you say is showing the above error?

Thx, now I don’t get the error but it the lights don’t get triggered. I double checked the entity names and they are correct. The code now looks like this:

alias: Larm Bromma
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.motion_bromma_entre
    to: 'on'
    from: 'off'
    id: switch.koksfonster
  - platform: state
    entity_id: binary_sensor.motion_bromma_kallartrappa
    to: 'on'
    from: 'off'
    id: switch.kallare_entredorr
condition:
  - '{{ is_state(''sun.sun'', ''below_horizon'') }}'
  - '{{ is_state(trigger.id, ''off'') }}'
action:
  - service: homeassistant.turn_on
    target:
      entity_id: '{{ trigger.id }}'
  - delay:
      minutes: 5
  - service: homeassistant.turn_off
    target:
      entity_id: '{{ trigger.id }}'
mode: parallel

It really looks so neat as I hoped it would, but I have missed something. I checked the cameras and a get the motion, I even built the flow i Node-RED and it works but the cant seems to get this to work.

EDIT: Now I can get it to work when I excluded the

- '{{ is_state(''sun.sun'', ''below_horizon'') }}' 

Will try again later when the sun is down with it back in as condition. I already realize tough that I need to turn on more then one light, is it possible to use scenes instead of the switch, I cant seem to find a state on the scene

EDIT2: Don’t think scenes will solve it anyhow, I will give the action: - choose: a go, seems to be closer to my former experience with sql and lua


You define a scene containing the lights you want to turn on (or off) and then simply activate the scene using scene.turn_on (see the first example in the documentation).