A different take on designing a Lovelace UI

Oh, sorry, and thank you :blush:

Thanks for sharing, works like a charm. One Question…what for a font are you using. Looks amazing. Thx Dirk

Thanks, the font is one of my more recent favorites, Poppins.

Many thanks will have a try

Maybe off-topic, but how did you create the sensor.ps5_activity

It’s a fairly recent integration

1 Like

Trying to set up for the first time. My current lovelace config is as below. Am I able to add in this somehow without removing the mode:storage that I use for my other dashboards?

lovelace:
  mode: storage
  # Add yaml dashboards
  dashboards:
    minimalist-mobile:
      mode: yaml
      title: Mobile Dashboard
      icon: mdi:cellphone-text
      show_in_sidebar: true
      filename: ui_lovelace_minimalist/dashboard/minimalist-mobile.yaml
    minimalist-test:
      mode: yaml
      title: Test Dashboard
      icon: mdi:tablet-dashboard
      show_in_sidebar: true
      filename: ui_lovelace_minimalist/dashboard/test.yaml

You can use this dashboard in storage mode, however you will need to change some things here and there to get everything up and running. I have also done it that way until I ultimately decided to just stick with this one dashboard

1 Like

Don’t suppose you can elaborate a little more on that one? Would be greatly appreciated!

you add this one exactly the same how you have the other 2

1 Like

good morning and congratulations for the really nice progress bar, perfectly integrated, I’m trying it with spotify, it works but I find that the bar doesn’t respect the tempo of the song, it completes in the middle of the song, can you give me a hint of how I could solve this?

Sure, can you show me the available attributes while a song is playing?

Yeah that isn’t working

This worked for me

template: !include sidebar.yaml
lovelace:
  mode: storage
  # Add yaml dashboards
  dashboards:
    lovelace-yaml:
      mode: yaml
      title: YAML
      icon: mdi:script
      show_in_sidebar: true
      filename: dashboard.yaml
1 Like

Thanks!! I am guessing you added the resouces to the actual dashboard.yaml file then?

Also, how do you handle the template: !include sidebar.yaml part? It will error mine as I have template: !include template.yaml in my config already…

First of all: big fan of this dashboard! One thing I notice me and my partner doing is leaving the popups open. Is there an easy way to automatically close/hide the different popups after X seconds?

add timeout: in milliseconds under

tap_action:
  browser_mod:
    data:

I think the resources are loaded from UI mode when using the storage mode. Regarding the sidebar, you could also move the file under your packages or another include. It’s basically only a sensor.

Unfortunately I do not remember the exact way I had this setup, so sorry for that

1 Like

sure here they are

I suspect what is happening is that media_position is being updated more frequently than what media_position_updated_at is reporting.

You could test this a couple ways. First, refresh that view, and see if media_position is updated and media_position_updated_at stays the same while a song is playing.

Second, wait until the progress bar is near 100%, but the song is only halfway through, and then pause it. Does the progress bar change to the proper position?

Edit: Curiosity got the better of me and I signed up for a trial spotify account. The issue here is exactly what I had guessed. media_position is updated every 30 seconds while media_position_updated_at is not updated. From what I understand this is a bug in the spotify integration. I opened a github issue for it, but in the meantime, the best we can do is use the paused progress bar calculation media_position / media_duration * 100 for spotify. However, that means the progress bar is only updated every 30 seconds, which kind of sucks, but I guess it’s better than being wrong.

I only tested briefly, but this should work for progress_bar.yaml

progress_bar:
  styles:
    custom_fields:
      progress:
        - background-color: var(--progress-bar-background-color)
        - position: absolute
        - left: 0%
        - top: 73.4%
        - height: var(--progress-bar-height)
        - width: 100%
      bar:
        - background-color: var(--progress-bar-color)
        - position: absolute
        - left: 0%
        - top: 73.4%
        - height: var(--progress-bar-height)
        - z-index: 1
        - transition: 1s ease-out
  custom_fields:
    bar: >
      [[[
        if (entity.attributes.media_position !== undefined) {
        setTimeout(() => {
          let elt = this.shadowRoot,
              card = elt.getElementById('card'),
              container = elt.getElementById('container'),
              bar = elt.getElementById('bar');
        
          if (elt && card && container && bar) {
              card.insertBefore(bar, container);
                function update() {
                  let mediaPositionUpdatedAt = entity.attributes.media_position_updated_at,
                      mediaPosition = entity.attributes.media_position,
                      mediaDuration = entity.attributes.media_duration,
                      mediaContentID = entity.attributes.media_content_id;

                  let percentage = entity.state === 'paused' || (typeof mediaContentID === 'string' && mediaContentID.includes('spotify'))
                    ? (mediaPosition / mediaDuration * 100)
                    : entity.state === 'playing'
                      ? (((Date.now() / 1000) - (new Date(mediaPositionUpdatedAt).getTime() / 1000) + mediaPosition) / mediaDuration * 100)
                      : 0;

                  bar.style.width = percentage.toFixed(1) + '%';
                  requestAnimationFrame(update);
                }
                requestAnimationFrame(update);
          }
        }, 0);
        return ' ';}
      ]]]
    progress: >
      [[[
        if (entity.attributes.media_position !== undefined) {
        setTimeout(() => {
            let elt = this.shadowRoot,
                card = elt.getElementById('card'),
                container = elt.getElementById('container'),
                progress = elt.getElementById('progress');

            if (elt && card && container && progress) {
                card.insertBefore(progress, container);
            }
          }, 0);
        return ' ';}
      ]]]