A different take on designing a Lovelace UI

I already have a new icon, but only with a simple animation. I hope you like it.
CleanShot 2023-10-22 at 15.46.09

icon_shower:
  styles:
    custom_fields:
      icon:
        - filter: >
            [[[ return variables.state_on
                  ? 'drop-shadow(2px 1px 5px black)'
                  : 'grayscale(1) brightness(0.7)';
            ]]]
        - margin-top: -10%
        - width: 95%
  custom_fields:
    icon: >
      [[[
        let state = variables.state_on && variables.timeout < 50000 ? 'on' : null;
      return `
        <svg viewBox="-23.04 -23.04 174.08 174.08" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" class="iconify iconify--noto" transform="scale(-1 1)" stroke="#000" stroke-width=".001">
          <style>
            @keyframes on {
              0%,
              100% {
                transform: rotate(0deg);
                transform-origin: top;
              }
              10% {
                transform: rotate(2deg);
              }
              20%,
              40%,
              60% {
                transform: rotate(-4deg);
              }
              30%,
              50%,
              70% {
                transform: rotate(4deg);
              }
              80% {
                transform: rotate(-2deg);
              }
              90% {
                transform: rotate(2deg);
              }
            }
            .on {
              animation: on 2s linear both infinite;
            }
          </style>
          <rect x="-23.04" y="-23.04" width="174.08" height="174.08" rx="87.04" fill="#f0f0f0" opacity="0.05" stroke="none"/>
          <g stroke-linecap="round" stroke-linejoin="round" stroke="#CCC" stroke-width=".256"/>
          <path d="M100.87 15.07 87.94 27.95l10.11 10.11 13.03-13.04c3.64-3.64 7.98-6.12 12.92-7.22V4.67c-8.78.47-16.88 4.16-23.13 10.4z" fill="#bdbdbd"/>
          <path d="M96.59 30.45c-14.37-14.37-37.92-14.13-52.07-.18l52.25 52.25c13.95-14.15 14.19-37.7-.18-52.07z" fill="#bdbdbd"/>
          <path d="M107.74 28.62c-.21-.79-1.84-3.67-4.07-5.83s-4.75-3.72-6.94-4.17c-4.35-.9-6.82 2.28-9.57 5.03 3.41 1.7 6.6 3.96 9.43 6.8 2.45 2.45 4.47 5.18 6.08 8.08-.13-.23 4.03-4.03 4.03-4.03 1.48-1.5 1.6-3.8 1.04-5.88z" fill="#78909c"/>
          <path d="M96.59 30.45c-14.37-14.37-37.92-14.13-52.07-.18l52.25 52.25c13.95-14.15 14.19-37.7-.18-52.07z" fill="#bdbdbd"/>
          <path d="M83.74 41.83C67.75 27.39 53.9 23.61 53.9 23.61c-1.07.44-1.97.86-2.78 1.31 0 0 11.13 4.66 28.22 20.36s24 28.51 24 28.51c.53-1.08.99-2.28 1.45-3.7-.01 0-2.1-11.14-21.05-28.26z" fill="#9e9e9e"/>
          <path d="M81.17 44.73c17.59 16.13 28.11 32.83 24.01 37.75-2.9 3.48-6.52 3.2-6.52 3.2-7.77-1.84-20.51-12.25-33.16-23.85-12.87-11.8-26.09-27.08-26.71-29.7 0 0-.79-2.69-.09-4.63.88-2.43 2.79-3.42 2.79-3.42 6.74-3.68 22.09 4.52 39.68 20.65z" fill="#bdbdbd"/>
          <ellipse transform="rotate(-47.48 69.275 57.34)" cx="69.27" cy="57.34" rx="7.05" ry="41.25" fill="#757575"/>
          <path d="M68.13 22.25c-.97.39-1.85 1.25-1.9 2.29-.06 1.29 1.98 2.63 4.39 2.21 3.91-.69 7.16-.55 8.21-.37.56.1 2.62.1 2.62-1.19 0-1.32-2.05-2.19-2.58-2.4-3-1.19-7.52-1.82-10.74-.54zm-19.19 4.31c-.34 1.54 2.71 2.53 3.39 2.73 1.41.43 5.26 1.84 5.9 1.32.45-.37.53-1.44-3.52-3.7-3.21-1.8-5.44-1.81-5.77-.35z" fill="#dfecf5"/>
        <g id="water" class="${state}">
          <radialGradient id="a" cx="79.276" cy="48.098" r="123.225" gradientTransform="matrix(-.7157 .6984 -.1115 -.1142 141.374 -1.776)" gradientUnits="userSpaceOnUse">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </radialGradient>
          <path d="M6.71 120.14c-2.09-2.09-1.68-7.4.66-9.49l58.66-52.79a2.71 2.71 0 0 1 3.79 0 2.701 2.701 0 0 1 .04 3.82l-54.26 57.4c-2.47 2.6-6.8 3.16-8.89 1.06z" fill="url(#a)"/>
          <linearGradient id="b" gradientUnits="userSpaceOnUse" x1="69.927" y1="58.047" x2="22.517" y2="111.451">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </linearGradient>
          <path d="M70.27 58.5c-31.63 27.37-54.62 58.91-55.28 61.14 0 0 .56-.52.59-.56l54.26-57.4c.86-.87.99-2.16.43-3.18z" fill="url(#b)"/>
          <radialGradient id="c" cx="61.263" cy="35.447" r="94.412" gradientTransform="matrix(-.7902 .6129 -.0978 -.1261 118.085 7.166)" gradientUnits="userSpaceOnUse">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </radialGradient>
          <path d="m9.41 77.98 44.76-31.47c1.17-.9 2.84-.7 3.76.45.93 1.16.74 2.86-.42 3.8L13 87.76c-2.9 2.41-6.26 3.28-8.4-.51-2.19-3.85 2.21-7.44 4.81-9.27z" fill="url(#c)"/>
          <linearGradient id="d" gradientUnits="userSpaceOnUse" x1="53.324" y1="44.822" x2="14.231" y2="87.377" gradientTransform="rotate(6.88 23.825 79.01)">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </linearGradient>
          <path d="M58.31 47.65c-.19-.04-34.81 23.68-46.16 40.8L57.5 50.76c.96-.76 1.24-2.03.81-3.11z" fill="url(#d)"/>
          <radialGradient id="e" cx="43.953" cy="24.996" r="70.073" gradientTransform="matrix(-.8551 .5185 -.0827 -.1365 93.478 13.157)" gradientUnits="userSpaceOnUse">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </radialGradient>
          <path d="M5.09 62.38C3.09 58 7.7 55.9 7.7 55.9l35.55-19.75c1.25-.77 2.9-.4 3.69.85a2.7 2.7 0 0 1-.82 3.73L12.1 63.39s-4.84 3.75-7.01-1.01z" fill="url(#e)"/>
          <linearGradient id="f" gradientUnits="userSpaceOnUse" x1="38.337" y1="32.629" x2="9.822" y2="63.669" gradientTransform="rotate(12.933 15.624 72.315)">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </linearGradient>
          <path d="M47.25 37.72c-.19-.06-18.51 9.7-36.37 26.41l35.23-23.4a2.71 2.71 0 0 0 1.14-3.01z" fill="url(#f)"/>
          <radialGradient id="g" cx="100.706" cy="64.392" r="97.119" gradientTransform="matrix(-.6174 .7867 .1255 .0985 141.612 -26.248)" gradientUnits="userSpaceOnUse">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </radialGradient>
          <path d="m48.38 117.92 32.7-46.36c.9-1.17.69-2.9-.45-3.76-1.19-.9-2.86-.74-3.8.42L38.6 114.34c-2.41 2.9-3.28 6.26.51 8.4 3.85 2.18 7.44-2.22 9.27-4.82z" fill="url(#g)"/>
          <linearGradient id="h" gradientUnits="userSpaceOnUse" x1="95.906" y1="76.972" x2="56.6" y2="119.758" gradientTransform="rotate(-3.078 -13.274 321.193)">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </linearGradient>
          <path d="M81.11 68.3c-.5.51-26.25 33.02-34.47 51.84l34.38-48.5c.8-.98.84-2.51.09-3.34z" fill="url(#h)"/>
          <radialGradient id="i" cx="87.278" cy="48.666" r="73.408" gradientTransform="matrix(-.5065 .8622 .1376 .0808 133.433 -8.723)" gradientUnits="userSpaceOnUse">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </radialGradient>
          <path d="M64.89 122.83c4.37 2 6.48-2.61 6.48-2.61L92.3 81.38c.77-1.25-.09-3-.85-3.69-.82-.75-2.93-.44-3.73.82l-23.85 37.31c.01 0-3.74 4.84 1.02 7.01z" fill="url(#i)"/>
          <linearGradient id="j" gradientUnits="userSpaceOnUse" x1="84.048" y1="59.372" x2="53.924" y2="92.163" gradientTransform="rotate(-16.266 156.843 42.953)">
            <stop offset="0" stop-color="#4fc3f7"/>
            <stop offset=".83" stop-color="#4fc3f7" stop-opacity="0"/>
          </linearGradient>
          <path d="M91.71 77.92c-.19.04-13.16 19.47-20.59 42.77l20.83-38.64c1.13-1.51.57-3.31-.24-4.13z" fill="url(#j)"/>
        </g>
        </svg>


      `
      ]]]

8 Likes

Thank you, that’s great :+1: Do you use any window or door icons that are either animated or different to the default HA icons?

Noticed that it was a comment on a tip from @mobiustorr

What do I do wrong if - despite having added overflow: hidden my swipe looks like this:

Edit: @Mattias_Persson _ I tried to copy the Media area setup to the vardagsrum area as I plan to use that for all my lights. Since I have more than four lights to control, I want to use the swipe card. However, once I remove the conditional card from the code, something happens with the custom buttons for the lights. They become larger than the once for the neighboring areas and they are cut off at the bottom? Any good ideas here?

My mini graph button is not populated. Instead it says please provide the entities a list. This is my button:

type: custom:button-card
entity: sensor.snitt_temperatur
name: Temperatur
template:
  - base
  - temperature
  - icon_temp

Starnge thing is that for the pop-up, I Use mini-graph cards and they work flawlessly.
Any ideas?

Hey @VietNgoc would you mind publishing your Dashboard?

I would like to have a similiar layout as you! :slight_smile:

@tomerbs @ZynanBob



14 Likes

Thanks a lot Mate

looks nice , like the status icons in top, the weather status and the quick media layout

Just wanted to give you a heads up, that bug report for the Spotify progress issue was finally closed and the fix is in 2023.10.3+
The progress bar now works with Spotify without any code modifications.

