This looks really cool. Did you plan on sharing your setup? I’d like to give it a run.
type: vertical-stack
cards:
- type: conditional
conditions:
- entity: sensor.plex_session_1_tautulli
state_not: unavailable
- entity: sensor.plex_session_1_tautulli
state_not: unknown
card:
type: vertical-stack
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
border-radius: var(--ha-card-border-radius, 12px);
border: none;
--ha-card-border-width: 0px !important;
overflow: hidden;
}
cards:
- type: custom:stack-in-card
card_mod:
style: |
ha-card {
box-shadow: var(--ha-card-box-shadow, none);
border: none;
--ha-card-border-width: 0px !important;
border-radius: var(--ha-card-border-radius, 12px);
overflow: hidden;
position: relative;
{% set art_url = state_attr('sensor.plex_session_1_tautulli', 'art_url') %}
{% if art_url and art_url != 'None' and art_url != '' %}
background: rgba(var(--card-background-color), 0.95);
{% else %}
background: var(--card-background-color);
{% endif %}
}
ha-card::before {
{% set art_url = state_attr('sensor.plex_session_1_tautulli', 'art_url') %}
{% if art_url and art_url != 'None' and art_url != '' %}
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('{{ art_url }}') center/cover;
filter: blur(20px) saturate(150%) brightness(0.3);
z-index: -1;
transform: scale(1.1);
{% endif %}
}
cards:
- type: custom:layout-card
layout_type: custom:grid-layout
layout:
grid-template-columns: 1fr 40px
gap: 12px
margin: 0px
padding: 12px
cards:
- type: custom:mushroom-template-card
entity: sensor.plex_session_1_tautulli
primary: >
{% if states('sensor.plex_session_1_tautulli') not in
['unavailable', 'unknown', 'none'] %}
{% set series = state_attr('sensor.plex_session_1_tautulli', 'grandparent_title') %}
{% set season = state_attr('sensor.plex_session_1_tautulli', 'parent_media_index') %}
{% set episode = state_attr('sensor.plex_session_1_tautulli', 'media_index') %}
{% set title = state_attr('sensor.plex_session_1_tautulli', 'title') %}
{% if series and season and episode %}
{{ series }} - S{{ season }}E{{ episode }}
{% elif title %}
{{ title }}
{% else %}
Active Plex Session
{% endif %}
{% else %}
No Active Session
{% endif %}
secondary: >
{% if states('sensor.plex_session_1_tautulli') not in
['unavailable', 'unknown', 'none'] %}
{% set user = state_attr('sensor.plex_session_1_tautulli', 'user_friendly_name') %}
{% set device = state_attr('sensor.plex_session_1_tautulli', 'device') %}
{% set progress = state_attr('sensor.plex_session_1_tautulli', 'progress_percent') %}
{% set remaining = state_attr('sensor.plex_session_1_tautulli', 'stream_remaining') %}
{% set transcode = state_attr('sensor.plex_session_1_tautulli', 'transcode_decision') %}
{% if user and device %}
{{ user }} • {{ device }}{% if progress %} • {{ progress }}%{% endif %}{% if remaining %} • {{ remaining }} left{% endif %}{% if transcode and transcode != 'direct play' %} • {{ transcode|title }}{% endif %}
{% else %}
Session data loading...
{% endif %}
{% else %}
Sensor unavailable
{% endif %}
icon: >
{% if states('sensor.plex_session_1_tautulli') not in
['unavailable', 'unknown', 'none'] %}
{% set media_type = state_attr('sensor.plex_session_1_tautulli', 'media_type') %}
{% if media_type == 'episode' %}
mdi:television-classic
{% elif media_type == 'movie' %}
mdi:movie-roll
{% else %}
mdi:plex
{% endif %}
{% else %}
mdi:plex
{% endif %}
icon_color: >
{% set transcode =
state_attr('sensor.plex_session_1_tautulli',
'transcode_decision') %} {% if transcode and transcode !=
'direct play' %}
red
{% else %}
orange
{% endif %}
tap_action:
action: more-info
entity: sensor.plex_session_1_tautulli
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: rgb(255, 255, 255) !important;
text-shadow: 0 1px 3px rgba(0,0,0,0.8);
font-weight: 600;
font-size: 16px;
white-space: normal !important;
overflow: visible !important;
text-overflow: clip !important;
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
font-size: 14px;
}
mushroom-shape-icon {
--icon-color: rgb(255, 193, 7) !important;
--shape-color: rgba(255, 193, 7, 0.3) !important;
}
- type: custom:mushroom-template-card
entity: input_boolean.plex_session_dropdown
primary: ""
secondary: ""
icon: >-
{% if is_state('input_boolean.plex_session_dropdown', 'on')
%}
mdi:chevron-up
{% else %}
mdi:chevron-down
{% endif %}
icon_color: disabled
tap_action:
action: toggle
entity: input_boolean.plex_session_dropdown
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
display: flex;
align-items: center;
justify-content: center;
min-height: 42px;
}
mushroom-shape-icon {
--shape-color: rgba(255, 255, 255, 0.1) !important;
--icon-color: rgba(255, 255, 255, 0.6) !important;
}
- type: conditional
conditions:
- entity: input_boolean.plex_session_dropdown
state: "on"
- entity: sensor.plex_session_1_tautulli
state_not: unavailable
- entity: sensor.plex_session_1_tautulli
state_not: unknown
card:
type: custom:stack-in-card
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
margin-top: 8px;
}
cards:
- type: custom:mushroom-template-card
primary: >
{% set progress =
state_attr('sensor.plex_session_1_tautulli',
'progress_percent') %} {% set duration =
state_attr('sensor.plex_session_1_tautulli', 'duration')
%} {% set remaining =
state_attr('sensor.plex_session_1_tautulli',
'stream_remaining') %} Progress: {{ progress or 0 }}% {%-
if duration %} • Duration: {{ duration }}{% endif %} {%-
if remaining %} • {{ remaining }} left{% endif %}
secondary: ""
icon: mdi:progress-clock
icon_color: orange
card_mod:
style: |
ha-card {
background: rgba(0,0,0,0.3);
border: none !important;
margin: 8px 0px 12px;
position: relative;
}
.primary { color: white !important; }
ha-card::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
height: 4px;
background: rgb(255, 193, 7);
width: {{ state_attr('sensor.plex_session_1_tautulli', 'progress_percent') or 0 }}%;
border-radius: 0 0 8px 8px;
}
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: >
{% set media_type =
state_attr('sensor.plex_session_1_tautulli',
'media_type') %} {% if media_type == 'episode' %}
Episode Title
{% elif media_type == 'movie' %}
Movie Title
{% else %}
Media Title
{% endif %}
secondary: >
{% set title =
state_attr('sensor.plex_session_1_tautulli', 'title')
%} {% if title %}
{{ title }}
{% else %}
{% set media_type = state_attr('sensor.plex_session_1_tautulli', 'media_type') %}
{% if media_type == 'episode' %}
No episode info
{% elif media_type == 'movie' %}
No movie info
{% else %}
No media info
{% endif %}
{% endif %}
icon: mdi:information
icon_color: blue
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
white-space: normal !important;
overflow: visible !important;
text-overflow: clip !important;
}
- type: custom:mushroom-template-card
primary: Quality & Transcode
secondary: >
{% set resolution =
state_attr('sensor.plex_session_1_tautulli',
'stream_video_resolution') %} {% set codec =
state_attr('sensor.plex_session_1_tautulli',
'stream_video_codec') %} {% set transcode =
state_attr('sensor.plex_session_1_tautulli',
'transcode_decision') %} {% if resolution or codec or
transcode %}
{{ resolution or 'Unknown' }}{% if codec %} • {{ codec|upper }}{% endif %}{% if transcode %} • {{ transcode|title }}{% endif %}
{% else %}
Quality info unavailable
{% endif %}
icon: >
{% set resolution =
state_attr('sensor.plex_session_1_tautulli',
'stream_video_resolution') %} {% set transcode =
state_attr('sensor.plex_session_1_tautulli',
'transcode_decision') %}
{% if resolution %}
{% if '4k' in resolution|lower or '2160' in resolution %}
mdi:video-4k-box
{% elif '1080' in resolution or '720' in resolution %}
mdi:high-definition-box
{% elif '480' in resolution %}
mdi:standard-definition
{% else %}
mdi:video
{% endif %}
{% elif transcode and transcode != 'direct play' %}
mdi:cogs
{% else %}
mdi:quality-high
{% endif %}
icon_color: >
{% set transcode =
state_attr('sensor.plex_session_1_tautulli',
'transcode_decision') %} {% if transcode and transcode
!= 'direct play' %}
red
{% else %}
green
{% endif %}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: Ratings & Content
secondary: >
{% set content_rating =
state_attr('sensor.plex_session_1_tautulli',
'content_rating') %} {% set audience_rating =
state_attr('sensor.plex_session_1_tautulli',
'audience_rating') %} {% if content_rating or
audience_rating %}
{% if content_rating %}{{ content_rating }}{% endif %}{% if content_rating and audience_rating %} • {% endif %}{% if audience_rating %}⭐ {{ audience_rating }}{% endif %}
{% else %}
No rating info
{% endif %}
icon: mdi:star-box
icon_color: yellow
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: custom:mushroom-template-card
primary: Video Dynamic Range
secondary: >
{% set video_dynamic_range =
state_attr('sensor.plex_session_1_tautulli',
'video_dynamic_range') %} {% if video_dynamic_range %}
{{ video_dynamic_range|upper }}
{% else %}
SDR
{% endif %}
icon: mdi:television-shimmer
icon_color: >
{% set video_dynamic_range =
state_attr('sensor.plex_session_1_tautulli',
'video_dynamic_range') %} {% if video_dynamic_range
and 'hdr' in video_dynamic_range|lower %}
purple
{% else %}
blue
{% endif %}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: Location
secondary: >
{% set location =
state_attr('sensor.plex_session_1_tautulli',
'location') %} {% set city =
state_attr('sensor.plex_session_1_tautulli',
'geo_city') %} {% set region =
state_attr('sensor.plex_session_1_tautulli',
'geo_region') %} {% if location or city or region %}
{{ (location|title) if location else 'Unknown' }}{% if city and region %} • {{ city }}, {{ region }}{% endif %}
{% else %}
Location unavailable
{% endif %}
icon: mdi:map-marker
icon_color: purple
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: custom:mushroom-template-card
primary: Bandwidth
secondary: >
{% set bandwidth =
state_attr('sensor.plex_session_1_tautulli',
'bandwidth') %} {% if bandwidth %}
{{ (bandwidth | float / 1000) | round(2) }} Mbps
{% else %}
Bandwidth unavailable
{% endif %}
icon: mdi:speedometer
icon_color: orange
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: custom:stack-in-card
cards:
- type: custom:mushroom-template-card
primary: ""
secondary: ""
icon: mdi:text
color: yellow
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
height: 48px !important;
margin-bottom: -10px !important;
}
- type: markdown
content: >
#### Summary {% set summary =
state_attr('sensor.plex_session_1_tautulli',
'summary') %} {% if summary %}
{{ summary }}
{% else %}
No summary available
{% endif %}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
margin-left: 27px !important;
margin-top: -45px !important;
padding-left: 12px !important;
}
ha-markdown {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
line-height: 1.4 !important;
}
ha-markdown h2 {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
font-size: 12px !important;
font-weight: 500 !important;
margin: 0 0 0px 0 !important;
}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
}
grid_options:
columns: 12
rows: auto
- type: horizontal-stack
cards:
- type: custom:mushroom-template-card
primary: Pause
icon: mdi:pause
icon_color: yellow
tap_action:
action: call-service
service: script.pause_plex_session
service_data:
session_id: >
{{ state_attr('sensor.plex_session_1_tautulli',
'session_id') }}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: custom:mushroom-template-card
primary: Stop
icon: mdi:stop
icon_color: red
tap_action:
action: call-service
service: script.stop_plex_session
service_data:
session_id: >
{{ state_attr('sensor.plex_session_1_tautulli',
'session_id') }}
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
- type: custom:mushroom-template-card
primary: More Info
icon: mdi:information-outline
icon_color: blue
tap_action:
action: more-info
entity: sensor.plex_session_1_tautulli
card_mod:
style: |
ha-card {
background: none !important;
box-shadow: none !important;
border: none !important;
--ha-card-border-width: 0px !important;
}
.primary {
color: white !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
.secondary {
color: rgba(255, 255, 255, 0.8) !important;
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
}
card_mod:
style: |
ha-card {
background: none;
box-shadow: none;
border-radius: var(--ha-card-border-radius, 12px);
border: none;
--ha-card-border-width: 0px !important;
overflow: hidden;
}
1 Like
I’m about to try it now. Is there any specific configuration that’s needed within these lines of code?
You need to create a helper for the dropdown but I think that is it
can someone help me get the progress bar working
type: custom:auto-entities
filter:
exclude:
- options: {}
state: unknown
- options: {}
state: unavailable
- options: {}
state: "off"
include:
- options:
entity: this.entity_id
type: custom:button-card
variables:
entity: this.entity_id
custom_fields:
picture:
card:
type: picture
image: |
[[[
if (states[variables.entity].attributes.grandparent_thumb != ''){
return "***********************************/api/v2?apikey=**************************cmd=pms_image_proxy&img=" + states[variables.entity].attributes.grandparent_thumb + "&width=300&height=450&fallback=poster&refresh=true";
} else {
if (states[variables.entity].attributes.thumb != ''){
return "*********************************/api/v2?apikey=*******************************************cmd=pms_image_proxy&img=" + states[variables.entity].attributes.thumb + "&width=300&height=450&fallback=poster&refresh=true"
} else {
return states['sensor.' + states[variables.entity].attributes.user + '_session_thumbnail'].state
}
}
]]]
card_mod:
style: |
ha-card {
box-shadow: 0;
border-radius: 0;
margin: 5px 0 0 -5px;
}
ha-card img {
min-height: 100px;
min-width: 100px;
}
bar:
card:
type: custom:bar-card
entities:
- entity: this.entity_id
attribute: progress_percent
unit_of_measurement: "%"
positions:
icon: "off"
indicator: "off"
name: inside
height: 19px
color: "#e49f29"
name: |
[[[
return states[variables.entity].state
]]]
card_mod:
style: |-
ha-card {
--ha-card-background: none;
border: none;
box-shadow: none;
}
ha-card #states {
padding: 0;
}
bar-card-currentbar, bar-card-backgroundbar {
border-radius: 5px;
left: 0;
}
bar-card-name {
margin-left: 3%;
text-shadow: 1px 1px 1px #0003;
}
bar-card-value {
margin-right: 3%;
text-shadow: 1px 1px 1px #0003;
}
user: |
[[[
return "<b>" + states[variables.entity].attributes.user + "</b>"
]]]
title: |
[[[
if (states[variables.entity].state == 'playing') {
return "<ha-icon icon='mdi:play' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> " + states[variables.entity].attributes.full_title;
} else {
if (states[variables.entity].state == 'paused') {
return "<ha-icon icon='mdi:pause' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> " + states[variables.entity].attributes.full_title;
} else {
return states[variables.entity].attributes.full_title;
}
}
]]]
stream_label: <b>Stream</b>
stream: |
[[[
return states[variables.entity].attributes.video_resolution + " > " + states[variables.entity].attributes.transcode_decision + " > " +states[variables.entity].attributes.stream_video_resolution + ""
]]]
product_label: <b>Product</b>
product: |
[[[
return states[variables.entity].attributes.product
]]]
player_label: <b>Player</b>
player: |
[[[
return states[variables.entity].attributes.player
]]]
location_label: <b>Location</b>
location: |
[[[
return states[variables.entity].attributes.location + ": " + states[variables.entity].attributes.ip_address
]]]
media_detail: |
[[[
if(states[variables.entity].attributes.media_type == 'movie') {
return "<ha-icon icon='mdi:filmstrip' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> (" + states[variables.entity].attributes.year + ")";
} else {
return "<ha-icon icon='mdi:television-classic' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> S" + states[variables.entity].attributes.parent_media_index + " • E" + states[variables.entity].attributes.media_index;
}
]]]
bandwidth_label: <b>Bandwidth</b>
bandwidth: |
[[[
var bytes = states[variables.entity].attributes.bandwidth * 1000;
var sizes = ['Bytes', 'Kbps', 'Mbps', 'Gbps', 'Tbps'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1000)));
if (i == 0) return bytes + ' ' + sizes[i];
return (bytes / Math.pow(1000, i)).toFixed(1) + ' ' + sizes[i];
]]]
card_mod:
style: |
ha-card {
box-shadow: 0;
padding: 0;
margin: 0;
border: 0;
}
ha-card #container {
margin: 5px 0 0 0;
}
#name {
display:none;
}
styles:
card:
- height: 100x
- padding: 0
custom_fields:
bar:
- text-transform: capitalize
- font-size: 13px
user:
- text-align: end
- font-size: 15px
title:
- text-align: start
- font-size: 13px
stream:
- text-transform: capitalize
- text-align: start
- font-size: 13px
product:
- text-transform: capitalize
- text-align: start
- font-size: 13px
player:
- text-transform: capitalize
- text-align: start
- font-size: 13px
location:
- text-transform: uppercase
- text-align: start
- font-size: 13px
media_detail:
- text-transform: uppercase
- text-align: start
- font-size: 13px
bandwidth:
- text-transform: capitalize
- text-align: start
- font-size: 13px
product_label:
- text-transform: uppercase
- text-align: end
- font-size: 10px
player_label:
- text-transform: uppercase
- text-align: end
- font-size: 10px
stream_label:
- text-transform: uppercase
- text-align: end
- font-size: 10px
location_label:
- text-transform: uppercase
- text-align: end
- font-size: 10px
bandwidth_label:
- text-transform: uppercase
- text-align: end
- font-size: 10px
grid:
- grid-template-areas: |
"picture product_label product"
"picture player_label player"
"picture stream_label stream"
"picture location_label location"
"picture bandwidth_label bandwidth"
"picture bar bar"
"picture title title"
"picture media_detail user"
- grid-template-columns: 1fr 60px 3fr
- grid-gap: 5px 10px
entity_id: "*plex*session*"
card:
type: vertical-stack
card_param: cards
grid_options:
columns: 12
rows: 4
visibility:
- condition: user
users:
- 42197d78403c4eee9926076c1f6ac517