Automation based on location of entity with unknown name?

You could use an event trigger that watches for state_changed events. Then use a condition that requires old_state to be none, and entity_id to start with geo_location.lightning_strike_.

How does it look in the code to set wildcards for entity IDs?

Something like this:

- trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {{ trigger.old_state is none and
         trigger.entity_id.startswith('geo_location.lightning_strike_') }}
  action:
    ...

Thanks, will give a shot. Have to wait for the next storm to test!

Why not just create a temporary entity on the States page? You can enter whatever you want at the top and click SET STATE. It will just create an entry in the state machine, which is what the automation will react to. Next time you restart HA that entry will be gone.

So here is the automation I am testing:


- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {{ trigger.old_state is none and
         trigger.entity_id.startswith('geo_location.lightning_strike_') }}
  action:
  - service: input_boolean.turn_on
    data:
      entity_id: input_boolean.lightning_state

I create an entity “geo_location.lightning_strike_3694317” with a state of “10” - it appears on my state list correctly, but this boolean doesn’t turn on.

Sorry, my bad. Try this:

- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {{ trigger.event.data.old_state is none and
         trigger.event.data.entity_id.startswith('geo_location.lightning_strike_') }}
  action:
  - service: input_boolean.turn_on
    data:
      entity_id: input_boolean.lightning_state

Ok, that works, thanks.

do you have the same with the end of the lightning show in the sky ?

With this automation, any way to have the state of this wildcard entity in a message?

{{ states.sensor.startswith(‘geo_location.lightning_strike_’).state }} or similar?

Sorry for taking so long to respond. If you want to add a step to the action part of the automation, then yes, use this:

{{ trigger.event.data.new_state.state }}

Just to complicate things - I didn’t want to be notified about every strike, so I tried to come up with a system to only get notified by the first one, and if there had been no strikes for 30 minutes, to re-enable notifications. This puts the notification action in a different automation than the initial strike detection. Can you think of a way to add the state of the lightning strike entity to the annoucement, which occurs in a different automation? Set a variable equal to it?

Here’s what I have so far:

- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
    condition: template
    value_template: >
      {{ trigger.event.data.old_state is none and
         trigger.event.data.entity_id.startswith('geo_location.lightning_strike_') }}
  action:
  - service: timer.cancel
    data:
      entity_id: timer.lightning_timer
  - service: timer.start
    data:
      entity_id: timer.lightning_timer
      duration: '00:30:00'
  - service: input_boolean.turn_on
    data:
      entity_id: input_boolean.lightning_state

- alias: Lightning Alarm
  initial_state: 'on'
  trigger:
    platform: state
    entity_id: input_boolean.lightning_state
    from: 'off'
    to: 'on'
  action:
  - service: notify.email3
    data_template:
      message: 'Skynet reports lightning strike.'
  - service: notify.alexa_media
    data_template:
      message: 'Skynet reports lightning strike within 30 miles.'
      data:
        type: announce
      target: [media_player.kitchen_echo_2,media_player.jason_s_spot]

- alias: Lightning Reset
  initial_state: 'on'
  trigger:
    platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.lightning_timer
  action:
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.lightning_state
  - service: timer.cancel
    data:
      entity_id: timer.lightning_timer

I think you can make this much simpler:

- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
  - condition: template
    value_template: >
      {{ trigger.event.data.old_state is none and
         trigger.event.data.entity_id.startswith('geo_location.lightning_strike_') }}
  - condition: state
    entity_id: timer.lightning_timer
    state: idle
  action:
  - service: timer.start
    data:
      entity_id: timer.lightning_timer
      duration: '00:30:00'
  - service: input_boolean.turn_on
    data:
      entity_id: input_boolean.lightning_state
  - service: notify.email3
    data_template:
      message: 'Skynet reports lightning strike.'
  - service: notify.alexa_media
    data_template:
      message: 'Skynet reports lightning strike within 30 miles.'
      data:
        type: announce
      target: [media_player.kitchen_echo_2,media_player.jason_s_spot]

- alias: Lightning Reset
  initial_state: 'on'
  trigger:
    platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.lightning_timer
  action:
  - service: input_boolean.turn_off
    data:
      entity_id: input_boolean.lightning_state

Not sure where you want to use {{ trigger.event.data.new_state.state }}, but now you can.

I assume you’re using input_boolean.lightning_state for another reason, but if not, you can simplify this even more by removing it and the second automation.

