Template failure using sort with attribute media_position_updated_at

Trying to sort a list of media players and obtain the one with the newest state attribute: media_position_updated_at. This template fails with
UndefinedError: 'homeassistant.helpers.template.TemplateState object' has no attribute 'media_position_updated_at'

{{ states.media_player | selectattr('attributes.media_position_updated_at', 'defined') | sort(reverse=true, attribute='media_position_updated_at') | map(attribute='entity_id') | list | first | default(none) }}

Sample:

Entity: media_player.office_echo_dot_left
State: standby
State attributes:
 source_list:
   - Local Speaker
 friendly_name: Office Echo Dot Left
 supported_features: 56253
 is_volume_muted: false
 media_content_type: standby
 media_position_updated_at: '2023-08-13T02:21:51.181611+00:00'
 source: Local Speaker
 available: true
 bluetooth_list: []
 last_called: true
 last_called_timestamp: 1691888921265
 last_called_summary: what time is it
 volume_level: 0.21
{{ states.media_player | selectattr('attributes.media_position_updated_at', 'defined') | sort(reverse=true, attribute='attributes.media_position_updated_at') | map(attribute='entity_id') | list | first | default(none) }}

You da man!!

But I’m also LOL! I almost had it!

{{ states.media_player | selectattr('attributes.media_position_updated_at', 'defined') | sort(reverse=true, attribute='media_position_updated_at') | map(attribute='entity_id') | list | first | default(none) }}
{{ states.media_player | selectattr('attributes.media_position_updated_at', 'defined') | sort(reverse=true, attribute='attributes.media_position_updated_at') | map(attribute='entity_id') | list | first | default(none) }}

Unfortunately, now that I have a working template, it’s no help. When I say “Alexa” several within listening distance update their media position. When I say something else, the one taking control of the converation updates media position but then that is followed quite quickly by an updated media position for media_player.this_device which is alexa on my phone, even though my phone is locked and dormant. I’m trying to find a way to work around media_player.last_alexa failing to update in a timely manner, or be able to determine when the service call update.last_alexa has completed but alas, it seems hopeless. IF there’s a change to be made then there’s an event service_registered which I can watch for but if there’s no change to be made, there’s no indication of that fact in HA, at least from what I can tell So, I have to hardcode a fixed delay in scripting, which if too small results in the previous last_alexa being summoned, or an error as there’s no service in HA to call at that instant, and if too large is annoying!

After reflecting on this a bit, I did some more tests and the media_postion_updated at must only be a reflection of which device heard something and not which alexa took command and responded as now I see office_echo_dot_left, office_echo_dot_right and then living_room_echo_dot_left update their media position when I say “alexa” but after asking a question, office_echo_dot_left answers but the most recent media_position_updated_at remains as living_room_echo_dot_left. Useless!

Another thought… After I invoke a script via (alexa scenes), if the script is interactive I always execute service: alexa_media.update_last_called as the first step. I just tested speaking to the same alexa and manually running the service call and I see the last_called_timestamp update even if there’s no change in media_player.last_alexa (i.e. attribute last_called: true). That same alexa just shows an updated timestamp for last_called. Might there be a way to watch for that change in all alexa’s last_called_timestamps via a template?


Revelation!!


I added the last_updated_timestamp to my sensor.last alexa and am trying checking for that to change.

 - name: "{{ states.media_player | selectattr('attributes.last_called', 'defined') | selectattr('attributes.last_called','eq',true) | map(attribute='name') | first | default(none) }}"
    unique_id: last_alexa
    state: "{{ states.media_player | selectattr('attributes.last_called', 'defined') | selectattr('attributes.last_called','eq',true) | map(attribute='entity_id') | first | default(none) }}"
    attributes:
      last_called_timestamp: >
        {{ states.media_player | selectattr('attributes.last_called', 'defined') | selectattr('attributes.last_called','eq',true) | map(attribute='attributes.last_called_timestamp') | first | default(none) }}

I’ve created a script I can execute at the beginning of other interactive scripts. I’ve added it to script.good_night and it seems to be good! Minimal delay and she interacted with me from the new alexa!

alias: Update sensor.last_alexa - wait for tmestamp to update
sequence:
  - service: alexa_media.update_last_called
    data: {}
  - wait_for_trigger:
      - platform: state
        entity_id:
          - sensor.last_alexa
        attribute: last_called_timestamp
    timeout:
      hours: 0
      minutes: 0
      seconds: 5
      milliseconds: 0
mode: single

Thank you for your templating expertise! I think I am learning…