A different take on designing a Lovelace UI

I run mutable dashboards myself, but I have split up the YAML like so, a deck is a set of 4 cards.

see how the rooms deck is reused on both dashboards

my plan is to have a full dashboard for each room in my home that has a google show or tablet, and use a long tap on the rooms card to change the current dashboard if needed

You are einstein :sunglasses:

Now how can I separate this by singular and plural? Like 1 light on or 2 lights on?

        active: >
          <b>
          {% set lights = [
            states.light.fita_led_pc,
            states.light.fita_led_quarto,
            states.light.led_tv,
            states.light.lado_esquerdo,
            states.light.lado_direito,
            states.light.luzes_quarto
          ] %}

          {% set lights_on = lights | selectattr('state','eq','on') | list %}
          {% set lights_name = lights | selectattr('state','eq','on') | map(attribute='name') | join(', ') %}

          {{ lights_on | length }} Luz Ligada 
          </b>

And another question, how can I insert this icon?
It’s poorly programmed, but it’s just to set an example.

          {{ lights_on | length }} Luz Ligada {{'\uD83D\uDCA1'}}
          </b>

thank you

I currently have this climate button card that I took from André’s code:

image

Unfortunately the CSS is a bit off, probably due to differences in the theme code. How would I go about to make it look like this (ignore the background color).

image

This is the code for the button card template:

weather_forecast:
  variables:
    temp_min: ''
    temp_max: ''
  aspect_ratio: 1/1
  show_icon: false
  show_entity_picture: true
  show_name: true
  show_state: false
  show_label: true 
  tap_action:
    action: more-info
  styles:
    grid:
      - grid-template-areas: |
          "n"
          "temp"
          "i"
          "s"
          "l"
      - grid-template-columns: 1fr
      - grid-template-rows: min-content repeat(2, 1fr) repeat(2, min-content)
      - gap: 0%
    card:
      - color: > #rgba(157, 160, 162, 1) #rgba(84, 85, 85, 1) #rgba(85, 86, 86, 1)
          [[[
            if (states['sun.sun'].state == 'below_horizon'){
              return 'rgba(157, 160, 162, 1)';
            } else
              return 'rgba(71, 71, 71, 1)';
          ]]]  
      - background: > # else linear-gradient(to top, rgba(123,168,197,0.8) 0%, rgba(61,132,176,0.8) 100%)
          [[[
            if (states['sun.sun'].state == 'below_horizon'){
              return 'linear-gradient(to top, rgba(53,59,83,0.8) 0%, rgba(10,14,34,0.8) 100%)';
            } else
              return 'linear-gradient(to top, rgb(123 168 197) 0%, rgba(61,132,176,0.8) 100%)';
          ]]]
        # return 'linear-gradient(to top, rgb(123 168 197) 0%, #b0c5d3 100%)'; --- rgb(213, 215, 216)
    name:
      - place-self: start
      - text-transform: uppercase
      - font-weight: 400
    img_cell:
      - justify-content: start
    icon:
      - width: 37%
    label:
      - place-self: start
      - margin-left: -5px
    custom_fields:
      temp:
        - place-self: start
        #- margin-top: -10px
  label: >   
    [[[
      return `
        <ha-icon icon="mdi:arrow-up-thin" style="width: 1.1em; height: 1.1em; margin-right: -0.3em;"></ha-icon>
        <span> ${states[variables.temp_max].state}°</span>
        <ha-icon icon="mdi:arrow-down-thin" style="width: 1.1em; height: 1.1em; margin-right: -0.3em;"></ha-icon>
        <span> ${states[variables.temp_min].state}°</span>
      `
    ]]]
  custom_fields:
    temp: >
      [[[ return entity.attributes.temperature + "°"; ]]]
  entity_picture: |
    [[[
      if ((entity.state == 'sunny') && (states['sun.sun'].state == 'above_horizon'))
        return "/local/svg/weather/clear-day.svg";
        if ((entity.state == 'sunny') || (entity.state == 'clear-night') && (states['sun.sun'].state == 'below_horizon'))
          return "/local/svg/weather/clear-night.svg";
            if (entity.state == 'fog')
              return "/local/svg/weather/fog.svg";
                if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'above_horizon'))
                  return "/local/svg/weather/partly-cloudy-day.svg";
                    if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'below_horizon'))
                      return "/local/svg/weather/partly-cloudy-night.svg";    
                        if (entity.state == 'rainy')
                          return "/local/svg/weather/rain.svg";                  
                            if (entity.state == 'sleet')
                              return "/local/svg/weather/sleet.svg";         
                                if (entity.state == 'snow')
                                  return "/local/svg/weather/snow.svg";  
                                    if (entity.state == 'cloudy')
                                      return "/local/svg/weather/cloudy.svg";    
      else (entity.state == 'wind')
        return "/local/svg/weather/wind.svg";                        
    ]]]
  extra_styles: |
    [[[
      return `
        #name {
          font-size: 0.7vw;
        }
        #temp {
          font-size: 1.7vw;
        }
        #state {
          font-size: 0.8vw;
        }  
        #label {
          font-size: 0.7vw;
        }                    
        /* portrait */
        @media screen and (max-width: 2000px) {
          #name {
            font-size: 0.7vw !important;
          }
          #temp {
            font-size: 1.8vw !important;
          }
          #state {
            font-size: 0.7vw !important;
          }  
          #label {
            font-size: 0.7vw !important;
          }  
        }
        /* phone */
        @media screen and (max-width: 800px) {
          #name {
            font-size: 2vw !important;
          }              
          #temp {
            font-size: 4.5vw !important;
          }    
          #state {
            font-size: 2vw !important;
          }   
          #label {
            font-size: 2vw !important;
          }                        
        }
        @keyframes card_bounce {
          0% {
            transform: scale(1);
          }
          15% {
            transform: scale(0.9);
          }
          25% {
            transform: scale(1);
          }
          30% {
            transform: scale(0.98);
          }
          100% {
            transform: scale(1);
          }
        }
      `
    ]]]
