Trigger automation on nested attribute

Trying to create a new automation that triggers based on the state value of a nested attribute, but not finding a solution. I see how to trigger on an attribute, but not a nested attribute.

Below are some of the attribute contents from the Garmin integration, and sensor sensor.last_activity:

last_synced: "2025-03-04T16:11:27.184"
activityId: 18437398344
activityName: Yoga
startTimeLocal: "2025-03-04 08:58:49"
startTimeGMT: "2025-03-04 15:58:49"
activityType:
  typeId: 163
  typeKey: yoga
  parentTypeId: 29
  isHidden: false
  trimmable: false
  restricted: false
eventType:
  typeId: 9
  typeKey: uncategorized
  sortOrder: 10
duration: 687.8779907226562
elapsedDuration: 693.9910278320312
movingDuration: 687.8779907226562
hasPolyline: false

I’d like to trigger the automation on the nested attribute activityType: typeKey:, so when typeKey changes to a known activity, the automation would fire. The attribute activityName: is user defined, whereas typeKey: is integration defined, I’d rather trigger off the integration defined name than a user degined name.

I’ve gotten this far, but I’m not sure how to get the nested attribute typeKey: state?

trigger: state
entity_id:
  - sensor.last_activity
attribute: activityType

Any advice would be appreciated, thanks!

You will need to break out the desired sub-attribute(s) using template sensors or template triggers.

template:
  - sensor:
      - name: Last Activity Type Key
        availability: "{{ has_value('sensor.last_activity') }}"
        state: |
          {{ state_attr('sensor.last_activity', 'activityType')['typeKey'] | default("unknown type", 1) }}

So create a new template sensor that extracts the sub-attribute, and stores it as a state, then trigger off that new template sensor? Would the new template sensor need it’s own automation to check if the sub-attribute has changed?

Yes, see above.

No, the template will be rendered whenever the activityType attribute updates.

Go into traces and find Changed Variables.

This gives you the things available.
You may want trigger.entity_id From this example, for instance. (Or trigger.from_state.attributes.friendly_name)

trigger:
  id: '0'
  idx: '0'
  alias: null
  platform: state
  entity_id: binary_sensor.back_door_motion
  from_state:
    entity_id: binary_sensor.back_door_motion
    state: 'off'
    attributes:
      state: motion
      expires_at: '2025-03-04T12:20:17'
      attribution: Data provided by Ring.com
      device_class: motion
      friendly_name: Back Door Motion
    last_changed: '2025-03-04T18:20:17.347677+00:00'
    last_reported: '2025-03-04T18:20:17.347677+00:00'
    last_updated: '2025-03-04T18:20:17.347677+00:00'
    context:
      id: 01JNH66723ETGV2FAX6BTMJHP3
      parent_id: null
      user_id: null
  to_state:
    entity_id: binary_sensor.back_door_motion
    state: 'on'
    attributes:

Trying to build that template sensor to extract the nested data, but I don’t think I’m understanding how to get to the nested attribute; this is what I’ve got but it’s not working, looks like state_attr is only accepting 3 positional arguments, not 4.

"{{ state_attr('sensor.last_activity', 'activityType', 'typeKey') }}"

Is there a better way to walk these nested attributes?

Try “{{ state_attr(‘sensor.last_activity’, ‘activityType’).typeKey }}”

1 Like

Eureka! That did it! Thank you so much!

“{{ state_attr('sensor.last_activity', 'activityType').typeKey }}”

Hmm, using the above creates values that are quoted, and I’m not sure why…
e.g.
image

So a state trigger for hiking isn’t the same as "hiking", and setting the trigger state for "hiking" isn’t working. I’m thinking stripping the "" would fix the issue, just not sure how to-do that?

edit: I believe the template needs to be "quoted" in order to function properly…

Can you paste the YAML you’re using for the sensor? I think you probably need to remove the quotes, but that’s only if you’ve got something like this in the YAML:

state: |

or

state: >

So I built a template sensor to extract the nested value I’m trying to trigger off of, that template looks like this (and produces the "quoted" string):

“{{ state_attr('sensor.last_activity', 'activityType').typeKey | string }}”

And that template creates this sensor sensor.extracted_last_activity, which I’m using as a trigger.

edit: I’ve tried without the | string and I still get a "quoted" string.

I understand. Just try taking out the double quote marks from the code you pasted.

Edit: just the double quotes. Leave the single ones.

I think we have a winner, testing now.

Just note that the values recorded previously in the history will still have the quotes. But once you fix it the sensor won’t put the quotes in moving forward.

Understood, thank you, and that’s fine, I’m not too worried about the historical data, just the new data, to trigger the automation.

That did it! Thanks @d921, @Edwin_D & @Didgeridrew for the assistance to get this working!

Happy it works now.

The quotes are a pain. If you use the automation editor, don’t use them, the automation editor will do it. If you use yaml, use them when it is a single line, not when you use > or | to put the template on sepatate line(s).

Thanks for that!

I think this is also a side effect of using Home Assistant for almost a decade, there was no UI editor early on, and I code regularly outside of the HA project, so I tend to follow normal coding standards. So the UI does things that aren’t expected, like adding " around things for you. Guess I’m just getting old, and miss the manual way of doing things. :smirk: