A different take on designing a Lovelace UI

Yeah need to make a step by step will do. Maybe somone else can show me quicker ways once I do becuase …I know I took the long way :slight_smile:

Hello everyone, I have been following the tutorial step by step, and I have always been unable to display the cover of plex, and other entities cannot display it on plex’s card when playing videos. I hope that some of the code can be shared by the big shots so that I can refer to and modify it. Thank you, here are some of my code, and I don’t know which yaml I still need to configure.

configuration.yaml

sensor:
- platform: plex_recently_added
  token: MaHb4Vrb3nttW-kfqAY_
  host: 192.168.50.254
  port: 32400

ui-lovelace.yaml

      #################################################
      #                                               #
      #                     MEDIA                     #
      #                                               #
      #################################################

      - type: grid
        title: Media
        view_layout:
          grid-area: media
        columns: 1
        cards:

          - type: custom:swipe-card
            parameters:
              speed: 550
              spaceBetween: 40
              threshold: 5
            cards:

              - type: horizontal-stack
                cards:

                  - type: conditional
                    conditions:
                      - entity: select.conditional_media
                        state_not: Plex Movies (Offline)

                      - entity: select.conditional_media
                        state_not: jellyfin

                      - entity: select.conditional_media
                        state_not: emby

                      - entity: select.conditional_media
                        state_not: google
                    card:
                      type: custom:button-card
                      entity: sensor.plex_recently_added
                      name: Plex Movies
                      tap_action:
                        action: none
                      template:
                        - conditional_media
                        - icon_plex
                        

                  - type: conditional
                    conditions:
                      - entity: select.conditional_media
                        state: jellyfin
                    card:
                      type: custom:button-card
                      entity: media_player.plex_plex_web_chrome_osx
                      name: Plex Movies (Offline)
                      template:
                        - conditional_media
                        - icon_jellyfin

                  - type: conditional
                    conditions:
                      - entity: select.conditional_media
                        state: jellyfin
                    card:
                      type: custom:button-card
                      entity: media_player.chrome
                      triggers_update: sensor.youtube_watching
                      template:
                        - conditional_media
                        - icon_plex

                  - type: conditional
                    conditions:
                      - entity: select.conditional_media
                        state: emby
                    card:
                      type: custom:button-card
                      entity: media_player.emby_chrome_macos_2
                      template:
                        - conditional_media
                        - icon_emby

                  - type: conditional
                    conditions:
                      - entity: select.conditional_media
                        state: google
                    card:
                      type: custom:button-card
                      entity: media_player.chromecast
                      template:
                        - conditional_media
                        - icon_google

              - type: grid
                columns: 2
                cards:

                  - type: custom:button-card
                    entity: media_player.plex_plex_web_chrome_osx_2
                    triggers_update: sensor.youtube_watching
                    name: plex
                    template:
                      - media
                      - icon_plex2

                  - type: custom:button-card
                    entity: media_player.chromecast
                    triggers_update: sensor.youtube_watching
                    name: google
                    template:
                      - media
                      - icon_google

                  - type: custom:button-card
                    entity: media_player.emby_chrome_macos_2
                    name: emby
                    template:
                      - media
                      - icon_emby

                  - type: custom:button-card
                    entity: media_player.chrome
                    name: jellyfin
                    template:
                      - media
                      - icon_jellyfin


sensor.yaml