4 Likes

Hi. It was shared by another user. Link:

https://community.home-assistant.io/t/a-different-take-on-designing-a-lovelace-ui/162594/3775?u=pablo_gustavo_fiscel

Ok. Thanks for sharing. I will read it carefully.

Thanks for sharing

@Mattias_Persson hello and please forgive my first question about my first adventure into home assistant… :upside_down_face:

Your install.md states …
"* Manually copy over these files from matt8707/hass-config

  • ui-lovelace.yaml
  • button_card_templates folder
  • popup folder
  • themes.yaml
  • sidebar.yaml"

where exactly do I copy them to ? :pleading_face:

That’s the file and folder structure you have to have for it to work. Everything comes out of the config folder

That’s what I did. And I still get an error:

my code:

  card:
    type: grid
    columns: 1
    square: false
    cards:
      - type: custom:button-card
        entity: sensor.hass_version_installed
        template: updates_hass
        variables:
          latest: sensor.hass_version_latest
          latest_beta: sensor.hass_version_latest_beta
          release_notes: sensor.hass_release_notes
          release_notes_beta: sensor.hass_version_latest_beta
ButtonCardJSTemplateError: Error: marked(): input parameter is undefined or null in 'if (entity) { let links = new RegExp('<a href="([^"]+)"', "g"), installed = entity...'
tap_action:
  href: null
type: custom:button-card
group_expand: false
hold_action:
  action: none
double_tap_action:
  action: none
layout: vertical
size: 40%
color_type: icon
show_name: false
show_state: true
show_icon: false
show_units: true
show_label: false
show_entity_picture: false
show_live_stream: false
card_size: 3
styles:

Did you get to fix this? Mine is empty too.

Hey @Mattias_Persson

I cannot change the background image because I cannot find it in the code. Where should I look?

/config/www

Defined in themes.yaml

1 Like

Good day. When clicking on any tile, I get the error -browser_mod/toast. Service not found. Tell me where to start looking for a problem?

After the last HACS update, sensor.hacs is not working?

Do you mean here:

card-mod-root: |
  ha-app-layout {
    background: url('/local/background.png');
    background-size: cover; 

?

I see no red notification over the update button, if I get new updates, but no error logs.

Anyone else with this problem?

After the last HACS update, something had to change and sensor.hacs is unavailable. I have updates in HACS but no notifications.

Yes.
/local/ = /config/www/

After updating, sensor.hacs was removed

I am not that advanced, unfortunately this is not working for me to get a background.

  1. I upload the image in /config/www/
  2. I use the code like below:

####################################################

CARD-MOD

####################################################

card-mod-theme: tablet

card-mod-root: |
  ha-app-layout {
    background: url('/config/www/bg.png'); 
    background-size: cover;
  }x

card-mod-view-yaml: |
  .: |
    hui-view {
      background: none !important;
      min-height: 100vh;
    }

Am I doing something wrong? (maybe the background: none !important; is wrong but not sure