A different take on designing a Lovelace UI

Hi André

Thanks for the automation.

Do you maybe have an idea how I can close the popup automatically after x seconds.

I dont get any further :slight_smile:

WOW very nice!

@Mattias_Persson - Question regarding your default grid layout, how do you get the grid to fit your screen size perfectly based on your screenshots?

I have created a grid layout as below:

margin: 0
grid-gap: 5px
grid-template-columns: 250px repeat(2, 1fr) 250px
grid-template-rows: 0fr repeat(2, fit-content(100%)) 0fr
grid-template-areas: |
  ".  badges badges ."
  ".  main1  main2 ."
  ".  media  main4 ."
  ".  footer footer ."

I use custom button cards with aspect ratio 1/1 like yourself but for some reason the buttons appear huge on my desktop monitor and even on the samsung tab i have to scroll the dashboard rather than it being nicely setup within the viewport of the browser.

The grid is tablet first. I can make the layout scroll too if I fullscreen on desktop. Use css media queries and avoid px units.

I think it’s because you’re trying to load https url over http

Try something like this

if (entity) {
  let entity_picture = entity.attributes.entity_picture !== undefined
    ? entity.attributes.entity_picture
    : entity.attributes.entity_picture_local !== undefined
      ? entity.attributes.entity_picture_local
      : null;
  return entity.attributes.data !== undefined
    ? `url("${entity.attributes.data[variables.i].fanart}"), url("${entity.attributes.data[variables.i].poster}")`
    : `url("${entity_picture}")`;
}

You can loop your media players that are playing and count that

  let count = 0,
  media_players = [
    states['media_player.plex_firetv_kueche'],
    states['media_player.plex_shield'],
    states['media_player.plex_firetv_schlafzimmer'],
    states['media_player.plex_galaxy_s21'],
    states['media_player.plex_karschiller_googlemail_com_plex_for_android_tv_aftt'],
    states['media_player.plex_plexamp_iphone_von_marc'],
    states['media_player.plex_iphone']
  ];
  for (var i = 0; i < media_players.length; i++) {
    if (media_players[i] !== undefined && media_players[i].state === 'playing') {
      count += 1;
    }
  }
  return count;

You can test it in terminal. If I copy this command I get 401% as a response and if I enter the correct credentials it spits out json.


data='{"username":"user","password":"pass"}'; ip='https://192.168.1.1:443'; c=$(curl -H 'Content-Type: application/json' -d $data -ksc - $ip/api/auth/login -o /dev/null); echo "${c}" | curl -ksb - $ip/proxy/network/api/s/default/stat/device/

Hi Mattias
I am also trying to get the Dream Machine working, I think have it all setup both the template and the secret, when connecting to Homeassistant via putty and running the script there are no errors and I get alle the information from my Dream Machine, But in Homeassistant all my sensors says unknown and I can’t see anything in the log, do you have any idea what I can do to see why it’s failing ???

You can try running the command inside the container to see whats up

For me it’s

ssh nas.local
docker exec -it home-assistant bash
data='{"username":...

:thinking: ok. I’m impressed you can fit so much on the tablet. Pretty sure I have the same as you and I’m struggling to fit my cards on it without them causing overflow issues.

if I do it via Portainer there are still no error, stange It cannot be runned from my command line template

hey

thanks for your answer, both posts from you work very well.

i actaully try that the icon_monitors animation should animated all the time when the state is playing. he should not stop the animation. he should stop the animation when its changed to paused.

have you perhaps a tip for me? i tried it but he always stops the animation.

EDIT

okay, i get it to work with a simple “animation-iteration-count: infinite;” on the active animation part. BUT when i reload the page the animation stops and dont starts anymore. Gives there a way to get this to work?

EDIT2
okay i must remove the timeout, because when i relaod or change a song he things the timeout is reached, when i remove it, it works.

