A different take on designing a Lovelace UI

think i have found the problem, if i do browser_mod.popup and the code then i receive the same message.

Browser_mod is installed but it likes to that browser_mod is not functioning by me.

i have it installed over hacs and in my configuration.yaml do i have this:

lovelace:
mode: yaml
resources:

  • url: /browser_mod.js
    type: module
    (this below is only for a test for now)
  • url: /hacsfiles/button-card/button-card.js
    type: module

it has been resolved, I had skipped a step

1 Like

hey,

i try like many others to implement your awesome ui, but i have trouble with button_card_templates.yaml

the logger tells me:
“mapping values are not allowed here in “/config/button_card_templates.yaml”, line 92, column 65”

any idea what could be the problem and how to fix it. Help would be very a appreciated.
thanks!

Is there any chance of making a youtube tutorial on this for us who aren’t so good at understanding things by text?

2 Likes

Hi,

Just wondering about the colors (active and non-active) of the svg icons inside the button cards.

I saw in a previous answer that the color is defined inside themes.yaml like this: paper-item-icon-active-color: ‘#3182b7’ (which is the light blue color), but I can’t find where the darker color (which I prefer) is defined.

It seems to do with the entity, meaning that “Tellus plug” is a switch and not a light? Because if I swap the entities (but keeping the same icon svg info), it also turned to the light blue color. So how would I go about to have all svg icons in the same dark blue color?

Off state:

On state (“Tellus plug” has a different color)

On state (Switched the entities Dinner and Tellus plug, and now Dinner has the light blue color)

I cought something I’m not able to understand. Had tje problem with this slider color thing and the backdrop filter. Never got it to work. But when I use applicationize (spelling?) on my computer both things works, but not on the ios app for example. Simply wonder why? Is there something in the theme?

Thank you very much for this fantastic UI!
I have managed to adopt it to my needs and it is working well.
I even have mini graph cards in the layout, but I am struggling with scaling on different devices.

Does anybody know of a way to progressively scale the custom mini-graph-card?
Or has anybody been successful with the built in graph in the button-card?

Thank you!


Graph-small-screen

7 Likes

Could you please elaborate on your suggestion?
All the custom button-cards have an aspect of 1:1 and they are positioned with the values top, left and width submitted in %.
I tried replacing the background image with the correct aspect for me and as Mattias mentioned, it doesn’t work well without hand tweaking everything.

Should I rewrite all the % values to vw values?

And can you share your automation solution to switching the two version of backround.png?

Thank you very much!

Hi @Mattias_Persson

Since I had my cover button working, I was trying to get the temp. sensor, I use to run the automation to show up instead of an icon.
2021-01-15_16h04_01
I just can’t seem to figure out the proper way to go, I’ve been scanning the custom:button-card documentation.
This is my functioning button card template + me trying to add the temperature sensor and positioning it left of the opening % circle.

  cover_kokken:
    aspect_ratio: 1/1
    show_state: true
    show_icon: false
    state:
      - value: 'open'
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']
      - value: 'opening'
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']   
    styles:
      name:
        [top: 57.7%, left: 11%, line-height: 2vw, position: absolute]
      state:
        [top: 74%, left: 11%, line-height: 2vw, position: absolute]
      card:
        [font-family: Sf Display, letter-spacing: 0.05vw, font-weight: 400, color: 'rgba(255, 255, 255, 0.3)', font-size: 1.34vw, 
        background-color: 'rgba(115, 115, 115, 0.2)', border-radius: 0.8vw, box-shadow: none, transition: none]
      custom_fields:
        circle:
          [top: 8.5%, left: 56.2%, width: 3.5vw, position: absolute, letter-spacing: 0.03vw]
        **temp:**
**          [top: 8.5%, left: 11.2%, width: 3.5vw, position: absolute]**       
    **custom_fields:**
