Tautulli REST End Point and custom-button-card

Hmm the new doesn’t quite match what is in the first post? Looks like some single quotes are swapped for double quotes. Particularly, can you try switching the “off” in the exclude to ‘off’?

No it is the same thing, when I save with single quotes, it becomes dubble quotes automatically.

Weird, mine are single in the UI. I’ll take another look when I can. Probably in a few hours at the earliest.

Is what you posted above the full code for each card?

No, here is the full template of the old version:

And your newest version

All I have done is to remove the media cover because o got annoyed that the photo was always missing (due to HA remote link).

I just copy/pasted in your “new” gist straight into my dashboard, and it works fine for me. It’s only showing a single session.

I did a compare between your version and my gist, and aside from the single/double quotes thing, I see that you removed the picture like you said. I don’t see anything wrong with what you’ve done…

If you inspect the page, go to the console, and then refresh the page - it should print out what versions of custom components you have installed. Do you have the latest 1.13.0 auto-entities installed?

When I check in HACS, it says there thet I have the latest v1.13.0

Could it be some other setting that is enabled/disabled?

Edit: okey I found what I did wrong…

When I added the code to Auto-Entities card, I had this code in the front, before I added your code, in other words X2 of the code below.

    - type: custom:auto-entities
      filter:
        exclude:
          - state: unknown
          - state: unavailable
          - state: 'off'
        include:

After removing this, and the following at the bottom, it shows correctly.

I didn’t see this issue/error because the code editor hide the first “custom:auto-entities” so I never saw it untill I pressed manually “show code editor” then I saw it right away that something was off.

Need to see if another button card shows if I have another streamer, but for now it seems that it works as intended.

Thanks though for trying to help me with what could be the issue :slight_smile: really appreciate it!

Update: yep, works as intended, thank you for this great card that you’ve done :slight_smile:

1 Like

Hello,
i have updated the Sensor and the Dashboardcard with the transcode_hw label…

Here is the first template sensor as example…

template:
  - sensor:
      - unique_id: plex_session_1
        name: Plex Session 1 (Tautulli)
        icon: mdi:plex
        state: >
          {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1)%}{{ state_attr('sensor.tautulli_activity','sessions')[0].state }}{%else%}off{%endif %}
        attributes:
          user: > 
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].user }}{%endif%}
          progress_percent: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].progress_percent }}{%endif%}
          media_type: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].media_type }}{%endif%}
          full_title: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].full_title }}{%endif%}
          grandparent_thumb: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].grandparent_thumb }}{%endif%}
          thumb: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].thumb }}{%endif%}
          parent_media_index: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].parent_media_index }}{%endif%}
          media_index: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].media_index }}{%endif%}
          year: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].year }}{%endif%}
          product: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].product }}{%endif%}
          player: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].player }}{%endif%}
          device: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].device }}{%endif%}
          platform: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].platform }}{%endif%}
          location: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].location }}{%endif%}
          ip_address: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].ip_address }}{%endif%}
          ip_address_public: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].ip_address_public }}{%endif%}
          local: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].local }}{%endif%}
          relayed: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].relayed }}{%endif%}
          bandwidth: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].bandwidth }}{%endif%}
          video_resolution: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].video_resolution }}{%endif%}
          stream_video_resolution: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].stream_video_resolution }}{%endif%}
          transcode_decision: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].transcode_decision }}{%endif%}
          transcode_hw: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].transcode_hw_requested }}{%endif%}

and here is the code for the card…