icon_monitors_test:
    styles:
      custom_fields:
        icon:
          - width: 73%
          - margin-left: -9%
    custom_fields:
      icon: >
        [[[
          let style = `
            <style>
              @keyframes cone {
                35% {
                  transform: scale(0.8);
                  animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
                }
                36% {
                  transform: translateY(0%);
                }
                49% {
                  transform: scale(1.25);
                }
                63% {
                  transform: scale(0.85);
                  animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
                }
                77% {
                  transform: scale(1.15);
                  animation-timing-function: cubic-bezier(0, 0.55, 0.45, 1);
                }
                95% {
                  transform: scale(1);
                }
              }
              .cone {
                animation: cone 1.2s;
                animation-iteration-count: infinite;
                transform-origin: center;
              }
              @keyframes speaker {
                0% {
                  transform: scale(1);
                }
                40% {
                  transform: scale(1);
                }
                49% {
                  transform: scale(0.95);
                }
                63% {
                  transform: scale(1);
                }
                77% {
                  transform: scale(0.95);
                }
                100% {
                  transform: scale(1);
                }
              }
              .speaker {
                animation: speaker 1.3s;
                transform-origin: center;
              }
            </style>
          `,
            paths = `
              <g class="speaker">
                <path fill="#686868" d="M35.8 46.9H14.2c-1.1 0-2-1-2-2.3V6.7c0-1.3.9-2.3 2-2.3h21.5c1.1 0 2 1 2 2.3v37.9c0 1.2-.9 2.3-1.9 2.3z"/>
                <path fill="#2a2a2a" d="M39.2 1H10.8C9.4 1 8.3 2.1 8.2 3.5v42.9a2.65 2.65 0 0 0 2.6 2.6h28.3c1.4 0 2.5-1.2 2.6-2.6V3.5c0-1.4-1.1-2.5-2.5-2.5zM25 7c1.3 0 2.4 1.1 2.4 2.4s-1.1 2.4-2.4 2.4-2.4-1.1-2.4-2.4C22.5 8 23.6 7 25 7zm10.2 35.5l-.4 1.9s-.2.6-.6.6H15.8c-.4 0-.6-.6-.6-.6s-.1-1.1-.4-1.9.6-.9.6-.9h19.3c0-.1.8-.1.5.9z"/>
              </g>
              <path class="cone" fill="#e5dd00" d="M25 15.7c-6.2 0-11.3 5.1-11.3 11.3S18.8 38.3 25 38.3 36.3 33.2 36.3 27c-.1-6.3-5.1-11.3-11.3-11.3zm0 14.5a3.33 3.33 0 0 1-3.3-3.3 3.33 3.33 0 0 1 3.3-3.3 3.33 3.33 0 0 1 3.3 3.3c-.1 1.9-1.5 3.3-3.3 3.3z"/>
            `;
          if (variables.state_on && variables.timeout < 2000) {
          return `
            <svg viewBox="0 0 50 50">
              ${style}
              ${paths}
            </svg>
          `;
          }
          return variables.state_on && variables.timeout > 2000 ? `
            <svg viewBox="0 0 50 50">
              ${paths}
            </svg>
          ` : `
            <svg viewBox="0 0 50 50">
              <path fill="#9da0a2" d="M25 18.6c-4.6 0-8.4 3.8-8.4 8.4s3.8 8.4 8.4 8.4 8.4-3.8 8.4-8.4-3.7-8.4-8.4-8.4zm0 11.7a3.33 3.33 0 0 1-3.3-3.3 3.33 3.33 0 0 1 3.3-3.3 3.33 3.33 0 0 1 3.3 3.3c0 1.8-1.4 3.3-3.3 3.3zM39.2 1H10.9C9.4 1 8.3 2.1 8.3 3.6v42.9a2.65 2.65 0 0 0 2.6 2.6h28.3a2.65 2.65 0 0 0 2.6-2.6v-43C41.7 2 40.5.9 39.2 1zM25 7c1.3 0 2.4 1.1 2.4 2.4s-1.1 2.4-2.4 2.4-2.4-1.1-2.4-2.4S23.7 7 25 7zm10.3 35.5l-.4 1.9s-.2.6-.6.6H15.8c-.4 0-.6-.6-.6-.6l-.4-1.9c-.2-.9.6-.9.6-.9h19.3s.9.1.6.9zM25 38.2c-6.2 0-11.3-5.1-11.3-11.3a11.29 11.29 0 1 1 22.6 0c.1 6.3-5 11.3-11.3 11.3z"/>
            </svg>
          `;
        ]]]

