A different take on designing a Lovelace UI

Hi, kan jij wellicht jouw ui-lovelace.yaml delen?

Hi All,

Just wondered if anyone knows how to allow titles of custome:button_cards to go over two lines?

All of the worlds i use to describe the entity are too long.

Any help would be really appreciated.

This does exactly that

You might be missing the extra styles class and animation “marquee”

1 Like

targetservice_data

https://www.home-assistant.io/lovelace/actions/#tap_action

1 Like

I might have an odd resolution idk 16:10 (1920x1200)

Here’s the theme variables for what @wjbeckett said about grid spacing

custom-layout-card-padding
grid-card-gap

and maybe “GRID CARD HEADINGS h1 font-size/ padding”

2 Likes

Yep. That’s the ones.
I adjusted the custom-layout-card-padding which helped. Don’t over do it though, otherwise the view becomes cluttered and messy. Same goes for grid-card-gap. Adjust with caution :slight_smile:

@Mattias_Persson What tablet are you using? Still the Galaxy Tab A 10.1? I thought the screen was 1920x1080 on those?

Yeah still that tablet, I don’t recommend it though. From what I can find it’s 1920x1200

Oh you don’t? Have you had issues with it?
Is yours the one with the capacitive buttons?

I’ve been searching around for a new tablet so keen to know your challenges with this one.

I don’t believe there’s any capacitive buttons.
It works fine but if I open a popup with loads of cards it takes over 1 sec to actually pop up and the animations are sometimes below 30fps. But I’m comparing a ~$200 device to iphone/imac which are not $200…

Ah fair enough.
I’ve got a couple I can test against. :slight_smile:

One question about animation:
How do you make the animated icons? I mean is it via svg animation tools, or is it CSS animation… I don’t know how to make my own “moving” icons.
Do you use a software to get the code and insert into the animated icons template?
Thanks for this nice and hard work !!!

Would anyone know why the popups won’t work when the type is custom:button-card ?
if I use the standard button then the popups work fine.

I have the latest version of browser_mod and button-card.

thanks in advance

EDIT: Solved, comment:

Tool from Mattias: card-mod-helper

Hello community,

First of all, thank you Mattias for sharing this!

I just recently started to use HA, coming from homebridge and now I am trying to build up my dashboard using Mattias’ config.

I just got stuck when I was trying to build up a custom button card with some data from my devices.
I would like to eliminate the spacing between the two cards that contiain the battery level of different devices and have them close to each other.

My ui-lovelace.yaml looks like this

views:
  - type: custom:grid-layout
    path: 0
    layout:
      #default
      grid-gap: var(--custom-layout-card-padding)
      grid-template-columns: repeat(4, 1fr) 0
      grid-template-rows: repeat(2, fit-content(100%)) 0fr
      grid-template-areas: |
        "sidebar  .           .          .          ."
        "sidebar  batteries   .          .          ."
        "sidebar  .           .          .          ."
        "sidebar  footer  footer     footer         ."


    cards:
      - type: custom:button-card
        styles: #extra_styles fix
          card:
            - display: none

      - type: grid
        title: Batteries
        view_layout:
          grid-area: batteries
        columns: 1
        cards:
          - type: custom:button-card
            entity: device_tracker.tamas_iphone_xs_2
            triggers_update:
              - sensor.time
            name: >
              [[[ 
                return entity.attributes.friendly_name; 
              ]]]
            variables:
               battery: device_tracker.tamas_iphone_xs_2
            template: battery

          - type: custom:button-card
            entity: device_tracker.tamas_iphone_se
            triggers_update:
              - sensor.time
            name: >
             [[[ 
               return entity.attributes.friendly_name; 
             ]]]
            variables:
             battery: device_tracker.tamas_iphone_se
            template: battery