**      temp: >**
**        [[[**
**          <ha-icon icon="mdi:thermometer"></ha-icon>{{ states('sensor.velux_sensor_temperature').state °C }}**
**        ]]]**      
      circle: >
        [[[ if (entity.state === 'open') {
        const position = states['sensor.velux_position_kokken'].state;
        const radius = 20.5; const circumference = radius * 2 * Math.PI;
        return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="${radius}" stroke="#b2b2b2" stroke-width="1.5" fill="none" style="
        transform: rotate(-90deg); transform-origin: 50% 50%; stroke-dasharray: ${circumference}; stroke-dashoffset: ${circumference - position / 100 * circumference};" />
        <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle">${position}<tspan font-size="10">%</tspan></text></svg>`; } ]]]    

2020-12-30_20h33_05

All I get is this: 2021-01-15_16h07_23

Hope you can help :slight_smile:

Where did you all get your fonts from? I downloaded the ones in fonts.css however all my sizing is way out

image

Want to share your config for those graph cards?

1 Like

This looks great. I have tried to start from your repo and remove stuff. My house setup is a lot simpler than yours, as I only have smart lights, some Hue-compatible led strips smart plugs and Google and Alexa speakers. What do you suggest for adapting your code to my setup? Where do I start from? your earliest commits in the repo? Has somebody else something very similar with a simpler setup?

I started with this piece and am now continuing to build until I have had everything. I don’t have everything in it yet because I come from another smart home controller.

##########################################################################
#                                                                        #
#                              * SETTINGS *                              #
#                                                                        #
##########################################################################

anchors:
  ⚓₁: &title
    entity: sensor.placeholder
    tap_action:
      action: none
    hold_action:
      action: none
    type: state-label
  ⚓₂: &title-style
    color: '#bcbebf'
    font-family: SF Text
    font-size: 1.5vw
    font-weight: 500
    max-width: 1px
    cursor: default

button_card_templates: !include button_card_templates.yaml

##########################################################################
#                                                                        #
#                              * LOVELACE *                              #
#                                                                        #
##########################################################################

title: Thuis
views:
  - panel: true
    path: default_view
    cards:
      - type: picture-elements
        image: /local/background.png
        elements:

          # markdown fix
          - type: custom:hui-element
            card-type: markdown
            style: {opacity: 0}
            content: preload

          ##########################################################################
          #                                                                        #
          #                              * SIDEBAR *                               #
          #                                                                        #
          ##########################################################################

          - type: image
            image: local/sidebar.png
            tap_action:
              action: none
            hold_action:
              action: none
            style:
              {top: 49.24%, left: 10.6%, width: 21.5%, pointer-events: none, border-right: '1.5px solid rgba(58,69,73,0.2)'}


#          - type: custom:hui-markdown-card
#            style:
#              {top: 15%, left: 8%}
#            content: >
#              Vandaag is het **<font color=green> {{states('sensor.vandaag')}}</font>**.
#
#              Volgende afval-ophaal over **<font color=var(--secondary-text-color)>{{states('sensor.trash_next')}}</font>** dagen:
#
#              **<font color=var(--secondary-text-color)>{{states('sensor.trash_firstdate')}}</font>** : **{{states('sensor.trash_firstwastetype')}}**

REMOVE THIS I HAVE A ISSUE WITH THIS PIECE OF CODE

            #########################    TIME & DATE    #########################

          - entity: sensor.time
            hold_action:
              action: none
            style:
              color: 'rgba(255, 255, 255, 0.7)'
              font-size: 3.0vw
              font-weight: 350
              left: 6.0%
              letter-spacing: '-0.05vw'
              max-width: 1px
              top: 7.5%
            tap_action:
              action: none
            type: state-label
          - entity: sensor.date
            hold_action:
              action: none
            style:
              color: 'rgba(255, 255, 255, 0.7)'
              font-size: 1.3vw
              font-weight: 300
              left: 21.55%
              letter-spacing: '-0.05vw'
              text-align: left
              top: 12.2%
              width: 30%
            tap_action:
              action: none
            type: state-label

Hi. Can you tell me how did you put this blur effect on the background of this card, only under de text.
Look at mine, dont have this effect:
image

Hi, i have one quick question :
i post some questions here and almost no one replyed, i hope this time someone can help, any idea how i can change this code ? I have a ledstrip light and i’ll like to change the hue lamp icon by led lighstrip :

          - type: custom:button-card
            entity: light.bar
            style:
              top: 37.9%
              left: 66.18%
              width: 10%
            custom_fields:
              icon_hue: &icon_hue_2 >
                [[[ const state = entity.state === 'on' ? 'animate' : null;
                return `<svg viewBox="0 0 50 50"><style>@keyframes animate{0%{transform: scale(0.85);}20%{transform: scale(1.1);}40%{transform: scale(0.95);}60%{transform: scale(1.03);}80%{transform: scale(0.97);}100%{transform: scale(1);}}.animate{animation: animate 0.8s; transform-origin: center;}</style>
                <path fill="#9da0a2" d="M27.4 47.3h-4.9s-.7.1-.7.8.4.9.7.9h4.9c.3 0 .7-.1.7-.9s-.7-.8-.7-.8zm3.3-2.9H19.3s-.8 0-.8.8.6.9.8.9h11.5c.2 0 .8-.1.8-.9-.1-.8-.9-.8-.9-.8zm0-3H19.3s-.8 0-.8.8.6.9.8.9h11.5c.2 0 .8-.1.8-.9-.1-.8-.9-.8-.9-.8zm0-2.9H19.3s-.8 0-.8.8.6.9.8.9h11.5c.2 0 .8-.1.8-.9s-.9-.8-.9-.8zm5.2-23.2c-3.3-5.3-7-5.6-10.9-5.6-3.8 0-8.4.4-10.9 5.6-.1.1-.1.3.1.7.4.8 3.3 7.2 3.2 18.8 0 1.1-.1 1.6 0 1.7 0 .1 0 .7 1.1.7h13c1 0 1-.5 1.1-.7v-1.7c-.1-11.6 2.8-18 3.2-18.8.1-.4.1-.5.1-.7"/>
                <path class="${state}" fill="var(--button-card-light-color-no-temperature)" d="M14.1 15.3c3.4-.3 7-.4 10.9-.4 3.8 0 7.5.2 10.9.4.4-.4.7-.8.9-1.1C39 8.5 38.9 6.5 38.9 6c-.2-4.4-8.4-5-12.1-5h0-3.4c-3.7 0-12 .5-12.1 5 0 .5-.1 2.5 2.1 8.2 0 .3.3.8.7 1.1z"/></svg>`; ]]]
            styles: 
              custom_fields:
                icon_hue:
                  [top: 11%, left: 4.5%, width: 3.05vw, position: absolute]
            template: light  

oops a another question, i don’t know why but this code is not working too :

styles: *icon_hue_styles

i have to import icons somewhere ?
because i copied the file “custom_icons.js”

thanks for your help

Hi, i had the same problem i guess it’s a problem with your button card template file, you have to be sure you have copy it this file

Try this for a led strip icon:

          - type: custom:button-card
            entity: light.bar
            style:
              top: 37.9%
              left: 66.18%
              width: 10%
            custom_fields:
              icon_wled: &wled >
                [[[ const state = entity.state === 'on' ? 'animate' : null;
                return `<svg viewBox="0 0 24 24"><style>@keyframes animate{0%{transform: scale(0.85);}20%{transform: scale(1.1);}40%{transform: scale(0.95);}60%{transform: scale(1.03);}80%{transform: scale(0.97);}100%{transform: scale(1);}}.animate{animation: animate 0.8s; transform-origin: center;}</style>
                <path class="${state}" fill="var(--button-card-light-color-no-temperature)" d="M2.95 3L2 6.91L19.34 11.25L20.29 7.34L2.95 3M6.09 6.89L4.16 6.41L4.64 4.46L6.57 4.94L6.09 6.89M9.94 7.86L8 7.38L8.5 5.42L10.42 5.91L9.94 7.86M13.8 8.82L11.87 8.34L12.35 6.39L14.27 6.87L13.8 8.82M17.65 9.79L15.72 9.31L16.2 7.35L18.13 7.84L17.65 9.79M4.66 12.75L3.71 16.66L21.05 21L22 17.1L4.66 12.75M7.8 16.65L5.88 16.16L6.35 14.21L8.28 14.69L7.8 16.65M11.65 17.61L9.73 17.13L10.2 15.18L12.13 15.66L11.65 17.61M15.5 18.58L13.58 18.09L14.06 16.14L16 16.62L15.5 18.58M19.36 19.54L17.43 19.06L17.91 17.11L19.84 17.59L19.36 19.54M6.25 12.11L11 10.2L17.75 11.89L13 13.8L6.25 12.11Z"/></svg>`; ]]]
            styles: &icon_wled_styles
              custom_fields:
                icon_wled:
                  [top: 10%, left: 4.7%, width: 3.6vw, position: absolute]
            template: light

Thanks a lot it’s working and thanks for your quick answer !
it seems it’s not only the icon you change in the code, you have changed this line too :slight_smile:

return `<svg viewBox="0 0 24 24"><style>@keyframes animate{0%{transform: scale(0.85);}20%{transform: scale(1.1);}40%{transform: scale(0.95);}60%{transform: scale(1.03);}80%{transform: scale(0.97);}100%{transform: scale(1);}}.animate{animation: animate 0.8s; transform-origin: center;}</style>
                <path class="${state}" fill="var(--button-card-light-color-no-temperature)" d="M2.95 3L2 6.91L19.34 11.25L20.29 7.34L2.95 3M6.09 6.89L4.16 6.41L4.64 4.46L6.57 4.94L6.

can you tell me what’s the point ?
Thanks again for your help

Here you go, but be aware, the mini-graph-card font does not scale with resolution.
If you have one display to show your setup, you can tweak the font size and graph height to work though as I have shown in my screenshots.

lovelace.yaml

          - type: custom:button-card
            entity: sensor.living_room_temperature
            variables:
              var_title: Living Room temperature
              var_name: Living R.
            style:
              top: 37.9%
              left: 80.05%
              width: 10%
            template: graph_temp

button_card_template.yaml

graph_temp:
  template: ["base"]
  show_name: false
  show_state: false
  custom_fields:
    graph:
      card:
        type: 'custom:mini-graph-card'
        color_thresholds:
          - color: '#f53a1b'
            value: 25
          - color: '#ef6a12'
            value: 22
          - color: '#8ff331'
            value: 19
          - color: '#00a1ff'
            value: 16
        entities:
          - "[[[ return entity.entity_id ]]]"
        hours_to_show: 24
        points_per_hour: 2
        height: 110
        align_icon: left
        align_header: left
        name: '[[[ return variables.var_name ]]]'
        show:
          graph: line
          icon: true
          name: true
          labels: false
          points: false
          labels_secondary: false
        tap_action:
          action: call-service
          service: browser_mod.popup
          service_data:
            title: '[[[ return variables.var_title ]]]'
            card:
              type: entities
              entities:
                - type: custom:mini-graph-card
                  entities:
                    - "[[[ return entity.entity_id ]]]"
                  hours_to_show: 24
                  points_per_hour: 2
                  height: 200
                  color_thresholds:
                    - color: '#f53a1b'
                      value: 25
                    - color: '#ef6a12'
                      value: 22
                    - color: '#8ff331'
                      value: 19
                    - color: '#00a1ff'
                      value: 16
                  show:
                    graph: line
                    icon: false
                    name: false
                    extrema: true
                    labels: false
                    labels_secondary: false
  styles:
    custom_fields:
      graph:
        [
          bottom: 0%,
          left: 0%,
          width: 100%,
          position: absolute
        ]
3 Likes

I have just reused the code from Mattias.
The blur area is defined in the lovelace.yaml and the actual effect is in button_card_templates.yaml
Check if you have properly adapted both in your setup.

                  #################################################
                  #                                               #
                  #              RECENTLY DOWNLOADED              #
                  #                                               #
                  #################################################

                  - type: conditional
                    conditions:
                      - entity: input_select.conditional_media
                        state: Recently downloaded
                    elements:
                      - type: custom:button-card
                        entity: sensor.plex_recently_added
                        triggers_update:
                          ['sensor.plex_recently_added']
                        name: Recently downloaded
                        state_display: >
                          [[[ const data = states[entity.entity_id].attributes.data;
                          const number = data[1].number == undefined ? '(' + data[1].aired.split('-')[0] + ')' : data[1].number;
                          return `${data[1].title} ${number}`; ]]]
                        custom_fields:
                        #  icon: >
                        #    <svg viewBox="0 0 50 50"><path d="M7.7.3h34.6c4.1 0 7.4 3.3 7.4 7.4v34.6c0 4.1-3.3 7.4-7.4 7.4H7.7c-4.1 0-7.4-3.3-7.4-7.4V7.7C.3 3.6 3.6.3 7.7.3z" fill="#282a2d"/><path d="M25,7.1H14.6L25,25L14.6,42.9H25L35.4,25L25,7.1z" fill="#e5a00d"/></svg>
                          blur: >
                            <svg viewBox="0 0 50 50" />
                        styles:
                          custom_fields:
                            media_image: &plex_poster
                              [background-position: center center, background-image: 
                              "[[[ return 'url(' + states[entity.entity_id].attributes.data[1 ].fanart + ')'; ]]]"]
                            blur: *plex_poster
                            overlay: [background: 'rgba(0, 0, 0, 0.4)']
                          card:
                            [color: '#efefef', text-shadow: '1px 1px 5px rgba(18, 22, 23, 0.9)']
                        tap_action:
                          action: none
                        style:
                          top: 50%
                          left: 50%
                          width: 100%
                        template: conditional_media
conditional_media:
  template: ["base", "shared_media"]
  state_display: >
    [[[ if (entity.attributes.media_title === 'Nothing playing' || entity.attributes.media_title === 'No title' && entity.state === 'paused' ) { return 'Nothing playing'; }
    if (entity.attributes.media_title === 'No title' && entity.state === 'playing') { return 'No title'; }
    else { return entity.attributes.media_title; } ]]]
  custom_fields:
    media_image: >
      <svg viewBox="0 0 50 50" />
    blur: >
      [[[ if (entity.attributes.entity_picture != null) {
      return '<svg viewBox="0 0 50 50" />'; } ]]]
    overlay: >
      [[[ if (entity.state != 'off' && entity.state != 'idle' && entity.state != 'standby' && entity.state != 'unavailable') {
      return '<svg viewBox="0 0 50 50" />'; } ]]]
    play_pause: >
      [[[ const style = `<style>.scale-up { animation: scale-up 0.3s; cubic-bezier(.05,.5,.3,1) 1; transform-origin: center center; }
      @keyframes scale-up { 0% { opacity: 0; transform: scale(0); } 100% { opacity: 1; transform: scale(1); } }</style>`;
      if (entity.state === 'playing') { return `<svg viewBox="0 0 166 166">${style}<path class="scale-up" d="M0 0h59.9v166H0zm106.1 0H166v166h-59.9z"/></svg>`; }
      if (entity.state === 'paused') { return `<svg viewBox="0 0 166 166">${style}<path class="scale-up" d="M0 0l166 83L0 166z"/></svg>`; } ]]]
  styles:
    custom_fields:
      media_image:
        [
          background-image:
            "[[[ return entity.attributes.entity_picture == null ? 'linear-gradient(0deg, rgba(115, 115, 115, 0.2) 0%, rgba(115, 115, 115, 0.2) 100%)'
            : 'linear-gradient(0deg, rgba(13,17,19,0.9) 0%, rgba(13,17,19,0) 50%), url(' + entity.attributes.entity_picture + ')'; ]]]",
          background-size: cover,
          top: 0%,
          left: 0%,
          width: 100%,
          position: absolute,
        ]
      blur:
        [
          background-image: "[[[ return entity.attributes.entity_picture == null ? 'none' : 'url(' + entity.attributes.entity_picture + ')'; ]]]",
          background-size: cover,
          top: 0%,
          left: 0%,
          width: 100%,
          filter: blur(4px),
          clip-path: inset(16vw 0 0 0),
          position: absolute,
        ]
      overlay:
        [
          background: "[[[ return entity.attributes.entity_picture == null ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.4)'; ]]]",
          background-size: cover,
          z-index: 0,
          top: 16vw,
          left: 0%,
          width: 100%,
          opacity: 1,
          position: absolute,
        ]
      play_pause:
        [
          filter: "[[[ return entity.attributes.entity_picture == null ? 'none' : 'drop-shadow(0 0 1.3vw rgba(0,0,0,0.7))'; ]]]",
          fill: "#dedede",
          top: 0,
          right: 0,
          bottom: 0,
          left: 0,
          margin: auto,
          width: 21%,
          height: 21%,
          position: absolute,
        ]
      icon:
        [
          fill:
            "[[[ if (entity.state === 'off' || entity.state === 'idle' || entity.state === 'standby' ||
            entity.state === 'unknown' || entity.state === 'unavailable') return '#9da0a2';
            else return 'rgba(255, 255, 255, 0.8)'; ]]]",
          top: 5.35%,
          left: 5.35%,
          width: 2.95vw,
          position: absolute,
        ]
    name:
      [
        top: 79.8%,
        left: 5.3%,
        position: absolute,
        line-height: 2vw,
        z-index: 10,
      ]
    state:
      [
        top: 87.5%,
        left: 5.3%,
        position: absolute,
        line-height: 2vw,
        z-index: 10,
        white-space: nowrap,
        overflow: hidden,
        text-overflow: ellipsis,
        max-width: 90%,
      ]