Hey guys,
I’m very new to HA and have been enjoying learning a lot by trying to modify this UI for my home. I’m working on my covers/screens, and have defined a variables.state_moving. I want the loader to continually spin as long as this variable is true.

I’m struggling with reading the code for the loader, so not sure how I can apply this. Anyone got suggestions for me? Thanks a lot!

Hi Mattias
I found out if I remove the following 2 lines from the command then it is working :slight_smile: any idea why I can’t have tempature and storage line ??
image

Mattias;

What about Unifi Access Point with Controller, How I can add info as sensor for Memory Uptime, Status etc?

Hello @Mattias_Persson . I have a long time problem that I can’t solve. I have some custom stuff and I can’t replace all the files. The problem is that when the song name is long it exceeds the limits of the image. What could I look at or change? thank you

i think you must look at the function marquee in the button_card_templates.yaml under conditional_media: → state_display

function marquee() {
            let state = elt.getElementById("state"),
              container = elt.getElementById("container");

            if (state && container) {
              state.innerHTML = output;
              let ro = new ResizeObserver(entries => {
                let spacer = "&nbsp;".repeat(3),
                  s = entries[0],
                  c = entries[1],
                  r = s && s.contentRect &&
                      c && c.contentRect &&
                      s.contentRect.width !== 0 &&
                      c.contentRect.width !== 0;

                if (r && s.contentRect.width < c.contentRect.width) {
                  state.classList.remove("marquee");
                }
                else if (r && s.contentRect.width >= c.contentRect.width) {
                  state.innerHTML = `${output} ${spacer} ${output} ${spacer}&nbsp;`;
                  state.classList.add("marquee");
                }
              });
              ro.observe(state);
              ro.observe(container);
            }
          }
          return output;
        }
        return variables.translate_unknown;

but when you use the code from mattias then he scrolls.

@Mattias_Persson
is it possible to hide the names in the footer on phones?
cause it’s not implemented as a custom field, I couldn’t hide it by extra_styles.
Thanks in advance.

I have an iPhone 13 mini, and with icon and name the footer looks too cramped.

I keep getting the error: Custom element doesn’t exist: apexcharts-card.
Anyone knows how to fix this?

HI,

try this in your Config.yaml:

lovelace:
  mode: yaml
  resources:
    [
      { url: /hacsfiles/atomic-calendar-revive/atomic-calendar-revive.js,         type: module },
      { url: /hacsfiles/flex-table-card/flex-table-card.js,                       type: module },
      { url: /hacsfiles/hass-shutter-card/hass-shutter-card.js,                   type: module },
      { url: /hacsfiles/thermostat-popup-card/thermostat-popup-card.js,           type: module },
      { url: /hacsfiles/simple-weather-card/simple-weather-card-bundle.js,        type: module },
 


      { url: /local/decluttering-card.js,                                         type: module },
      { url: /local/apexcharts-card.js,                                           type: module },
      { url: /local/buien-rain-card.js,                                           type: module },
      { url: '/local/calendar-card.js?v=3.109.1',                                 type: module },
      { url: '/local/custom-lovelace/weather-card/weather-card.js',               type: module },
      { url: '/local/custom_icons.js?v=28082021',                                 type: module },
      { url: '/local/marked.min.js?v=4.0.12',                                     type: module },
      { url: '/local/vanilla-tilt.min.js?v=1.7.2',                                type: module },
      { url: /local/font.css,                                                     type: css} ]
      

and copy apexcharts-card.js directly in your local folder (www)