Loop through Media Player source list

@Petro, how would you place this code in a script?

  alias: Sonos Next Favourite
  sequence:
    {%- set entity_id = 'media_player.sonos' %}
    {%- set current = states(entity_id) %}
    {%- set source_list = state_attr(entity_id, 'source_list') %}
    {%- set index = source_list.index(current) %}
    {%- set next = 0 if current == source_list[-1] else index + 1 %}
    {{ source_list[next] }}

You literally just place that in the script section as is. Depending on how you have your script section broken out, you may need the - sign in front of alias.

I must be missing something obvious here…

image
image

'1553339734942':
  alias: sonos next favourite
  {%- set entity_id = 'media_player.sonos' %}
  {%- set current = states(entity_id) %}
  {%- set source_list = state_attr(entity_id, 'source_list') %}
  {%- set index = source_list.index(current) %}
  {%- set next = 0 if current == source_list[-1] else index + 1 %}
  {{ source_list[next] }}

Missing the word sequence

  alias: Sonos Next Favourite
  sequence:
    {%- set entity_id = 'media_player.sonos' %}
    {%- set current = states(entity_id) %}
    {%- set source_list = state_attr(entity_id, 'source_list') %}
    {%- set index = source_list.index(current) %}
    {%- set next = 0 if current == source_list[-1] else index + 1 %}
    {{ source_list[next] }}

Thanks for getting back to me. I’m still getting the same error when I check my config

“Error loading /config/configuration.yaml: while scanning for the next token
found character ‘%’ that cannot start any token
in “/config/scripts.yaml”, line 81, column 6”

any other suggestions?

I’m braindead this morning. You are completely missing your action and service. YOu need to add that and place this template in the source field.

Take a look at your previous script. Notice it has a service with attributes and a data section?

EDIT:

  alias: Sonos Next Favourite
  sequence:
  - service: media_player.select_source
    data_template:
      entity_id: media_player.sonos
      source: >
        {%- set entity_id = 'media_player.sonos' %}
        {%- set current = state_attr(entity_id, 'source') %}
        {%- set source_list = state_attr(entity_id, 'source_list') %}
        {%- set index = source_list.index(current) %}
        {%- set next = 0 if current == source_list[-1] else index + 1 %}
        {{ source_list[next] }}
1 Like

it almost works…but it keeps trying to put the state “playing” as the source

Edited it, try it again

Weird…it doesn’t work but nothing shows up in the log files.

I’m wondering if this would be easier with a input_select with a list of the sources. I’m just not sure how to make the source = an input_select.

EDIT - Found the proper format on a different thread.

'1553339734862':
  alias: Sonos Source
  sequence:
  - service: media_player.select_source
    data_template:
      entity_id: media_player.sonos
      source: "{{  states('input_select.sonos_source') }}"

are you using the correct entity_id?

I am. i tried a different entity_id and nothing happened as well. It’s okay though i got the input_select changing the sources for now. Is there a way to trigger the next option on a input_select?

Hello.

Trying to get this to work also. No luck, script does not work for me either.

Were you able to solve this? I also want to change media player source with one button.

Try this:

bathroom_cycle_player_source:
  alias: Bathroom Cycle Player Source
  sequence:
  - service: media_player.select_source
    entity_id: media_player.bad
    data_template:
      source: >
        {%- set entity_id = 'media_player.bad' %}
        {%- set current = state_attr(entity_id, 'source') %}
        {%- set source_list = state_attr(entity_id, 'source_list') %}
        {%- set index = source_list.index(current) %}
        {%- set next = 0 if current == source_list[-1] else index + 1 %}
        {{ source_list[next] }}
2 Likes

bah looking back at my template, it’s missing data_template instead of data. Edited it

1 Like

Sorry to dig up an old thread - but how would you do this in node-RED?

Hope it’s ok to revive this…

I’m trying to accomplish the exact same thing. I grabbed the code above, and I think I did it right, but I get an error… I want to be able to cycle through my Sonos sources (favorites) with a button. An automation is calling this.

bathroom_source:
  alias: Sonos Next Favorite
  sequence:
    - service: media_player.select_source
      data:
        entity_id: media_player.bathroom
        source: >
          {%- set entity_id = 'media_player.bathroom' %}
          {%- set current = state_attr(entity_id, 'source') %}
          {%- set source_list = state_attr(entity_id, 'source_list') %}
          {%- set index = source_list.index(current) %}
          {%- set next = 0 if current == source_list[-1] else index + 1 %}
          {{ source_list[next] }}

The error:

2021-01-08 02:22:04 ERROR (MainThread) [homeassistant.components.script.bathroom_source] Sonos Next Favourite: Error executing script. Unexpected error for call_service at pos 1: Error rendering data template: ValueError: None is not in list

Thanks!

That should be working. I don’t see anything wrong in the code. Can you take a screenshot of media_player.bathroom inside the developer tools -> states page?

Sorry for the delayed response. I didn’t get a notification. Thanks for your reply!

The attribute “source” only has a value in some cases - e.g. if the source is a Sonos Radio station. If the Sonos favorite is e.g. a (Spotify) playlist, than “source” is not set, hence the “None” error. In case of a playlist, the attribute “media_playlist” is set to the name of the playlist and is identical to that of the source list entry. There are also other types of source list entries which are neither playlists nor radio stations - e.g. the “Artists” entry of the Sonos Library. This entry would not be be playable in the first place. The combinations of these scenarios will make tricky to cycle through the source list.

There’s been some changes recently to the Sonos HA integration. So some attributes have changed or been revised.

Anyway, source attribute is only present when playing radio stations (eg. TuneIn or similar)
When on playlists, source attrbute is omitted and you have to test for that scenario, otherwise the template will fail. Preferrably before doing the sequence at all, as I expect you don’t want to skip to a radio station when a playlist is currently running ? But you could do a test in the template that eg. chose first source from source_list if source attribute is not present.

{%- set entity_id = 'media_player.bad' %}
{%- set current = state_attr(entity_id, 'source') if state_attr('media_player.bad', 'source') != none else state_attr('media_player.bad', 'source_list')[0] %}
{%- set source_list = state_attr(entity_id, 'source_list') %}
{%- set index = source_list.index(current) %}
{%- set next = 0 if current == source_list[-1] else index + 1 %}
{{ source_list[next] }}

Ciao !