Automation help; wait for clear or time

Goal of the automation is as follows

  • turn on a light at 5am at 40% brightness
  • then wait for the bed presence sensor to clear
  • if not cleared by 6h30 turn on all the lights at full power
  • once bed presence cleared, wait for a motion sensor to trigger
  • then run a script that does stuff houses in the house
  • close lights 5 minutes later

the issue: full lights dont trigger at 6h30 am; however the rest does work once bed presence clears regardless of time

alias: Lumiere matin - travail
description: ''
triggers:
  - trigger: time
    at: '05:00:00'
conditions:
  - condition: and
    conditions:
      - type: is_on
        condition: device
        device_id: b3a81120720ce78f6b85e066efa58cb2
        entity_id: a6540a5d3938e0a817316c1a6eb0430b
        domain: binary_sensor
      - condition: state
        entity_id: binary_sensor.master_bed_presence_bed_occupied_either_2
        state:
          - 'on'
        enabled: true
actions:
  - action: light.turn_on
    metadata: {}
    data:
      transition: 300
      brightness_pct: 40
      rgb_color:
        - 195
        - 238
        - 196
    target:
      entity_id:
        - light.gu10_local
  - if:
      - condition: time
        after: '06:30:00'
    then:
      - action: light.turn_on
        metadata: {}
        target:
          entity_id:
            - light.gu10_local
        data:
          brightness_pct: 100
      - action: light.turn_on
        metadata: {}
        target:
          entity_id: light.lampes_de_chevet_maitres
        data: {}
      - action: button.press
        metadata: {}
        target:
          entity_id: button.rf_blaster_zrf01_start3
        data: {}
      - wait_for_trigger:
          - trigger: state
            entity_id:
              - binary_sensor.detecteur_presense_ch_maitres_occupancy
            enabled: true
            to:
              - 'on'
        continue_on_timeout: false
      - action: script.allumer_appareil_routine_matinal
        metadata: {}
        data: {}
      - delay:
          hours: 0
          minutes: 5
          seconds: 0
          milliseconds: 0
      - action: light.turn_off
        metadata: {}
        target:
          entity_id:
            - light.gu10_local
            - light.lampes_de_chevet_maitres
        data: {}
        enabled: true
      - action: button.press
        metadata: {}
        target:
          entity_id: button.rf_blaster_zrf01_start3
        data: {}
    enabled: true
    else:
      - wait_for_trigger:
          - trigger: state
            entity_id:
              - binary_sensor.detecteur_presense_ch_maitres_occupancy
            for:
              hours: 0
              minutes: 0
              seconds: 0
            enabled: true
            to:
              - 'on'
        continue_on_timeout: false
      - action: script.allumer_appareil_routine_matinal
        metadata: {}
        data: {}
      - delay:
          hours: 0
          minutes: 5
          seconds: 0
          milliseconds: 0
      - action: light.turn_off
        metadata: {}
        target:
          entity_id:
            - light.gu10_local
            - light.lampes_de_chevet_maitres
        data: {}
mode: single
triggers:
  - trigger: time
    at: '05:00:00'

But then you check if it’s after 6:30:

actions:
  - if:
      - condition: time
        after: '06:30:00'
    then:

Personally, I write small, single purpose, short-lived automations.

What if you look at your requirement in terms of triggers and actions:

  • turn on a light at 5am at 40% brightness

That one is a simple trigger and turn on a light or a scene

  • then wait for the bed presence sensor to clear

No action there, no automation – although you could set an input_boolean.out_of_bde to use later based on the presence changing state (perhaps after some amount of time).

  • if not cleared by 6h30 turn on all the lights at full power

The event/trigger is 6:30, condition on input_boolean.out_of_bed, turn on lights/scene.

  • once bed presence cleared, wait for a motion sensor to trigger
  • then run a script that does stuff houses in the house

Automation trigger on motion, condition out of bed, run script. (I’ll bet you need other conditions too.)

  • close lights 5 minutes later

Trigger is lights have been on 5 minutes. Action turn off lights. Is that always the case – turn lights off after 5 minutes? Or condition this on having just gotten out of bed?

I use a lot of timers to use as conditions in my automations instead of a wait and then another condition.

First nothing specifically checks at 0630 to see if the lights need to change. To do that you need another trigger at 0630.

Agreed. Short waits and out. Retrigger later of you have more things happening… don’t make the script wait till 630.

so remove the 6h30 part and have a second automation that triggers if conditions met

