Correct use of templates in automations

Hello

Is it somehow possible to use templates in the condition of an automation?
In the following example I am trying to put the household status to asleep, when all persons of the household are marked as asleep.
So the trigger is every person that goes to sleep.
The condition is to check if all other persons are already asleep.
It works with multiple automations that are specified for one person, but I am guessing there is also a way to shorten this. I tried to create a template for the condition, but this is failing.

Is there anyone who can help me with that issue? I am still quite new to home assisstant and yaml. Help is much appreciated.

- alias: Presence - Mark Household as Asleep
  id: 'presence_mark_household_as_asleep'
  trigger:
    - platform: state
      entity_id: 
        - sensor.person1_status
      to: 'Asleep'
  
  condition:
    - condition: template
      value_template: "{{ states('sensor.person2_status') == 'Asleep'}}"

  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.household_status_dropdown
        option: Asleep

- alias: Presence - Mark Household as Asleep2
  id: 'presence_mark_household_as_asleep2'
  trigger:
    - platform: state
      entity_id: 
        - sensor.person2_status
      to: 'Asleep'
  
  condition:
    - condition: template
      value_template: "{{ states('sensor.person1_status') == 'Asleep'}}"

  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.household_status_dropdown
        option: Asleep
- alias: Presence - Mark Household as Asleep
  id: 'presence_mark_household_as_asleep'
  trigger:
    - platform: state
      entity_id: 
        - sensor.person1_status
        - sensor.person2_status
      to: 'Asleep'
  
  condition:
    - condition: template
      value_template: >
        {% if trigger.entity_id == 'sensor.person1_status' %}
          "{{ states('sensor.person2_status') == 'Asleep'}}"
        {% else %}
          "{{ states('sensor.person1_status') == 'Asleep'}}"
        {% endif %}

  action:
    - service: input_select.select_option
      data:
        entity_id: input_select.household_status_dropdown
        option: Asleep
- alias: Presence - Mark Household as Asleep
  trigger:
    platform: state
    entity_id: 
      - sensor.person1_status
      - sensor.person2_status
    to: 'Asleep'
  condition:
    condition: state
    entity_id: 
      - sensor.person1_status
      - sensor.person2_status
    state: 'Asleep' 
  action:
    service: input_select.select_option
    data:
      entity_id: input_select.household_status_dropdown
      option: Asleep

Thank you for the quick reply. That does look very easy :smiley: I just haven’t thought about it this way…

Maybe another one. I have the feeling is also not correctly expressed.
Here I am trying to set one person to Just Left which is supposed to be an intermediate state between home and away. This is in analogy to Phil’s guide for not so binary presence states.
Again I was trying to combine all persons in one automation, however the transition to ‘Just Left’ is only allowed if the person was previously reported to be ‘Home’ or ‘Just Arrived’.
The issue however is the condition that applies should be in-line with the person, that triggered. the automation. Any idea? …

- alias: Presence - Mark person as just left
  id: 'presence_mark_person_as_just_left'
  trigger:
    - platform: state
      entity_id: 
        - device_tracker.person1
        - device_tracker.person2
      from: 'home'
      to: 'not_home'

  condition:
    - condition: or
      conditions:
        - condition: template
          value_template: "{{ states('sensor.person1_status') == 'Just Arrived'}}"
        - condition: template
          value_template: "{{ states('sensor.person1_status') == 'Home'}}"
        - condition: template
          value_template: "{{ states('sensor.person2_status') == 'Just Arrived'}}"
        - condition: template
          value_template: "{{ states('sensor.person2_status') == 'Home'}}"

  action:
    - service: input_select.select_option
      data_template:
        entity_id: >
          {% if trigger.entity_id == 'device_tracker.person1' %}
            input_select.markus_status_dropdown
          {% else %}
            input_select.jessica_status_dropdown
          {% endif %}
        option: Just Left

Yeah that would need a template, but the templates can be combined to reduce the code significantly…

- alias: Presence - Mark person as just left
  trigger:
    platform: state
    entity_id: 
      - device_tracker.person1
      - device_tracker.person2
    from: 'home'
    to: 'not_home'
  condition:
    - >
      {{ (trigger.to_state.entity_id == 'device_tracker.person1' and
        (states('sensor.person1_status') == 'Just Arrived'
        or states('sensor.person1_status') == 'Home')) 
        or (states('sensor.person2_status') == 'Just Arrived'
        or states('sensor.person2_status') == 'Home') }}
  action:
    service: input_select.select_option
    data:
      entity_id: >
        {% if trigger.to_state.entity_id == 'device_tracker.person1' %} input_select.markus_status_dropdown
        {% else %} input_select.jessica_status_dropdown {% endif %}
      option: Just Left

Thanks alot that is also working :+1:

1 Like

No worries :+1:

I think I start to understand why @forschi tried to template sensors per person and household a much better solution. Found out, that when both persons leave in the same car, the router will drop the IP addresses of the two personal devices simultaneously, however the automation is only run once, even if both trigger events are true, which results in only one person being marked as ‘Just Left’.

The automation will run once per trigger, if both persons leave, the automation will run twice. I use this method for tons of automations and have never had an issue with it not picking up the second trigger.

I believe there has been a change to this in automations “lately” to allow automations to trigger and run simulaneously, However I didn’t look into that.
I felt creating a template sensor that evaluated “continuously” was less prone to errors. Until now of course as I had to remove the “entity_id” part from all my template sensors… I had a lot of those.
Now my occupancy just stays at “Just arrived” :frowning:

How can I debug to check if an automation is run multiple times?

Look in the logbook, it will say automation XX was triggered by YY.

Hmm the logbook did not indicate it being triggered twice. I will investigate on future occurances.