type: custom:auto-entities
filter:
  exclude:
    - state: unknown
    - state: unavailable
    - state: 'off'
  include:
    - entity_id: '*plex*session*'
      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 "https://tautulli-URL/api/v2?apikey=xxx&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 "https://tautulli-URL/api/v2?apikey=xxx&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: >
            [[[

            let transcode_hw = states[variables.entity].attributes.transcode_hw;

            let transcode_hw_str = (transcode_hw == 1) ? " (HW)" : "";

            return states[variables.entity].attributes.video_resolution + " > "
            + 
                   states[variables.entity].attributes.transcode_decision + 
                   transcode_hw_str + " > " + 
                   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
card:
  type: vertical-stack
card_param: cards

Looks like this now

Bildschirmfoto 2024-09-04 um 23.10.14

Mit freundlichen Grüßen
Chris

1 Like

Hi - Can i get all the config on one post pls?

I almost got this going. Got the plexsession* entities showing up with the correct live info of what’s happening, but the card itself is where I can’t get it to work. I tried it in a popup window and in a lovelace dashboard but I get the same error. I got button Card, Bar Card and Auto entities Card installed.
What am I missing?


1 Like

You’re putting the entire config in the auto-entries card config.
Click “Show Code Editor” and paste it for the entire card.

1 Like

I’m not sure I understood you…
This is my code.

          # Original Auto-Entities Card for Plex Sessions
          - type: custom:auto-entities
            filter:
              exclude:
                - state: unknown
                - state: unavailable
                - state: "off"
              include:
                - entity_id: "*plex*session*"
                  options:
                    entity: this.entity_id
                    type: custom:button-card
                    variables:
                      entity: this.entity_id
                    custom_fields:
                      picture:
                        card:
                          type: picture
                          image: |
                            [[[
                              const grandparent = state_attr(variables.entity, 'grandparent_thumb');
                              const thumb = state_attr(variables.entity, 'thumb');
                              const user = state_attr(variables.entity, 'user');
                              
                              if (grandparent && grandparent !== '') {
                                return "http://192.168.1.33:8181/api/v2?apikey=6aefba7e4dd2441eacac813232478892&cmd=pms_image_proxy&img=" + grandparent + "&amp;width=300&amp;height=450&amp;fallback=poster&amp;refresh=true";
                              } else if (thumb && thumb !== '') {
                                return "http://192.168.1.33:8181/api/v2?apikey=6aefba7e4dd2441eacac813232478892&cmd=pms_image_proxy&img=" + thumb + "&amp;width=300&amp;height=450&amp;fallback=poster&amp;refresh=true"                    
                              } else if (user) {
                                return states('sensor.' + user + '_session_thumbnail')
                              }
                              return null;
                            ]]]
                          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)
                            ]]]
                          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: |
                        [[[
                          const user = state_attr(variables.entity, 'user');
                          return user ? "<b>" + user + "</b>" : "";
                        ]]]
                      title: |
                        [[[
                          const state = states(variables.entity);
                          const title = state_attr(variables.entity, 'full_title') || '';
                          
                          if (state === 'playing') {
                            return "<ha-icon icon='mdi:play' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> " + title;
                          } else if (state === 'paused') {
                            return "<ha-icon icon='mdi:pause' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> " + title;
                          }
                          return title;
                        ]]]
                      stream: |
                        [[[
                          const resolution = state_attr(variables.entity, 'video_resolution') || '';
                          const decision = state_attr(variables.entity, 'transcode_decision') || '';
                          const streamRes = state_attr(variables.entity, 'stream_video_resolution') || '';
                          return resolution + " > " + decision + " > " + streamRes;
                        ]]]
                      product: |
                        [[[
                          return state_attr(variables.entity, 'product') || '';
                        ]]]
                      player: |
                        [[[
                          return state_attr(variables.entity, 'player') || '';
                        ]]]
                      location: |
                        [[[
                          const location = state_attr(variables.entity, 'location') || '';
                          const ip = state_attr(variables.entity, 'ip_address') || '';
                          return location + ": " + ip;
                        ]]]
                      media_detail: |
                        [[[
                          const mediaType = state_attr(variables.entity, 'media_type');
                          if(mediaType === 'movie') {
                            const year = state_attr(variables.entity, 'year');
                            return "<ha-icon icon='mdi:filmstrip' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> (" + year + ")";
                          } else {
                            const season = state_attr(variables.entity, 'parent_media_index');
                            const episode = state_attr(variables.entity, 'media_index');
                            return "<ha-icon icon='mdi:television-classic' style='width: 15px; height: 15px; position: relative; top: -2px;'></ha-icon> S" + season + " • E" + episode;
                          }
                        ]]]
                      bandwidth: |
                        [[[
                          const bandwidth = state_attr(variables.entity, 'bandwidth');
                          if (!bandwidth) return 'n/a';
                          
                          const bytes = bandwidth * 1000;
                          const sizes = ['Bytes', 'Kbps', 'Mbps', 'Gbps', 'Tbps'];
                          if (bytes === 0) return 'n/a';
                          const 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
            card_mod:
              style: |
                ha-card {
                  border: none;
                  margin-top: 10px;
                }

Same issue here too. I would love to get this working. Is there a summarize step by step to implement this?

Does the template config go into the configuration.yml ?

When I add the template config to my configuration.yml , I get this check checking with developer tools:

Configuration warnings
Invalid config for 'template' from integration 'sensor' at configuration.yaml, line 268: required key 'sensors' not provided
Invalid config for 'sensor' at configuration.yaml, line 269: required key 'platform' not provided

Yes. Mines looks like this in configuration.yaml…

# Plex/Tautulli Sessions
sensor:
  - platform: rest
    unique_id: tautulli_activity
    name: Tautulli Activity
    icon: mdi:plex
    scan_interval: 5
    force_update: true
    resource: "URL TO TAUTULLI"/api/v2?apikey="API KEY"&cmd=get_activity
    method: POST
    headers:
      Content-Type: application/json
    value_template: "{{ value_json.response.result }}"
    json_attributes_path: "$.response.data"
    json_attributes:
      - stream_count
      - sessions
      - stream_count_direct_play
      - stream_count_direct_stream
      - stream_count_transcode
      - total_bandwidth
      - lan_bandwidth
      - wan_bandwidth

template:
  - sensor:
      - unique_id: plex_session_1
        name: Plex Session 1 (Tautulli)
        icon: mdi:plex
        state: >
          {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1)%}{{ state_attr('sensor.tautulli_activity','sessions')[0].state }}{%else%}off{%endif %}
        attributes:
          user: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].user }}{%endif%}
          progress_percent: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].progress_percent }}{%endif%}
          media_type: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].media_type }}{%endif%}
          full_title: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].full_title }}{%endif%}
          grandparent_thumb: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].grandparent_thumb }}{%endif%}
          thumb: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].thumb }}{%endif%}
          parent_media_index: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].parent_media_index }}{%endif%}
          media_index: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].media_index }}{%endif%}
          year: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].year }}{%endif%}
          product: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].product }}{%endif%}
          player: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].player }}{%endif%}
          device: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].device }}{%endif%}
          platform: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].platform }}{%endif%}
          location: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].location }}{%endif%}
          ip_address: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].ip_address }}{%endif%}
          ip_address_public: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].ip_address_public }}{%endif%}
          local: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].local }}{%endif%}
          relayed: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].relayed }}{%endif%}
          bandwidth: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].bandwidth }}{%endif%}
          video_resolution: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].video_resolution }}{%endif%}
          stream_video_resolution: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].stream_video_resolution }}{%endif%}
          transcode_decision: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].transcode_decision }}{%endif%}
          transcode_hw: >
            {% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].transcode_hw_requested }}{%endif%}