template:
  select:
    - name: conditional_media
      state: >
        {% set recently_added = 'Plex Movies' %}
        {% set recently_added_backup = 'Plex Movies (Offline)' %}
        {% set paused_timeout_minutes = 15 %}
        {% set media_players = [
          states.media_player.chrome,
          states.media_player.plex_plex_web_chrome_osx,
          states.media_player.emby_chrome_macos_2,
          states.media_player.chromecast ] %}
        
        {% macro media(state) %}
        {% set state = media_players | selectattr('state','eq',state) | list %}
        {% set last_changed = recently_added if state | length == 0 else state | map(attribute='last_changed') | list | max %}
          {{ state | selectattr('last_changed','eq', last_changed) | map(attribute='name') | list | join }}
        {% endmacro %}

        {% set recently_added = recently_added_backup if is_state('media_player.plex_plex_web_chrome_osx','Active') else recently_added %}
        
        {% set playing = media_players | selectattr('state','eq','playing') | list %}
        {% set timeout_playing = False if playing | length == 0 else
          (as_timestamp(now()) - as_timestamp(playing | map(attribute='last_changed') | list | max)) < paused_timeout_minutes * 60 %}
        
        {% set paused = media_players | selectattr('state','eq','paused') | list %}
        {% set timeout_paused = False if paused | length == 0 else
          (as_timestamp(now()) - as_timestamp(paused | map(attribute='last_changed') | list | max)) < paused_timeout_minutes * 60 %}
        
        {% if playing %}
          {{ media('playing') if timeout_playing else media('paused') if timeout_paused else media('playing') }}
        {% elif paused %}
          {{ media('paused') if timeout_paused else recently_added }}
        {% else %}
          {{ recently_added }}
        {% endif %}
      options: >
        {% set recently_added = ['Plex Movies'] %}
        {% set recently_added_backup = ['Plex Movies (Offline)'] %}
        {% set media_players = [
          states.media_player.chrome,
          states.media_player.plex_plex_web_chrome_osx,
          states.media_player.emby_chrome_macos_2,
          states.media_player.chromecast ] %}
        {{ recently_added + recently_added_backup + media_players | map(attribute='name') | list }}
      select_option:
        service: select.select_option
        target:
          entity_id: select.conditional_media
        data:
          option: >
            {{ option }}


  sensor:
  
    # SENSOR - PLEX RECENTLY ADDED (BACKUP)
    - unique_id: recently_added_backup
      name: 'Plex Movies (Offline)'
      state: >
        {% if not is_state('sensor.recently_added_movies', 'Online') %}
          Active
        {% else %}
          Passive
        {# Waiting for 'Plex Movies' to fail #}
        {% endif %}
      attributes:
        data: >
          {% if this.state not in ['unavailable','undefined','unknown','none','null','0'] %}
            {% set data = states('input_text.backup_recently_added_movies') %}
            {% set return = namespace(state=[]) %}
            {% set items = data.split("|") %}
            {% for item in items %}
              {% set object = item.split(":") %}
              {% set return.state = return.state + [{object[0]:object[1]}] %}
            {% endfor %}
            {{ return.state }}
          {% endif %}
        title: >
          {% if this.state not in ['unavailable','undefined','unknown','none','null','0'] %}
            {% set data = this.attributes.data %}
            {% set year = data[0].aired.split('-')[0] %}
            {% if data | count == 4 %}
              {% set title = data[1].title + ' (' + year + ')' %}
            {% else %}
              {% set title = data[1].title + ' · ' + data[2].number %}
            {% endif %}
            {{ title }}
          {% endif %}
        poster: >
          {% if this.state not in ['unavailable','undefined','unknown','none','null','0'] %}
            {% set data = this.attributes.data %}
            {% if data | count == 4 %}
              {% set poster = data[3].poster %}
            {% else %}
              {% set poster = data[4].poster %}
            {% endif %}
            {{ poster }}
          {% endif %}
        fanart: >
          {% if this.state not in ['unavailable','undefined','unknown','none','null','0'] %}
            {% set data = this.attributes.data %}
            {% if data | count == 4 %}
              {% set fanart = data[2].fanart %}
            {% else %}
              {% set fanart = data[3].fanart %}
            {% endif %}
            {{ fanart }}
          {% endif %}

automations.yaml

- id: '1675415708652'
  alias: System - Plex Recently Added
  description: Sensor attribute backup
  trigger:
  - platform: state
    entity_id:
    - sensor.plex_recently_added
    to: Online
  condition:
  - condition: template
    value_template: '{{ trigger.to_state.state not in [trigger.from_state.state, ''cannot
      be reached'', ''unavailable'', ''undefined'',''unknown'',''none'',''null'']
      }}'
  action:
  - service: input_text.set_value
    data:
      value: "{% if not states('sensor.plex_recently_added') in ['unavailable','undefined','unknown','none','null','0']
        %}\n  {% set state = namespace(return='') %}\n  {% set data = state_attr('sensor.plex_recently_added','data')
        %}\n  {%- for value in data %}\n    {%- if not loop.first and value is defined
        and state.return == '' %}\n      {%- if not value.number is defined %}\n        {%
        set state.return = \n          \"aired:\" + value.aired + \"|\" +\n          \"title:\"
        + value.title  + \"|\" +\n          \"fanart:\" + value.fanart + \"|\" +\n
        \         \"poster:\" + value.poster\n        %}\n      {%- else %}\n        {%
        set state.return = \n          \"aired:\" + value.aired + \"|\" +\n          \"title:\"
        + value.title  + \"|\" +\n          \"number:\" + value.number  + \"|\" +\n
        \         \"fanart:\" + value.fanart + \"|\" +\n          \"poster:\" + value.poster\n
        \       %}\n      {%- endif %}\n    {%- endif %}\n  {%- endfor %}\n  {{ state.return
        }}\n{% endif %}"
    target:
      entity_id: input_text.backup_plex_recently_added
  mode: single

