Automate on any state change, using value of new state

How would I create an automation that would trigger on all state changes of an entity? For example, I’d like to announce on a Google Home every change in state of Sun.

  1. Can this be done generically? Ie without knowing the actual state name?
  2. Can this be done on a list of known states? Ie without having to duplicate triggers or conditions?

And for a bonus question:

  1. Can you send a single message to multiple devices? Ie can I announce a TTS message on all my Google Homes?
  1. Yes. Just don’t specify a state. It will trigger on all changes. But beware - it will also trigger on attribute changes. e.g.
trigger:
 - platform: state
   entity_id: switch.my_switch
  1. Yes you can list the states you want if you don’t want them all (e.g. if an entity could go to the ‘unknown’ state, or you dont want to trigger on attribute changes).
trigger:
 - platform: state
   entity_id: switch.my_switch
   to: 
    - 'on'
    - 'off'
  1. Yes, create a group of your Google homes. TTS to that.
1 Like

Brilliant, thanks.

I presume then the way to extract the state further on (eg to announce “it is sunset” is directly via the device, ie there’s no “trigger result” I can use instead?

There are trigger variables you can use to extract this information:

For example:

  - service: notify.telegram_system
    data:
      title: '*ALERT*'
      message: "Public IP changed from {{ trigger.from_state.state }} to {{ trigger.to_state.state }}"

Perfect. For completion this is what I’ve ended with:

In groups.yaml (as there’s no way to create groups via the UI):

alert_announce_speakers:
        name: Alert Announce Speakers
        entities:
                - media_player.speaker_1
                - media_player.speaker_2

The automation was largely created in the UI, but this is what it resulted in. I used the generic form of the trigger with an exception list:

- id: 'xxx'
  alias: Alert on trigger
  description: ''
  trigger:
  - platform: state
    entity_id: lupt.lupt
  condition:
  - condition: not
    conditions:
    - condition: state
      entity_id: lupt.lupt
      state:
      - Exception
  action:
  - service: tts.google_translate_say
    data:
      entity_id: group.alert_announce_speakers
      message: {{ trigger.to_state.state }} alert triggered!
  mode: single

EDIT: Actually the above falls foul of @tom_l 's warning about attribute changes, so I’ll probably go back to having a “whitelist”.

That’s the best way as it prevents unneeded triggering but if you have a lot of states sometimes it’s easier just to add this condition to prevent the actions running:

- "{{ trigger.from_state.state != trigger.to_state.state}}"

That’s neat. It’s only 5 states I need to list, but logically the exception list is the more correct solution… so I’m torn :wink:

By the way, I had to use to instead of state when listing multiple acceptable states:

platform: state
entity_id: lupt.lupt
to: 
  - state1
  - state2
  - state3

Yeah that was a typo. Sorry.

I’ve fixed it in case anyone else reads it.

I think you can cooperate with node-red

Node red is not necessary for any of this.