custombase:
  variables:
    state_on: >
      [[[ return ['on', 'home', 'cool', 'fan_only', 'playing'].indexOf(entity === undefined || entity.state) !== -1; ]]]
  aspect_ratio: 1/1
  show_state: false
  show_icon: false
  styles:
    grid:
      - grid-template-areas: |
          "n circle"
      - grid-template-columns: 1fr 1fr
      - grid-template-rows: auto
      - align-items: start
    name:
      - justify-self: start
      - padding-left: 10px
    card:
      - font-family: Sf Display, Roboto
      - border-radius: 15px
      - -webkit-tap-highlight-color: rgba(0,0,0,0)
      - transition: none
      - padding: 10% 9% 9% 10%
      - --mdc-ripple-color: >
          [[[
            return variables.state_on
              ? 'rgb(0, 0, 0)'
              : 'rgba(255, 255, 255, 0.3)';
          ]]]
      - color: >
          [[[
            return variables.state_on
              ? 'rgba(0, 0, 0, 0.6)'
              : 'rgba(255, 255, 255, 0.3)';
          ]]]
      - background-color: >
          [[[
            return variables.state_on
              ? 'rgba(255, 255, 255, 0.8)'
              : 'rgba(115, 115, 115, 0.2)';
          ]]]
      - height: 40px
      - width: 300px


battery:
  template:
    - custombase
    - circle
  triggers_update: sensor.time
  hold_action:
    action: none
  custom_fields:
    circle: >
      [[[
          let input = states[variables.battery].attributes.battery_level,
            radius = 20.5,
            circumference = radius * 2 * Math.PI;
          var color = "#27C950";
            
          if (input <= 20) {
            color = "#FDD60F";
          } else if (input <= 40) {
            color = "#FDD60F";
          }
          else {
            color = "#27C950";
          }
          return `
            <svg viewBox="0 0 50 50">
              <style>
                circle {
                  transform: rotate(-90deg);
                  transform-origin: 50% 50%;
                  stroke-dasharray: ${circumference};
                  stroke-dashoffset: ${circumference - input / 100 * circumference};
                }
                tspan {
                  font-size: 10px;
                }
              </style>
              <circle cx="25" cy="25" r="${radius}" stroke="${color}" stroke-width="5" fill="none" stroke-linecap="round"/>
              <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${input}<tspan font-size="10">%</tspan></text>
            </svg>
          `;
      ]]]

I really just started to playing around and trying to get the whole picture.
Can you give some hint or direction where to look, pelase?
I do not get it why I have the vertical spacing between my custom cards.

Thank you in advance!

Perfect, that worked like a charm :slight_smile: Thanks!

Which one do you recommend then ? Firetab ?

What if you put a picture with opacity: 0 on top of the card?

          - type: custom:button-card
            name: Street camera
            custom_fields:
              picture:
                card:
                  type: picture-elements
                  camera_image: camera.street_camera_ch01_sub
                  camera_view: live
                  elements:
                    - type: image
                      image: /local/bg.png
                      tap_action:
                        !include popup/street_camera.yaml
                      style:
                        opacity: 0
                        top: 50%
                        left: 50%
                        width: 100%
            styles:
              custom_fields:
                picture:
                  [top: -27%, left: -55%, width: 190%, position: absolute]
            template: base
1 Like

Here you go. Keep in mind this will popup on all devices.

automations.yaml

- id: '1642017204324'
  alias: System - Dashboard - Display Doorbell Cam
  description: ''
  trigger:
  - platform: state
    entity_id: binary_sensor.doorbell
    to: 'on'
    id: pressed
    from: 'off'
  condition: []
  action:
  - service: browser_mod.popup
    data:
      large: true
      title: Doorbell
      style:
        $: ".mdc-dialog__surface {\n  background: transparent !important;\n  border-style:\
          \ none !important;\n  border: 0px !important;\n  box-shadow: none;\n}\n"
      card:
        type: vertical-stack
        cards:
        - type: custom:layout-card
          layout_type: grid
          layout:
            grid-gap: 0.4vw
            grid-template-columns: auto 80% auto
            grid-template-rows: 95%
            grid-template-areas: '".   cam1   ."

              '
            mediaquery:
              '(max-width: 800px)':
                grid-gap: 1.5vw
                grid-template-columns: auto
                grid-template-rows: auto
                grid-template-areas: '"cam1"

                  '
          cards:
          - type: picture-entity
            entity: camera.ringeklokke
            state_image: entity.attributes.entity_picture
            show_info: false
            show_state: false
            show_name: false
            camera_view: live
            view_layout:
              grid-area: cam1

PS: the grid you could probably do without, but I made it so it would be ready for an extra camera in the future.

Sure :slight_smile:

Garage (I haven’t finished animating it, yet)

              <path fill="#9da0a2" d="M24.933 11.355l19.948 3.894c.082.14.09 1.51 0 1.8l-39.761-.033c-.089-.283-.085-1.618.01-1.821z"/>
              <rect fill="#9da0a2" width="1.966" height="20.53" x="5.006" y="18.115" rx=".256" paint-order="fill markers stroke"/>
              <rect fill="#9da0a2" width="1.966" height="20.53" x="43.028" y="18.115" rx=".256" paint-order="fill markers stroke"/>
              <rect fill="#707070" id="port1" width="34.328" height="5.932" x="7.836" y="18.115" rx=".186" paint-order="fill markers stroke"/>
              <rect fill="#707070" id="port2" width="34.328" height="7.032" x="7.836" y="24.863" rx=".186" ry=".22" paint-order="fill markers stroke"/>
              <rect fill="#707070" id="port3" width="34.328" height="5.932" x="7.836" y="32.71" rx=".186" paint-order="fill markers stroke"/>

Camera (working on a more realistic version that lights up the red LEDs if night vision is on)

                  <path id="BottomBody" d="M25.4029 33.1482C32.5202 33.1572 34.049 32.8907 34.049 32.8907L34.0476 42.9924C34.0476 42.9924 33.7847 43.7983 25.2763 43.7668C17.5461 43.7986 17.0074 43.0119 17.0074 43.0119L17.0356 32.894C17.0356 32.894 18.7469 33.1734 25.403 33.1482L25.4029 33.1482Z" fill="#9da0a2"/>
                  <path id="rect1631" d="M25.5681 5.15724C30.289 5.15724 34.1007 8.92111 34.0896 13.5964L34.0441 32.6626C34.0441 32.6626 31.7224 33.0036 25.5247 32.9528C17.2365 32.8848 17.0033 32.6511 17.0033 32.6511L17.0467 13.5964C17.0573 8.92111 20.8473 5.15724 25.5681 5.15724H25.5681Z" fill="#9da0a2"/>
                  <path id="path26713" d="M25.5876 6.28206C29.8706 6.28206 33.3106 8.93542 33.3187 12.2313L33.3408 21.1665C32.9929 24.5645 30.6552 25.8211 25.5363 25.9361C20.3005 26.0536 17.8828 24.0377 17.8128 21.0478L17.8564 12.2313C17.8727 8.93545 21.3045 6.28206 25.5876 6.28206H25.5876Z" fill="#b6b9bc"/>
                  <path id="rect3378" d="M32.5782 13.4998C32.5782 9.61689 29.4304 6.46918 25.5475 6.46918C21.6646 6.46918 18.5169 9.61689 18.5169 13.4998V14.8764C18.5169 18.7593 21.6646 21.907 25.5475 21.907C29.4304 21.907 32.5782 18.7593 32.5782 14.8764V13.4998Z" fill="#212121"/>
                  <path id="rect4038" d="M29.7107 13.6797C29.7107 11.248 27.8357 9.27679 25.5226 9.27679C23.2096 9.27679 21.3345 11.248 21.3345 13.6797V14.5418C21.3345 16.9734 23.2096 18.9447 25.5226 18.9447C27.8357 18.9447 29.7107 16.9734 29.7107 14.5418V13.6797Z" fill="#1A1A1A"/>
                  <path id="path5422" d="M25.5318 16.8095C27.0803 16.8095 28.3356 15.5542 28.3356 14.0057C28.3356 12.4572 27.0803 11.2019 25.5318 11.2019C23.9833 11.2019 22.728 12.4572 22.728 14.0057C22.728 15.5542 23.9833 16.8095 25.5318 16.8095Z" fill="#333333"/>
                  <path id="circle21643" opacity="0.830128" d="M25.5436 16.1275C26.722 16.1275 27.6773 15.1722 27.6773 13.9938C27.6773 12.8155 26.722 11.8602 25.5436 11.8602C24.3653 11.8602 23.41 12.8155 23.41 13.9938C23.41 15.1722 24.3653 16.1275 25.5436 16.1275Z" fill="#212121"/>
                  <path id="CameraLens" d="M25.5279 14.541C25.8234 14.541 26.063 14.3014 26.063 14.0059C26.063 13.7103 25.8234 13.4708 25.5279 13.4708C25.2324 13.4708 24.9928 13.7103 24.9928 14.0059C24.9928 14.3014 25.2324 14.541 25.5279 14.541Z" fill="#1A1A1A"/>

3 Likes

How have you done the circles? Please share? :slight_smile: