Getting the entity_picture of last active media player

Hi,
I’m trying to put a card in my main dashboard to show the entity_picture of the last active media player (last one in playing state, and if not last one in paused state).

I was able to get it working using the code below and I could put this on a Mushroom Template card, but I’m trying to just show the picture on a big custom:button-card so you can just click on it to get you to the media view in the dashboard (like in the screenshot).

Working code with Mushroom Template Card (I have a long list of media players, I’m just including 3 as an example):

{% set players =  [ states.media_player.family_room_sonos,
                    states.media_player.sonos_roam,
                    states.media_player.roku_family_room ] %}
{% set last_played = players
      | selectattr('state', 'eq', 'playing')
      | sort(reverse=true, attribute='last_changed')
      | list %}
{% set last_paused = players
      | selectattr('state', 'eq', 'paused')
      | sort(reverse=true, attribute='last_changed')
      | list %}
{% if last_played |count > 0 -%}
  {{ last_played[0].attributes.entity_picture }}
{% elif last_paused |count > 0 -%}
  {{ last_paused[0].attributes.entity_picture }}
{%- else -%}
  {{ states.media_player.spotify.attributes.entity_picture }}
{%- endif %}

This is what I have so far, but I cannot find a way to navigate the array to pick up the ones playing/paused and sorting it out (the “set last_played and set last_paused” portions):

type: custom:button-card
entity: media_player.family_room_sonos
show_name: false
show_entity_picture: true
entity_picture: |
  [[[
    const players = [ states['media_player.family_room_sonos'],
                      states['media_player.sonos_roam'],
                      states['media_player.roku_family_room'] ];
    
    set last_played = players
      | selectattr('state', 'eq', 'playing')
      | sort(reverse=true, attribute='last_changed')
      | list
      
    set last_paused = players
      | selectattr('state', 'eq', 'paused')
      | sort(reverse=true, attribute='last_changed')
      | list
                      
    if (last_played |count > 0)
        return last_played[0].attributes.entity_picture;
    elif (last_paused |count > 0)
        return last_paused[0].attributes.entity_picture;
    else
        states['media_player.spotify'].attributes.entity_picture;
  ]]]
tap_action:
  action: navigate
  navigation_path: media
styles:
  icon:
    - width: 100%
    - height: 100%

I’ve also thought about creating a media_player template (last active), but that’d open another can of worms, but I’m open to ANY suggestions at this time!

Thanks!
German

1 Like

Not the cleanest approach, but I couldn’t find a card that supports yaml code like the Mushroom Template card, so I went ahead and implemented this using that and modding the card.

Leaving one possible solution here in case anybody else needs it, but if somebody has a better approach, please do share!

type: custom:mushroom-template-card
primary: ''
secondary: ''
icon: mdi:home
picture: |-
  {% set players =  [ states.media_player.family_room_sonos,
                      states.media_player.sonos_roam,
                      states.media_player.roku_family_room ] %}
  {% set last_played = players
        | selectattr('state', 'eq', 'playing')
        | sort(reverse=true, attribute='last_changed')
        | list %}
  {% set last_paused = players
        | selectattr('state', 'eq', 'paused')
        | sort(reverse=true, attribute='last_changed')
        | list %}
  {% if last_played |count > 0 -%}
    {{ last_played[0].attributes.entity_picture }}
  {% elif last_paused |count > 0 -%}
    {{ last_paused[0].attributes.entity_picture }}
  {%- else -%}
    {{ states.media_player.spotify.attributes.entity_picture }}
  {%- endif %}
tap_action:
  action: navigate
  navigation_path: /lovelace-main/media
layout: vertical
fill_container: true
card_mod:
  style: |
    ha-card {
      padding: 0px !important;
    }
    :host {
      --mush-icon-size: 100%;
      --mush-icon-border-radius: 8%;
    }
    mushroom-state-item {
      flex: 0px; !important;
    }
3 Likes

this is so awesome! thanks for sharing it.

that scripting magic is hot. do you have any advice for someone who wants to become more proficient? is it about putting some time into learning jinja? and not just fumbling around HA forums and trying to piece it together?

No particular advice… I learned by looking at examples here on this community whenever I wanted to do something… one thing led to another… I’m far from an expert :slight_smile:

I’ve found an awesome card that allowed me to handle this in a beautiful way! Sharing in case anybody needs something like this in the future:

First, you’d need to install this card from HACS:
iantrich/config-template-card: :memo: Templatable Lovelace Configurations (github.com)

Then you’d need a sensor template to provide the name of the last active media player (playing first, if not last active paused):
I’ve included extra code to handle “Music Assistant” in case you have duplicate media_players when initiating music from that.

- platform: template
  sensors:
    #Last Active Media Player
    last_active_media_player:
      friendly_name: "Last Active Media Player"
      value_template: >-
        {% set players =  expand('media_player.all_media_players') %}
        {% set last_played = players | selectattr('state', 'eq', 'playing') | sort(reverse=true, attribute='last_changed') | list %}
        {% set last_paused = players | selectattr('state', 'eq', 'paused') | sort(reverse=true, attribute='last_changed') | list %}
        {% if last_played |count > 0 -%}
          {%- set last_player = last_played[0] -%}
        {%- elif last_paused |count > 0 -%}
          {%- set last_player = last_paused[0] -%}
        {%- endif %}
        {%- if 'media_title' in last_player.attributes -%}
          {%- if 'Streaming from Music Assistant' in last_player.attributes.media_title -%}
            {%- set last_player = states['media_player.mass_' + last_player.object_id] -%}
          {%- endif %}
        {%- endif %}
        {{ 'media_player.' + last_player.object_id }}

Last step, the card itself:

type: custom:config-template-card
variables:
  LAST_PLAYER: states['sensor.last_active_media_player'].state
entities:
  - ${LAST_PLAYER}
card:
  type: custom:mini-media-player
  entity: ${LAST_PLAYER}
  artwork: full-cover
  hide:
    power: true
    icon: true
    source: true
    prev: true
    progress: true
    volume: true

End result:

image

3 Likes