New Sonos favorites sensor - can't search through attribute as an index

Hi’

I’m currently changing quite a few of my Sonos templates, since the deprecation of the source_list attribute and the birth of the sensor.sonos_favorites instead

One set of templates are beyond my template knowledge though. I simply can’t get my head wrapped around it… :roll_eyes::tired_face:

I’ve two templates that selects next or previous favourites from the previously indexed attribute list. Template include a circular loop - meaning skip to first source when at last source and vice versa. And with an extra twist that I define a start index no. to search from (excluding all my playlists from the ‘real’ source list (radio channels), as these are handled differently.

- id: hasp_sonos_prev_source
  alias: hasp_sonos_prev_source
  mode: single
  trigger:
    platform: mqtt
    topic: hasp/+/state/p2b16
    payload: '{"event":"down"}'
  condition:
    - condition: template
      value_template: "{{ states('sensor.media_source') != 'no source' }}"
  action:
    service: media_player.select_source
    data_template:
      entity_id: "{{ state_attr('group.sonos_all', 'entity_id')[0] }}"
      source: >-
        {% set source_start = states('sensor.sonos_source_index_start') | int(0) %}
        {% set entity_id = 'media_player.kokken' %}
        {% set current = state_attr(entity_id, 'source') %}
        {% set source_list = state_attr(state_attr('group.sonos_all', 'entity_id')[0],'source_list') %}
        {% set index = source_list.index(current) %}
        {% set prev = -1 if current == source_list[source_start] else index - 1 %}
        {{ source_list[prev] }}

I have already done the template changes in my other for/endfor loops without issues. Got help looking at this issue

These are my test template/results in HA’s template engine:

{{ states('sensor.sonos_source_index_start') }}

[{{ state_attr('sensor.sonos_favorites','items').values() | join(", ") }}]

{% set source_start = 0 | int(0) %}
{% set entity_id = 'media_player.kokken' %}
{% set current = state_attr(entity_id, 'media_title') %}
{% set source_list = states.sensor.sonos_favorites.attributes.values() | list | join(', ') %}
{% set index = source_list.index(current) %}
{% set next = source_start if current == source_list[-1] else index + 1 %}        
{{ source_list[next] }}
4

[*HT, *HT new, *New Music Friday Denmark, *The Ultimate Hit Mix, Classic FM, Classic Rock, DR Nyheder, DR P1, DR P3, DR P4 Fyn, DR P5, DR P6 Beat, Nova FM|, Radio 100|, Radio Soft|, Radio VLR, Retro Radio, Retro-Radio Millennium, Skala.fm, The Voice|]

       
R

So even it it’s appears to be an index, it’s not returning the expected source but an ‘R’ ?
Would really appreciate any help solving this, thanks.

//Henning

Remove the final join filter in order to produce a proper list.

{% set source_list = states.sensor.sonos_favorites.attributes.values() | list  %}

In my case, the values listed in the sensor’s items attribute correspond to the value found in the media_channel attribute (of a Sonos media_player), not media_title. So if I also make that substitution, and use one of my media_players, your template works for me. It correctly reports the next favorite (Main Stream) in the list of favorites.

{% set source_start = 0 | int(0) %}
{% set entity_id = 'media_player.family_room' %}
{% set current = state_attr(entity_id, 'media_channel') %}
{% set source_list = state_attr('sensor.sonos_favorites', 'items').values() | list  %}
{% set index = source_list.index(current) %}
{% set next = source_start if current == source_list[-1] else index + 1 %}        
{{ source_list[next] }}

OMFG !! I’ve completely missed the obvious reason why my template wasn’t working :man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming::man_facepalming:

And to make it even worse I actually posted the wrong template with media_title attribute in use (Correct ‘non working’ original template below)
That was a copy paste error, as the original template was using the source attribute which has been deprecated as well. I haven’t noticed that source also was gone from the media players attribute list :roll_eyes:

Your answer was the perfect solution and got me to look closer at what attributes actually is present now. media_title attribute will actually work partially, but only if player is paused. I’ve now revised to media_channel off course :laughing:

Only one issue left with this latest Sonos component change. Some radio stations overwrite both media_title and media_channel with various commercial info crap about the current programme. So the media_channel can’t always be used as a unique identifier for the actual source in Sonos and my template fails. I’ll have to file a bug report for that one.

Thank’s a million, @123 :tada::+1::sunglasses:
The god of templates :grin:

condition:
    - condition: template
      value_template: "{{ states('sensor.media_source') != 'no source' }}"
  action:
    service: media_player.select_source
    data_template:
      entity_id: "{{ state_attr('group.sonos_all', 'entity_id')[0] }}"
      source: >-
        {% set source_start = states('sensor.sonos_source_index_start') | int(0) %}
        {% set entity_id = 'media_player.kokken' %}
        {% set current = state_attr(entity_id, 'source') %}
        {% set source_list = state_attr(entity_id, 'source_list') %}
        {% set index = source_list.index(current) %}
        {% set next = source_start if current == source_list[-1] else index + 1 %}
        {{ source_list[next] }}
1 Like

If you’re interested, I believe you can reduce the original template to this:

{% set x = state_attr('sensor.sonos_favorites', 'items').values() | list %}
{% set i = x.index(state_attr('media_player.kokken', 'media_channel')) + 1 %}
{{ x[i if i <= x|count-1 else 0] }}

NOTE

The media_channel attribute doesn’t always exist. Therefore the template should be enhanced to gracefully handle this possibility.

1 Like

Hi’ @123

You basically halved the template! :astonished::muscle:
I’ll revise this and include my needed index start and give it a spin.

I’m aware that the media_channel attribute is not always present.
That’s handled in the condition, where I check my ‘helper’ sensor (sensor.media_source) to separate ‘real’ sources from playlists.

Once again, thank you for your suggestions and time invested.
I’m learning - every day :grin: Failing templates can really get my blood boiling from time to time :drop_of_blood::thermometer::imp:

Hi’ @123

One additional question popped up that, if possible, would massively simplify all my dynamic playlist templates. For now I split all my favorites in two, to be able to split them in two separate dropdown lists on my openHASP plate. One for ‘real’ sources (radio stations) and one for my playlists.

As Sonos doesn’t seem to (public) identify the origin of each favorite entries, I’ve added a preceeding ‘*’ asterix as playlist identifier, so playlists always will be sorted and listed before radio stations. Some radio channels have a trailing ‘|’ Vertical Bar as well. This only in order to separate TuneIn sources from other sources (picture size difference)

Question is now if I actually could identify the playlists using another method ?

The template list output today is:

[*HT, *HT new, *New Music Friday Denmark, *The Ultimate Hit Mix, Classic FM, Classic Rock, DR Nyheder, DR P1, DR P3, DR P4 Fyn, DR P5, DR P6 Beat, Nova FM|, Radio 100|, Radio Soft|, Radio VLR, Retro Radio, Retro-Radio Millennium, Skala.fm, The Voice|]

But when I look in HA’s dev tools the actual sensor.sonos_favorites attribute is:

items:
FV:2/38: '*HT'
FV:2/66: '*HT new'
FV:2/44: '*New Music Friday Denmark'
FV:2/47: '*The Ultimate Hit Mix'
FV:2/49: Classic FM
FV:2/54: Classic Rock
FV:2/63: DR Nyheder
FV:2/28: DR P1
FV:2/25: DR P3
FV:2/65: DR P4 Fyn
FV:2/51: DR P5
FV:2/3: DR P6 Beat
FV:2/64: Nova FM|
FV:2/60: Radio 100|
FV:2/59: Radio Soft|
FV:2/58: Radio VLR
FV:2/52: Retro Radio
FV:2/55: Retro-Radio Millennium
FV:2/50: Skala.fm
FV:2/62: The Voice|

Now for the actual question :slight_smile: Could the single quotes on the first four entries (playlists) actually be identified in the templates or are they ‘lost in translation’ when the values list is created ?

Regards
Henning

Not sure but I suspect they’ll be “lost in translation”. You can check by examining the output of this template in the Template Editor:

{{ state_attr('sensor.sonos_favorites', 'items').values() | list }}

No, all entries are unfortunately with quotes then.

['*HT', '*HT new', '*New Music Friday Denmark', '*The Ultimate Hit Mix', 'Classic FM', 'Classic Rock', 'DR Nyheder', 'DR P1', 'DR P3', 'DR P4 Fyn', 'DR P5', 'DR P6 Beat', 'Nova FM|', 'Radio 100|', 'Radio Soft|', 'Radio VLR', 'Retro Radio', 'Retro-Radio Millennium', 'Skala.fm', 'The Voice|']

Once again, thank you so much for your time and help.
Really appreciated ! :+1::+1:

1 Like