Then of course you compound on the template all the way to Plex Session 10…

1 Like

When I paste in your code to my configuration.yml, I get this error:

2024-12-07 05:28:34.167 ERROR (MainThread) [homeassistant.config] Invalid config for 'template' at configuration.yaml, line 293: 'name' is an invalid option for 'template', check: name
Invalid config for 'template' at configuration.yaml, line 294: 'icon' is an invalid option for 'template', check: icon
Invalid config for 'template' at configuration.yaml, line 295: 'state' is an invalid option for 'template', check: state
Invalid config for 'template' at configuration.yaml, line 297: 'attributes' is an invalid option for 'template', check: attributes

When I changed these lines to:

  - platform: template
  - sensor:

I then get this error:

Invalid config for 'template' from integration 'sensor' at configuration.yaml, line 291: required key 'sensors' not provided
Invalid config for 'sensor' at configuration.yaml, line 292: required key 'platform' not provided 

I then tried this:


  - platform: template
    sensors:
      - unique_id: plex_session_1
        name: Plex Session 1 (Tautulli)
        icon: mdi:plex 

But this resulted in error:

Configuration warnings
Invalid config for 'template' from integration 'sensor' at configuration.yaml, line 292: expected dictionary for dictionary value 'sensors', got [{'unique_id': 'plex_session_1', 'name': 'Plex Session 1 (Tautulli)', 'icon': 'mdi:plex', 'state': "{% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1)%}{{ state_attr('sensor.tautulli_activity','sessions')[0].state }}{%else%}off{%endif %}\n", 'attributes': {'user': "{% if (state_attr('sensor.tautulli_activity','sessions')|length >= 1) and (this.state !='off')%}{{ state_attr('sensor.tautulli_activity','sessions')[0].user }}{%endif%}\n", 'progress_percent': "{% if (state_attr(... 

I appear to struggle with understanding how to add templates in the configuration.yml

Please help :sob:

After messing around with the configuration.yaml and getting help from @ColtonYYZ , I finally got it working. Now I just have to figure out why the pictures aren’t showing.

Thank you for this!
I’m just trying figure out why images of the movies / shows are not showing…

If you’re not seeing images for either, you have to update the link to Tautulli in both the configuration yaml and where you have the actual entity on your dashboard.

In the configuration yaml it’ll be right after “resource” where the Tautulli url and api key from Tautulli will go.

Update what exactly?

Do I have to hard code the Tautulli url in the card code as well?

if (states[variables.entity].attributes.grandparent_thumb != ''){
            return "https://tautulli-URL/api/v2?apikey=xxx&cmd=pms_image_proxy&img=" + states[variables.entity].attributes.grandparent_thumb + "&amp;width=300&amp;height=450&amp;fallback=poster&amp;refresh=true";
          } else {
            if (states[variables.entity].attributes.thumb != ''){
              return "https://tautulli-URL/api/v2?apikey=xxx&cmd=pms_image_proxy&img=" + states[variables.entity].attributes.thumb + "&amp;width=300&amp;height=450&amp;fallback=poster&amp;refresh=true"                    
            } else

I re-read the first post and found this:

Replace the server ip/domain/port/api key values in the card below where it resembles: http://[TAUTULLI SERVER:PORT]/api/v2?apikey=[YOUR API KEY HERE]

I will update my card code with the actual Tautulli URL like I have in my configuration.yml

********UPDATE : that did the trick! :grin:
Thank you all for guidance.

1 Like

Can someone ELI5 how to link plex_sessions.yaml in the configuration.yml file? Probably would be a good idea to post step by step instructions for the whole thing as well.

1 Like