Grabbing individual items off a dict

Not sure i;'f i’m going about this the right way, but I’m making a card using paper buttons row to display all the favorite items on my Sonos using the sensor.sonos_favorites

what I’m trying to do is grab the individual names of the playlists and use them as the button names, the first hurdle i’m facing is that I can retrieve a list of all the items in the sensor, but i have no clue how to access them individually:

I would’ve thought it would be something along the lines of:

{{ states.sensor.sonos_favorites.attributes.items[0]}}

or somthing like that but nope… any ideas?

“items” is a dictionary, so you need to dereference its elements with their keys (e.g., “FV:2/5”, as opposed to 0).

I figured something like that, i’m wondering if those FV:#/# will change as the items on the list change etc, but that’s tomorrow’s problem, in the meantime i get an error:

Yes, the FV:#/# keys will obviously change as you add or remove favorites. What are you actually trying to do with the information in the “items” elements?

Before you tackle that, though, you’re using the states object which is not what you want to do. You should use state_attr('sensor.sonos_favorites', 'items') to get the attribute. It will save you headaches in corner cases like when Sonos is temporarily broken (something that happens with unfortunate frequency given Sonos’s reliance on 2.4GHz Wi-Fi, in a lot of Sonos environments).

it’s more of an experiment at this point, but “ideally” i want to have a row of buttons that each trigger a playlist. Right now i did it by hand, but it would be nice if i didn’t have to as things change:

I have my Sonos via ethernet so i’m not too worried about reliability from that standpoint

If items is actually a dictionary, you should be able to use the values() method then use the index numbers to select…

(state_attr('sensor.sonos_favorites', 'items').values()|list)[0]

YUP!!.. that’s exactly what i was trying to do, thanks!!

@estley
I get asked this same question / scenario a lot for the SpotifyPlus Integration. Here’s the How do I access dictionary items from a Service Response topic I put together for my FAQ wiki page that explains the issue in more detail.

Hope it helps!

How do I access dictionary items from a Service Response

All of the SpotifyPlus services that retrieve data from the Spotify Web API will return the data in a dictionary format in the service response. The data can then be processed in a template and used however you wish.

For example, consider the following service call to retrieve all albums for an artist:

action: spotifyplus.get_artist_albums
data:
  entity_id: media_player.spotifyplus_todd_l
  artist_id: 6APm8EjxOHSYM5B4i3vT3q
  include_groups: album
  limit_total: 10
  sort_result: true

The results would look like this (shortened for brevity, actual result will contain MUCH more data):

result:
  date_last_refreshed: 1739564010.147239
  items:
    - album_type: album
      artists:
        - id: 6APm8EjxOHSYM5B4i3vT3q
          name: MercyMe
          uri: spotify:artist:6APm8EjxOHSYM5B4i3vT3q
      id: 2ezUrMWSvn9nYsI6DvdCgW
      image_url: https://i.scdn.co/image/ab67616d0000b2732e7368a96604933f6a87b97a
      name: "10"
      total_tracks: 25
      uri: spotify:album:2ezUrMWSvn9nYsI6DvdCgW
    - album_type: album
      artists:
        - id: 6APm8EjxOHSYM5B4i3vT3q
          name: MercyMe
          uri: spotify:artist:6APm8EjxOHSYM5B4i3vT3q      
      id: 4nZS59zzTABfnSPq7a9iP1
      image_url: https://i.scdn.co/image/ab67616d0000b2733e8dc4e2eb7551afa8db3339
      name: All That Is Within Me
      total_tracks: 10
      uri: spotify:album:4nZS59zzTABfnSPq7a9iP1          

The Problem
When you go to process the data in your template processing, your first thought is to access the repeating items collection data using something like this:

artist_name: "{{serviceResponse.result.items[0].name}}"

which will result in an error that looks like this:

Error rendering data template: UndefinedError: builtin_function_or_method object has no element 0.

Keep in mind that you are processing data that is returned in a dictionary using Python; the Python dictionary class has a METHOD named items, which is not to be confused with the items KEY that is returned in the dictionary. The result.items[0].name statement is trying to call the Python items METHOD, which results in the builtin_function_or_method object has no element 0 error.

The Solution
You have to reference items as a dictionary KEY so that it’s not inferred as a METHOD, like so:

artist_name: "{{serviceResponse.result['items'][0].name}}"

Here’s a simple example I tested in the HA Developer Tools \ Templates editor:

{%-
set serviceResponse = {
  "result": {
    "items": [
      {
        "artists": [
          {
            "name": "MercyMe",
            "uri": "spotify:artist:6APm8EjxOHSYM5B4i3vT3q"
          }
        ],
        "image_url": "https://i.scdn.co/image/ab67616d0000b2732e7368a96604933f6a87b97a",
        "name": "10",
        "uri": "spotify:album:2ezUrMWSvn9nYsI6DvdCgW"
      },
      {
        "artists": [
          {
            "name": "MercyMe",
            "uri": "spotify:artist:6APm8EjxOHSYM5B4i3vT3q"
          }
        ],
        "image_url": "https://i.scdn.co/image/ab67616d0000b2733e8dc4e2eb7551afa8db3339",
        "name": "All That Is Within Me",
        "uri": "spotify:album:4nZS59zzTABfnSPq7a9iP1"
      }
    ]
  }
}
-%}

Artist Albums: {{"\n"}}
{%- for item in serviceResponse['result']['items'] -%}
  {%- set trackName = item['name'] | default('') -%}
  {%- set trackImageUrl = item['image_url'] | default('') -%}
  {%- set trackUri = item['uri'] | default('') -%}
  {%- set trackArtist = item['artists'][0]['name'] | default('') -%}
  - {{ trackName }} ({{trackUri}}) - {{ trackArtist }} {{"\n"}}
{%- endfor -%}

{{"\n"}}
1st item result A = {{ serviceResponse['result']['items'][0]['uri'] }}
1st item result B = {{ serviceResponse.result['items'][0].uri }}
1st item result C = {{ serviceResponse.result.items[0].uri }}    <- this fails