However I have another inconsistency at the Asleep and Wake-Up automation. My intention was to use me entering airplane mode over night as a sign, that I am in bed. However my better half does not follow that behaviour, so for now I have put in some time the person is considered asleep. However the automation never sets person2’s status to ‘Asleep’ or ‘Waking Up’

  ##########################################################
  ## Mark person as asleep
  ##########################################################
- alias: Presence - Mark person as asleep
  id: 'presence_mark_person_as_asleep'
  trigger:
    #Fallback for people who do not enter airplane mode over night
    - platform: time
      at: '22:00:00'
    - platform: state
      entity_id: 
        - device_tracker.person1
        - device_tracker.person2
      from: 'home'
      to: 'not_home'

  condition:
    - >
      {{ trigger.to_state.entity_id == 'device_tracker.person1' and
        (  states('sensor.person1_status') == 'Just Arrived'
        or states('sensor.person1_status') == 'Home')
        or 
        (  states('sensor.person2_status') == 'Just Arrived'
        or states('sensor.person2_status') == 'Home') }}

  action:
    - service: input_select.select_option
      data_template:
        entity_id: >
          {% if trigger.entity_id == 'device_tracker.person1' %}
            input_select.person1_status_dropdown
          {% else %}
            input_select.person2_status_dropdown
          {% endif %}
        option: Asleep

  ##########################################################
  ## Mark person as waking up
  ##########################################################
- alias: Presence - Mark person as waking up
  id: 'presence_mark_person_as_waking_up'
  trigger:
    # Fallback for people who do not enter airplane mode over night
    - platform: time
      at: '07:30:00'
    - platform: state
      entity_id: 
        - device_tracker.person1
        - device_tracker.person2
      from: 'not_home'
      to: 'home'
  
  condition:
    - >
      {{ trigger.to_state.entity_id == 'device_tracker.person1' and
        ( states('sensor.person1_status') == 'Asleep' )
        or 
        states('sensor.person2_status') == 'Asleep' }}
  
  action:
    # Wake-Up Person1
    - service: input_select.select_option
      data_template:
        entity_id: >
          {% if trigger.entity_id == 'device_tracker.person1' %}
            input_select.person1_status_dropdown
          {% elif trigger.entity_id == 'device_tracker.person2' %}
          {% else %}
            input_select.person1_status_dropdown
          {% endif %}
        option: Waking Up
    # Wake-Up Person2
    - service: input_select.select_option
      data_template:
        entity_id: >
          {% if trigger.entity_id == 'device_tracker.person1' %}
          {% elif trigger.entity_id == 'device_tracker.person2' %}
            input_select.person2_status_dropdown
          {% else %}
            input_select.person2_status_dropdown
          {% endif %}
        option: Waking Up

However I am beginning to think that a propper bed occupancy sensor will be a better more reliable solution. So mid-term I need to think about creating such a hardware-sensor.

You’re missing some brackets in your conditions so it will only fire if the trigger entity_id is person 1, you want the trigger entity_id bit to be bracketed with the first or, so it is

(trigger = person 1 and (blah or blah)) 

or

(blah or blah) 

Currently you have

Trigger = person 1

And

(blah and blah) or (blah and blah)

That’s why you’re not getting the second trigger for person 2, because the condition is filtering it out.

1 Like

Which I agree does not make much sense. Thanks for spotting this :slight_smile:

1 Like

Hm, it was still mit working correctly the last night.
Even though I checked afterwards in the development area, that the second section of the condition evaluates to true and the bracketing is corrected.
As far as I am aware there is no real debugging available, that I can check step by step what is happening, right?
And as I am not able to overwrite the time maybe my only option to dig in deeper is to replace the time trigger with some manual input boolean helper and try to elaborate what is being done there…

I didn’t notice that you had a time trigger too (that wasn’t in the code that you marked as a solution).

That’s not going to work with that condition.

The very first bit of the condition is trigger.to_state.entity_id, time triggers don’t have a to_state entity_id so the condition will fail.

You need to rethink your logic for this.

Yes it somehow evolved…
So you are saying it may be best to split the two triggers into separate automations such that they can be handled independently?

To be honest I can’t see the benefit of the time trigger in this instance at all :man_shrugging:

In the asleep automation, it is because my wife is not entering airplane mode over night, so the trigger that works for me does not work for her.
But her sleep schedule is very similar each day, which why I tried to catch it with a time trigger until I find a better solution.
As said before, to track the sleeping state consistently without any dependencies, I probably need to build a bed occupancy sensor. But for now I would say the time trigger would to the job for her.
I just started with the home automation, but the presence detection is basically the backbone of every automation, so I am investing some time here to get it right. Maybe start of with some simplifications such as the time trigger, but in general already containing all the states required at a later stage.

Yeah, I mean you have to work your automations around how your home works, so if you and your wife do things differently then you probably want an automation for each of you that follows your individual logic.

In my house there is me, my other half and the kids, but one of the kids is 17 so she can be up later than us.

The way my homeassistant knows we’ve all gone to bed is when all the lights turn off after 10pm. There are various automations that control the lights, and of course we can manually control them too, but them all being off after 10pm basically means we’re all asleep (or sitting in bed with insomnia).

The house then knows we’re awake the first time one of the ground floor motion sensors pick up movement after 6am. This means the kids can get up and go to the bathroom through the night, or even someone can get a drink from the kitchen through the night without homeassistant thinking that we’re all up.

Of course if a downstairs sensor is tripped whilst homeassistant thinks we’re asleep, and an upstairs one hasn’t tripped first, then it must be an intruder so that would trigger a security automation.

But yeah, that’s how my house works, which I’ve refined over years of trial and error. Obviously you need to look at the behaviour of the occupants of your home and work out what you can use as triggers and conditions based on that behaviour.

1 Like