3 Likes

Your dashboard looks fantastic. Could you please share the /Packages folder?

Nevermind! I found a solution here: A different take on designing a Lovelace UI - #1406 by pex81! Thanks @pex81!

i try it but it does not showing proper, only script…

really beautiful, compliments, but I notice that if I pause during a song, the progress bar continues to move forward, while when I put play back on it goes back and resumes from the right point. still really beautiful

This is kind of a limitation of the “fix” or workaround of the spotify API. Their API has an endpoint for timestamp which is described as “Unix Millisecond Timestamp when data was fetched” but that is not accurate. It fails to update when other information is updated like progress_ms and is_playing.

The spotify info still only updates every 30 seconds, but when that happens HA now grabs it’s own timestamp and updates the HA media_position_updated_at as a workaround. This makes the track progress correct, but it still won’t update play/pause until it grabs info from spotify. Which, worst case could be 30 seconds.

So unfortunately there isn’t a lot that can be done outside of spotify fixing their API. But, tracks will no longer show progress well past the total track length, and it will show progress more than every 30 seconds.

2 Likes

Does someone have any idea or can point me to the location where I can change the settings to make this space smaller for the portrait mode/tablet mode?

grid-gap

    # phone
    '(max-width: 800px)':
      # grid-gap: calc(var(--custom-layout-card-padding) * 1.7)
      grid-gap: 1.8vw
      margin: 0
      # grid-template-columns: 0 repeat(2, 1fr) 0
      grid-template-columns: 0 1fr 1fr 0
      grid-template-rows: 0 min-content min-content fit-content(100%) fit-content(100%) fit-content(100%) fit-content(100%)  fit-content(100%) fit-content(100%) fit-content(100%) fit-content(100%)
      grid-template-areas: |
        ". .            .        ."
        ". header      weather   ."
        ". chips       chips     ."
        ". home        security  ."
2 Likes

This helped.
Thanks!

I don’t use any scripts, only the decluttering card because I also use it for another dashboard. I’m not a developer or programmer, all the stuff used here is from this topic. So try to read this whole thread and maybe you will get more inspiration. :sweat_smile: :sweat_smile:

2 Likes

Hello VietNgoc,

Can you explain what is you sensor.home_mode and how its configurate ?

It’s just a sensor that shows the current scene settings, I use it simultaneously with Siri in Homekit. For example, a scene for leaving home, or for a guest with different automations, etc.

2 Likes