You can either use separate automations or use one automation with multiple triggers and branched actions using Choose or If/Then actions. Both ways work. Use whichever makes the most sense for you and the particular use case. If you decide to use a single automation, make sure to move the general conditions to where they are needed if they don’t apply to all the branched sequences.

One thing to note is if you go the single automation route, with multiple and possibly unrelated triggers, is what happens to the automation if it is running and another trigger fires.

Again, personally I (almost) always avoid using trigger IDs as a way to pack multiple automations into a single automation. It really helps to keep the yaml less deeply nested, shorter, and easier to follow.

I approach this from the opposite direction:

I try to avoid control structures (loops, if’s, chooses) in my automations - I don’t think any of my automations have more than 1 control structure (a lot have no control structures).
This limits my usage of trigger IDs - since without control structures, it becomes difficult to pack 3 automations into 1.

Most of my automations only have 1 trigger condition - which (obviously) makes trigger IDs pointless.

However if an automation has more than 1 trigger, there is about a 50/50 chance I am using trigger IDs, I do this for two reasons:

  • The triggers are interlinked - using a single automation means I don’t have to worry about a second trigger occurring while the first is active.
  • I use the IDs as “logical outputs” meaning that the ID is more about what the outcome of the automation will be, than the input that triggered it. Hence I don’t need more than 1 control structure because often the trigger ID is simply templated and passed to an action or script.

All of my automations are “almost” immediate - meaning any timed waits are only because an external device needs a short pause (max 2 seconds) and there are no waits for conditions to become true.

Note, I am not simply moving the goal posts (from automations to scripts):

  • About 1/2 my scripts have only 1 control structure.
  • The others typically don’t use more than 2 levels of nesting.

TL;DR - Keep automations (and scripts) simple/linear, if you do that you can only use trigger IDs where its logical to use them - you don’t need to blanket exclude their use.

This looks like two automations to me:

The first is just to turn the lights on/up:

  • Triggers at 5 am and 6:30 am.
  • Does the appropriate checks and sets the lights to the correct brightness.
    • Does nothing at 6:30 if the bed is already clear.

The second automation:

  • Triggers on the motion sensor.
  • Has a condition that this automation hasn’t run yet today.
  • Has a time condition (between 5 - 7 am).
  • Has a bed presence cleared condition.
  • then run a script that does stuff houses in the house
  • Wait 5 minutes
  • Turn off the light.

I actually have an automation very similar to this, for when I get up in the morning.

Just to add it here..
And my way of doing automations is to have everything in one place so that I don’t have to search for it.

If this is a wake up automation, then I’ll pack everything in there with whatever number of trigger IDs it may need.
If that becomes 3, 5 or more different IDs/choose doesn’t matter to me.
I just switch to yaml mode when I need to read what is happening.
The indentation makes it easy to “skip forward” to the next section.

My reasoning is that it’s enough of a problem to find all automations, so keeping fewer grouped automations makes it easier for me.

That is exactly what happened to me.

(I apologize as I just finished my second coffee…)

My journey consisted of:

  1. I felt that combining was the solution to having so many separate (and hard to track) automations and so I ended up with single, large automations with vaguely related triggers. All just to keep things in one place.

  2. I had tried using the “Assign category” feature as well as naming prefixes so the UI would group them, but I started to use more helpers and scripts and although those also have categories, the category names are not shared between them and there’s no UI page to show all automations, scripts and helpers in one place. Really, just not that helpful.

  3. Unrelated to the above, as the Automation Editor was improved it became harder and harder to use the UI when the automations were larger and more deeply nested with conditionals. I ended up always immediately switching to YAML mode. (Plus, YAML is how code is shared on this forum.)

  4. The complex automations got hard to follow so I added alias: all over the place to include in-line documentation. That messed up the UI even more and it’s a pretty restrictive way to add comments.

  5. I started using more template sensors that needed to be in YAML anyway. And those don’t show up in the UI – so now I’m editing some things in the UI and some directly in files. The situation was getting worse!

  6. Yikes! Then my sensors.yaml and template_sensors.yaml had the same problem as the automations: They were all thrown together in one place and I had to try and remember what automations or scripts used what sensors and templates. At least in those files you can add extensive comments.

I then moved to using packages:

  • All related helpers, template sensors, automations and scripts are in one place. A helper or template that an automation uses is right there with the automation.

  • You can break more complex home automation tasks into more files as it grows (see below).

  • Since automations/scripts can be grouped in a single file, I can then use single-trigger, short-lived, and too-the-point automations. Much easier to debug and to get right the first time.

  • Fewer conditionals makes for for simple YAML and thus fewer indentation errors, etc.

  • (I also write more scripts and my automations actions simply call a script. Makes testing easier.)

  • I can add comment blocks, in-line comments and add white space between lines of YAML.

  • I now track changes via git and keep in github.

  • I can rename a directory and completely disable everything related to some home automation feature.

  • Of course, code in files means command line tools and more advanced editors are available.

