Struggling with setting entities to a variable

Hello all. My first post here…I hope it’s a good one. I have been coding in Visual Basic for a while and I am trying to make the jump to YAML and jinja2. I have been looking over all of the documentation that I can find, but I am just not getting a grasp on what I am trying to learn.

I have written an automation for the sole purpose of learning how things work. There is no real use for this automation other than to better understand how to code. I am sure the code below is laughable, so chuckle along and help me learn the concepts that I am not getting.

I am used to object-based coding, but I am really struggling with how to create objects here. What I am hoping to learn is how to create a variable which represents a dynamic group of entities. I want to “pick apart” the entities by filtering different attributes. I realize that I could take the list in motion_entities and put it in the entity_id for the trigger. The automation should trigger if the state of any of the entities changes to ‘on’, a message is sent to my phone with the friendly name of the entities, and a light will turn on for 10 seconds then shut off.

- alias: Someone is Here
  id: "1711758350491"
  variables:
    motion_entities:
      - binary_sensor.front_doorbell_motion
      - binary_sensor.kitchen_camera_motion
      - binary_sensor.my_garage_motion
  trigger:
    - platform: state
      entity_id: "{{ motion_entities | list }}"
      to: "on"
  action:
    - action: notify.mobile_app_my_iphone_13_pro_max
      data:
        title: The following sensors were activated
        message: >
          {{ motion_entities
            | select_attr('state', 'on')
            | map('friendly_name')
            | list }}
    - action: light.turn_on
      target:
        entity_id: light.larry
      data:
        rgb_color:
          - 58
          - 253
          - 255
        brightness_pct: 100
    - delay:
        hours: 0
        minutes: 0
        seconds: 10
        milliseconds: 0
    - action: light.turn_off
      target:
        entity_id: light.larry
  mode: single

The entity_id in the state trigger does not accept templates. You would have to construct a template trigger: Automation Trigger - Home Assistant

The instinct to put everything in variables and reduce redundancy is good programming, but might make it harder to learn. It’s ok to have a little extra verbosity if it helps you get a steady footing. Also, instead of an object model, it might be easier to root yourself in an event model, especially when writing automations. All that said, you might should try something like this:

- alias: Someone is Here
  id: "1711758350491"
  trigger:
    - platform: state
      entity_id:
      - binary_sensor.front_doorbell_motion
      - binary_sensor.kitchen_camera_motion
      - binary_sensor.my_garage_motion
      to: "on"
  action:
    - action: notify.mobile_app_my_iphone_13_pro_max
      data:
        title: The following sensor activated
        message: >
          {{ trigger.entity_id }}
    - action: light.turn_on
      target:
        entity_id: light.larry
      data:
        rgb_color:
          - 58
          - 253
          - 255
        brightness_pct: 100
    - delay:
        hours: 0
        minutes: 0
        seconds: 10
        milliseconds: 0
    - action: light.turn_off
      target:
        entity_id: light.larry
  mode: single

This changes the notification to only have the motion sensor that just now was triggered, but think of it from the user’s point of view. If the front doorbell activates, they’ll get a notification. If five seconds later the garage activates, they don’t need that notification to tell them again that the front doorbell is still detecting motion.

Thank you @tom_l for the insight on the limitations of creating automations. I hadn’t seen anything that said that it couldn’t be done. I will absolutely look into template triggers.

I super appreciate the insight @atlflyer with your revision. The big thing that I learned is that I don’t need to create a variable to recall the entity_id from the trigger. I do have some follow-up questions.

After message: the is a > which I understand to be used so that quotation marks are not needed for the template and is usually used for multi-line templates. My question is that I have seen other examples where a pipe is used instead of the > character. What would the pipe do that the > doesn’t?

I ran the code you have and found that the notification from message: {{ trigger.entity_id }} only shows the entity that triggered. My object-based thinking assumes that the entity_id is the list of entities that were part of the trigger. I assume that a filter would have been needed to identify which of the entity_id items was changed to ‘on’. Can you help me understand how {{ trigger.entity_id }} filtered the correct item from the list?

I would like to use the friendly_name (if there is one) for the entity called out in the {{ trigger.entity_id }} template. My understanding is that ALL templates produce a string, not an object. I figure that I need to convert the string that is generated into an entity object so that I can get the friendly_name attribute. I have put together two templates that I thought would do that, but I am hitting a wall. Here’s what I have:

{{ states[{{ trigger.entity_id }}].attr(‘friendly_name’) }}
{{ state_attr({{ trigger.entity_id }},‘friendly_name’) }}

My assumption is that states(string variable) or states(‘this_entity’) creates an entity object. Is this correct?

I have seen and ( ) used for states(string), but I don’t understand when to each.

Thanks in advance for the help here.

If you’re writing this in yaml, use anchors.

Also, I reordered your fields in the auotmation to show you the order in which the fields are processed. Trigger, then variables, then Conditions (missing), then Actions.

- alias: Someone is Here
  id: "1711758350491"
  trigger:
    - platform: state
      entity_id: &someone_is_here_entities
      - binary_sensor.front_doorbell_motion
      - binary_sensor.kitchen_camera_motion
      - binary_sensor.my_garage_motion
      to: "on"
  variables:
    motion_entities: *someone_is_here_entities
  action:
    - action: notify.mobile_app_my_iphone_13_pro_max
      data:
        title: The following sensors were activated
        message: >
          {{ motion_entities
            | select_attr('state', 'on')
            | map('friendly_name')
            | list }}
    - action: light.turn_on
      target:
        entity_id: light.larry
      data:
        rgb_color:
          - 58
          - 253
          - 255
        brightness_pct: 100
    - delay:
        hours: 0
        minutes: 0
        seconds: 10
        milliseconds: 0
    - action: light.turn_off
      target:
        entity_id: light.larry
  mode: single

The pipe leaves newlines in place, but the > folds them into spaces. However, this is a difference that hardly ever matters within the context of how YAML is used in HA. You can read more here if you want all the details.

You can’t nest templates inside other templates, and you don’t need to.

{{ state_attr(trigger.entity_id,'friendly_name') }}

No, the states() function returns the raw state of the entity. To get the state object, you can index it from within the states object, like:

{{ states.binary_sensor.my_garage_motion }}

if you know the entity id or

{{ states[trigger.entity_id] }}

if you are getting the entity id from a variable.

Here is more info about the states object that you should definitely know as you get further into using templates. Also, please do note the warning about preferring states('sensor.my_sensor') over states.sensor.my_sensor.state.

I code in Visual Basic where the variables go on the top. Thanks for setting me straight here.

Seriously, this has been incredibly helpful for me to better understand. There is plenty of documentation out there about how the pieces work, but I haven’t found much that explains how they all fit together. There is only so much you can learn with the UI and picking apart code that others has written is difficult to interpret without some of the base knowledge. I really appreciate the help!

Unless templating is explicitly mentioned in the documentation then it is not possible. e.g.

Screenshot 2024-08-23 at 11-36-16 RESTful - Home Assistant