Automations #1: trigger only fires when it changes from not true to true

In an automation written to run when the heating drops below 20C, the trigger will fire when the temperature changes from 20 to 19.

trigger:
  - platform: numeric_state
    entity_id:
      - climate.study
    for:
      hours: 0
      minutes: 10
      seconds: 0
    below: 20

It will not fire again until the temperature rises above 20C and drops for a second time.

A trigger is an event… Not a state, but a change of state.

You can have more than one trigger:

trigger:
  - platform: numeric_state
    entity_id:
      - climate.study
    for:
      hours: 0
      minutes: 10
      seconds: 0
    below: 20
  - platform: numeric_state
    entity_id:
      - climate.study
    for:
      hours: 0
      minutes: 10
      seconds: 0
    below: 18

This automation will run when either one of the triggers fires - when the temperature drops from 20 to 19 or when it drops from 18 to 17. If the thermostat goes up from 17 to 19, then falls again, the automation rill run a second time because the second trigger has fired again.

A common issue is that the actions will not run during HA start-up should the entity ID’s value already be above or below the set threshold. In that case, one must trigger on the HA start event and add a guard condition.

trigger:
  - platform: numeric_state
    entity_id:
      - climate.study
    below: 20
  - platform: homeassistant
    event: start
condition:
  - condition: numeric_state
    entity_id: 
      - climate.study
    below: 20 

With state triggers (not with numeric state) you can leave the trigger value unspecified and use conditions in the action block:

trigger:
  - platform: state
    entity_id:
      - binary_sensor.daytime
action:
  - if:
      - condition: state
        entity_id: binary_sensor.daytime
        state: "off"
    then:
      - service: light.turn_on
        target:
          entity_id: light.yard
        data: {}
    else:
      - service: light.turn_off
        target:
          entity_id: light.yard
        data: {}

This trigger will fire every time the state of binary_sensor.daytime changes. Be careful when you do this - some entities change state very quickly and the automation will run every time. It will also fire if the value of the sensor changes to “unavailable” and whenever any of the entity’s attributes change.

To prevent it firing when the sensor is unavailable:

trigger:
  - platform: state
    entity_id:
      - binary_sensor.daytime
    not_to:
      - unknown
      - unavailable

Testing

You can test an automation in the UI by clicking Run in the three dots menu (top right).

However, this only runs the Action block of the automation. To test triggers and conditions as well, go to Developer Tools | States and change the value of the trigger entity.

Note: Developer Tools only changes sensor values temporarily. They will revert to their correct value next time the sensor updates.

The service automation.trigger will also run an automation. You can use this in Developer Tools | Services:

It does not test its triggers and by default it also bypasses any conditions, but setting the skip_conditions attribute to false will include these in a test.

My automation does not always work (AKA: why won’t the trigger always fire)

Because triggers only fire when changing from false to true, you might run into situations where automations do not always work as expected. It most notably happens when you add extra conditions. An often heard question is then: why won’t the trigger “always” fire.

Think for a moment about what “always fire” means. Is it that the automation should perform the action every millisecond? Suppose you put a notification in the action. You certainly do not want an endless stream of those.

When you have an automation with a single trigger, and you add extra conditions, then there are also extra triggers you need to think about.

This is why. If conditions A and B both need to be true for something to happen, then there are two ways that trigger (pun intended) the situation where A and B are both true. If A becomes true, and B is already true, or if B becomes true and A is already true.

Taking that into account, the general format for an automation with multiple conditions is:

trigger:
  A becomes true
  B becomes true
  C becomes true
  ...
condition:
  A is true
  B is true
  C is true
  ...
action:
  do something

I know this feels like double work, but remember only one trigger can fire at the same time. So you always need to check the other things too. With one condition, you only need one trigger, because it proves the only condition you have is already met by the trigger.

Alternative solution for multiple triggers and conditions

A template trigger can help, because the template only becomes true ‘when all the stars align’ so to say. a template trigger {{ A and B and C }} will only become true once all is as it should be. So using (only) that you do not need a condition. But still, this does not “always” fire. It only fires when it changes from being false to being true.

I still want it to trigger always

Always triggering would make it impossible to intervene. So event based, how it is now, is actually better suited for everything that is not absolutely critical to get right 100% of the time. For instance, an automation to turn the light off when there is no motion should not always fire, because you want to be able to turn the light on manually too. Motion sensors aren’t perfect. And especially in a home, you often cannot, or do not want to, write an automation that takes every situation into account. A home is not like a factory.

OK, I’ll use a time trigger instead

A time trigger often seems like an alternative to the “always fire” thought. But in fact, it is a worse way. If you check too often, HA is busy doing nothing all the time. Write 200 of those automations, and it is becoming messy soon. If you check infrequently, the automation is very slow to respond. Checking every 5 minutes implies you may need to wait almost 5 minutes for something to happen.

Using triggers as suggested works instantaneously, only in the situation intended, and leaves room for other automations (or people) to act on the same thing too.

Time triggers are best reserved for when there’s no other way than to periodically get new information, also known as polling. It is best kept for a last resort.


The Home Assistant Cookbook - Index.

5 Likes

Should one add a few things how to mitigate common follow-up questions?

For example, one issue is that numeric state triggers won’t update upon start-up, so you need to trigger on the start event and add a numeric state condition.

2 Likes

Yes please… :grin:

1 Like