There’s some irony in that all the improvements to the UI automations editor resulted in me moving away from the UI and to using YAML.

Still ongoing, but complex things can be highly organized. For example:

root@ha ~ $ find config/packages/sprinklers/ -name \*.yaml
config/packages/sprinklers/sprinkler_selects.yaml
config/packages/sprinklers/sprinkler_schedule.yaml
config/packages/sprinklers/sprinkler_test_valves.yaml
config/packages/sprinklers/sprinkler_run.yaml
config/packages/sprinklers/sprinkler_queue.yaml
config/packages/sprinklers/sprinkler_config.yaml
config/packages/sprinklers/sprinkler_ui.yaml
config/packages/sprinklers/local_sprinklers/flow_monitor.yaml
config/packages/sprinklers/local_sprinklers/monitoring.yaml

Whew…

The beginning of my journey was almost identical to Busman’s.

I forked from Busman when package started to be used, instead I decided to group by type instead - hence all the things that control lights are grouped, all things that read temperature, etc…

I work in both the UI and YAML files, so the nature of the grouping has to adapt:

  • In files it’s just ordering of the entries they tend to be group together before moving onto the next group - however I do have separate YAML files for sensors, binary sensors, inputs, templates etc.
  • In the UI I can often group “all button presses” into a single file (automation/script) - even with only one control structure, however I also make use of categories to organize my automations/scripts.

This is just a reflection of the fact that in any sufficiently complex system, there are often multiple ways to group/categories things.

We are all trying to optimize for readability, however I don’t think there is a perfect answer for that.

Very true. I think one thing everyone can (or should) agree on is that a chunk of code should be related – using trigger IDs just to make up for the lack of good way to organized automations is not good. How you write an automation to do something is unrelated to how you organize your collection of automations.

Where does it end? Just have a single automation for the entire house… :wink:

Like you, I still have simpler things grouped together, like lights or mostly similar (security):

config/packages/prod/security.yaml
config/packages/prod/lights.yaml

The real win is when anything gets a bit more comples:

config/packages/prod/hvac/fans_etc.yaml
config/packages/prod/hvac/ui.yaml
config/packages/prod/hvac/hall_thermostat.yaml
config/packages/prod/hvac/schedule.yaml

or not…

config/packages/prod/coffee.yaml

(Well, coffee turns out to be involved)

root@ha ~ $ wc -l config/packages/prod/coffee.yaml
219 config/packages/prod/coffee.yaml

No strict rules, of course. But once I start using helpers or templates I tend to put those in a separate file with the code that uses them.

Sorry, I’m a bit giddy over moving to packages. Odd, in some ways, because packages are a decade old feature of HA.

TBF, I don’t think someone truly understands HA until they realize that it is possible to do everything in a single automation.

For me it was asking the question - what are the downsides to using only one automation that gave me an understanding of what trade offs I was actually making.

Note, there is an advantage to using 1 huge automation - assuming you don’t set parallel execution, you never get a race condition, since there can only ever be one automation running at once.

It’s just that, that advantage doesn’t outweigh all the negatives.


HA is opinionated, it tries hard to keep state separate from logic and it seems to be pushing for more usage of the UI.

Having an opinion is not necessarily a bad thing, it tends to keep the community (as a whole) less fragmented / focussed on the “HA” way of doing things. But it does mean that as you bring in ideas from other domains (particularly software engineering) they typically have to be adapted to the HA way of doing things - hard rules from SE’s become guidelines in HA.

This is what forced my pivot in the opposite direction, I found that disparate components were too interlinked:

  • I want the AC to turn off while a window is opened (comes back on if the window is closed).
  • If a presence sensor detects I am at my desk the AC doesn’t need to be as aggressive / I need power turned on to the desk.
  • I use (colored) smart bulbs as indicators to tell me something has happened / I need to do something.
  • I can use scene switches to control multiple functions lights, AC, …
  • …

A pattern that I use often is:

  • Inputs
  • State/Helpers
  • Outputs

Using this pattern, triggers simply update helpers/inputs (state)
Then a second automation watches those state changes to actually apply the required changes.

This separation isn’t necessary for simply automations, but IMO it makes complex ones much easier to follow (and I can see the state on a dashboard).