Very nice. The one thing this doesn’t do that my original code does is “reset” the timer if a new strike occurs. My initial idea was if there was a strike every 15 minutes, it would only give a single warning, even if this happened all day long. It was only after 30 minutes of no strikes would it allow another announcement. I think your code would allow a new announcement every 30 minutes, even if there was an ongoing storm. That’s why I had the extra booleans in there.

the state of each new entity has the # of miles from your house to the strike, so I wanted that to be included in the announcement, like this:

- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
  - condition: template
    value_template: >
      {{ trigger.event.data.old_state is none and
         trigger.event.data.entity_id.startswith('geo_location.lightning_strike_') }}
  - condition: state
    entity_id: timer.lightning_timer
    state: idle
  action:
  - service: timer.start
    data:
      entity_id: timer.lightning_timer
      duration: '00:30:00'
  - service: notify.email3
    data_template:
      message: 'Skynet reports lightning strike within {{ trigger.event.data.new_state.state }} miles.'
  - service: notify.alexa_media
    data_template:
      message: 'Skynet reports lightning strike within {{ trigger.event.data.new_state.state }} miles.'
      data:
        type: announce
      target: [media_player.kitchen_echo_2,media_player.jason_s_spot]

What would be even better would be if I could save the state in a variable (the # of miles from the strike) and only re-announce if there was one closer (within that 30 minute period).

Ok, I think you can implement the first idea this way. This first automation simply starts, or restarts, the timer whenever there is a new lightning strike. It also saves the state for use in the second automation. (Of course, you need to define input_text.last_strike. I suppose you could also use an input_number instead of an input_text.)

- alias: Lightning Timer Start
  initial_state: 'on'
  trigger:
    platform: event
    event_type: state_changed
  condition:
  - condition: template
    value_template: >
      {{ trigger.event.data.old_state is none and
         trigger.event.data.entity_id.startswith('geo_location.lightning_strike_') }}
  action:
  - service: input_text.set_value
    data_template:
      entity_id: input_text.last_strike
      value: "{{ trigger.event.data.new_state.state }}"
  # This will start, or restart, the timer.
  - service: timer.start
    data:
      entity_id: timer.lightning_timer
      duration: '00:30:00'

This second automation triggers only when the timer starts (i.e., timer.start is called while the timer is idle.) I haven’t tested this, but according to the docs, if timer.start is called while the timer is active, it should fire the timer.restarted event instead of timer.started.

- alias: Lightning Announce
  initial_state: 'on'
  trigger:
    # Trigger only when timer starts (i.e., not when it restarts.)
    platform: event
    event_type: timer.started
    event_data:
      entity_id: timer.lightning_timer
  action:
  - service: notify.email3
    data_template:
      message: 'Skynet reports lightning strike within {{ states('input_text.last_strike') }} miles.'
  - service: notify.alexa_media
    data_template:
      message: 'Skynet reports lightning strike within {{ states('input_text.last_strike') }} miles.'
      data:
        type: announce
      target: [media_player.kitchen_echo_2,media_player.jason_s_spot]

Looks good, thanks!

Could I use two variables, input_text.last_strike and closest_strike, and make an extra announcement automation if the last_strike is closer than the closest_strike, and then set closest_strike to be equal to last_strike?

The message line is giving this error:

in “/config/automations.yaml”, line 33, column 7
expected , but found ‘’

Oops, my bad. Try:

      message: "Skynet reports lightning strike within {{ states('input_text.last_strike') }} miles."

Testing this automation - it’s announcing every new strike. From what I can tell, the timer.started trigger is firing every time the timer is reset with the timer.start service. It’s not registering it as a timer.restarted trigger if timer.start is acting on an active timer.

Sorry about that. Looking at the code I discovered the timer.restarted event is only fired if the timer was paused. Now that I look again, the docs say the same thing:

Starting a timer triggers a started event unless the timer is paused, in that case, it triggers a restarted event.

That’s unfortunate, because starting a timer that is running does restart it. :frowning_face:

Anyway, maybe you can change the first automation to first pause the timer (which does nothing if it isn’t running.)

   - service: timer.pause
    data:
      entity_id: timer.lightning_timer
   - service: timer.start
    data:
      entity_id: timer.lightning_timer
      duration: '00:30:00'

So if the timer isn’t running, the first step does nothing, and the second step should cause a timer.started event. But if the timer is running, the first step will pause it, causing the second step to restart it as before, but now it will fire a timer.restarted event.