“Currently, I have only modified the code in these three yaml files, but it has not worked. I have been struggling for this for several days. Please help me, thank you.”

Hi there, @zs2766.

I can start by pointing out some things:

The conditional_media select sensor looks incorrect:

{% set recently_added = recently_added_backup if is_state('media_player.plex_plex_web_chrome_osx','Active') else recently_added %}

This should check the state of a different sensor, like this:

{% set recently_added = recently_added_backup if is_state('sensor.recently_added_offline','Active') else recently_added %}

There are some other things missing in your post, I think. Please read this.

1 Like

Looks nice! Can u share the code? I and others could use it for hue lights.

Thank you very much for your answer. Currently, I have only modified these few items, and I don’t know how to modify the rest. I can’t find the relevant tutorials. Can you help me?

Well, I just pointed you to the tutorial I made for this.
Have you read it? (A different take on designing a Lovelace UI - #4536 by Laffer)

What you are trying to achieve is a modification of what Mattias made.
This includes a backup solution that I made for when the “Plex Recently Added” sensor fails.

Thank you. I will follow your tutorial and try it later. If it is still not available, I can send the file to you. Can you help me take a look at it? “If I need those files to send you, I hope you can list the names. Thank you.”

“I followed your tutorial and did it again, but it didn’t take effect. It’s still the same problem as before. Please help me, thank you.”

Send me screenshots and code from all the components mentioned in the tutorial and we’ll see if we can figure it out.

2 Likes

Okay, thank you very much. Here are some of my configuration files. If you need a complete config file, I can send it to you

Good. Now also please send me a screenshot of the following - from Developer Tools

input_text

backup template sensor

Okay, it looks like it’s not working

Have you tried to run the automation manually once?

Okay, I’ve run it manually once, but it still doesn’t work


In Developer Tools → Template, what result do you get if you try this: (change the sensor name to your Plex Movies / Recently Added)

{{ states(‘sensor.recently_added_mix’) }}

This MUST be = Online (At least once - when you run the automation)
If this is anything but Online, restart HA until this equals Online.

Okay, it shows online status

Do the same with the following, and see if it returns the data

{{ state_attr(‘sensor.recently_added_mix’,‘data’) }}

Okay, it doesn’t seem to have any content

Then I think you might need to have a look at that first.

If it doesn’t have any data in Developer Tools either, check to see if this sensor is set up correctly.
(and I assume your Plex server actually has content for this sensor to fetch)

Yes, my comparison with yours is completely different after checking. I have filled in a token for plex according to the recently added entity tutorial for plex. You can view the file I posted on GitHub. Please help me confirm if my token is incorrect. Thank you