A different take on designing a Lovelace UI

The original one is set up like this. If the entity state is ‘cool’, it’ll display entity.attributes.temperature if the state is anything other than cool, it’ll display entity.attributes.current_temperature. If your device doesn’t have those attributes, you’ll have to modify the circle_input for that button card.

Thank you for clarifying, However my air cleaner from Electrolux does not have attributes… Is it possible to add a entity instead?

yep, you should add the temp sensor entity to triggers_update: if you want the temp to update on the card without the button card entity updating. You’ll also want to modify circle_input to use the triggers_update entity. Here’s an example

- type: custom:button-card
  entity: climate.downstairs
  name: HVAC
  double_tap_action:
    !include popup/downstairs_climate.yaml
  triggers_update: sensor.fireplace_temp
  template:
    - base
    - icon_climate
    - circle
  variables:
    circle_input: "[[[ return Math.round(states[this._config?.triggers_update].state).toString(); ]]]"
    circle_input_unit: '°F'
4 Likes

Well… THANK YOU! <3
image

Hi Br3b, would you share the code from the weather widget? Mine looks like this…

Bildschirm­foto 2023-02-06 um 17.40.31

what do I have to adjust?

After spending lots of time a beautiful picture on the wall! Thanx a lot Mattias!!!

I read everything and learned a lot. But I’m not clear how the sidebar works.

The date has now disappeared, it was in the sidebar.yml, I placed it in a sidebar_time.yml, unfortunately that didn’t work either. It’s also not clear to me where to put what. Do you make a separate yml file for each item? Hopefully someone can help me with this. Can be done via DM or comment. Many thanks in advance!

Hi @weaverprojects,
the card template is not mine.
I just adjusted the “- margin-left: 10%” for all objects in the card. Hope it helps.

  widget_weather:
    variables:
      temp_min: ''
      temp_max: ''
      precip: ''
    aspect_ratio: 1/1
    show_icon: false
    show_entity_picture: true
    show_name: true
    show_state: true
    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(255, 255, 255, 0.8)
        - background: |
            [[[
              if (states['sun.sun'].state == 'below_horizon'){
                return 'linear-gradient(to top, rgba(53,59,83,1) 0%, rgba(10,14,34,1) 100%)';
              } else
                return 'linear-gradient(to top, rgba(123,168,197,1) 0%, rgba(61,132,176,1) 100%)';
            ]]]        
      state:
        - margin-left: 12%
      name:
        - place-self: start
        - margin-left: 10%
        - text-transform: uppercase
        - font-weight: 400
      img_cell:
        - margin-left: 10%
        - justify-content: start
      icon:
        - width: 25%
        - margin-left: 7%
      label:
        - margin-left: 7%
        - place-self: start
      custom_fields:
        temp:
          - place-self: start
          - margin-left: 10%
    custom_fields:
      temp: |
        [[[ return entity.attributes.temperature + "°"; ]]]    
    label: |
      [[[
          if (window.navigator.userAgent.match(/iPhone/i)) {
            return         `<ha-icon
            icon="mdi:arrow-up-thin"
            style="width: 15px; height: 15px; margin-right: -6px;">
            </ha-icon><span> ${states[variables.temp_max].state}°</span>
                  <ha-icon
            icon="mdi:arrow-down-thin"
            style="width: 15px; height: 15px; margin-right: -6px;">
            </ha-icon><span> ${states[variables.temp_min].state}° </span>       
          `;
                }
          else {
                    return `<ha-icon
            icon="mdi:arrow-up-thin"
            style="width: 15px; height: 15px; margin-right: -5px;">
            </ha-icon><span> ${states[variables.temp_max].state}°</span>
                  <ha-icon
            icon="mdi:arrow-down-thin"
            style="width: 15px; height: 15px; margin-right: -5px; margin-left: -5px;">
            </ha-icon><span> ${states[variables.temp_min].state}° </span>       
                  <ha-icon
            icon="mdi:weather-pouring"
            style="width: 14px; height: 14px; margin-right: -2px; margin-left: -1px;">
            </ha-icon><span> ${states[variables.precip].state}%</span>
          `}
      ]]]
    entity_picture: |
      [[[
        return entity && entity.state
          ? `/local/animated-weather-icons/${entity.state}.svg`
          : '?';
      ]]]
    extra_styles: |
      [[[
        return `
          #name {
            font-size: 1vw;
          }
          #temp {
            font-size: 1.9vw;
          }
          #state {
            font-size: 0.60vw;
          }  
          #label {
            font-size: 0.60vw;
          }
          /* portrait */
          @media screen and (max-width: 1200px) {
            #name {
              font-size: 1.3vw;
            }
            #temp {
              font-size: 4.5vw;
            }
            #state {
              font-size: 1.1vw;
            }  
            #label {
              font-size: 1.1vw;
            }
          }
          /* phone */
          @media screen and (max-width: 800px) {
            #name {
              font-size: 3vw;
            }              
            #temp {
              font-size: 2.5vw;
            }    
            #state {
              font-size: 1.8vw;
            }
            #label {
              font-size: 2.25vw;
            }
                   
          }
          @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);
            }
          }
        `
      ]]]
1 Like

sidebar.yaml (at least the one in the base directory) is nothing more than a template sensor. The sections themselves like time, date, greet are attributes of that sensor. If you look in button_card_templates/sidebar.yaml you’ll see how they’re displayed.

If you did want to separate things out or display some other info in a different template sensor, you can put yaml files in the packages folder, but include template: as the first line.

template:
  - sensor:
    ...

You’ll then have to add any new sensor to the sidebar section of ui-lovelace.yaml for it to show up.

A quick example would be
packages/sun_rising.yaml

template:
  - sensor:
    - unique_id: Sun Rising
      state: template
      attributes:
        sun: >
          {% if is_state("sun.sun", "above_horizon") -%}
            The sun rose {{ relative_time(states.sun.sun.last_changed) }} ago.
          {%- else -%}
            The sun will rise at {{ as_timestamp(state_attr('sun.sun', 'next_rising'), '%Y-%m-%d %H:%M:%S') | timestamp_custom("%A @ %-I:%M %p") }}.
          {%- endif %}

ui-lovelace.yaml

...
      #################################################
      #                                               #
      #                    SIDEBAR                    #
      #                                               #
      #################################################

      - type: vertical-stack
        view_layout:
          grid-area: sidebar
        cards:

          - type: custom:button-card
            entity: sensor.template_sidebar
            template: sidebar

          - type: custom:button-card
            entity: sensor.sun_rising
            template: sidebar
...

An alternate option is creating new attributes in sidebar.yaml to display whatever you want. Those will automatically be added since the sidebar template loops through all available attributes of the sensor.

1 Like

Hey guys, any idea how i can change this gap:

THNX!! Did the trick!

hello,

i tried to replace the background of the theme, its the background.png under local or www or?

i tried to replace an reboot and deletet my browser cache but no luck

Just add a padding in the template

... card:
      - padding: 10.9% 9.9% 8.9% 10.9%;
 #Additional padding to the template (Based on the % found on the extra_styles.yaml)
1 Like

check what path you have assigned based on the themes.yaml file
Matts is like:

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

The file would be in: www/background.png

Based on my own experiences the background was sometimes missing (full-on black) when a card would be broken (Erroring out). Not sure why is this thing; but that’s what I use as an early identifier of a broken card sometimes😂

Hi!

Sorry for the stupid question, but how can I add more icons like (wall sockets, motion sensors) the same way you did with icon_alexa?

Many thanks.

hey this looks amazing well done. Can I just ask how have you got all the time remaining and temp control etc integrated from your washer/dryer? Is it a smart dryer?

Yes, I have an LG washer and dryer and use the LG ThinQ Devices integration.

1 Like

Hello, how do you make the button light up, the radiator only lights up if the heating is on or off but not when it is really heating up.

And since you have managed to do the temperature circle, I don’t quite understand the other partner’s code.

Thank you so much.

      - type: custom:button-card
        entity: climate.termostato
        name: Calefacción
        double_tap_action:
          !include popup/sovrum_klimat.yaml
        triggers_update: sensor.termostato_temperature
        template:
          - base
          - icon_climate
          - circle
        variables:
          circle_input: "[[[ return Math.round(states[this._config?.triggers_update].state).toString(); ]]]"
          circle_input_unit: '°C'

Hello and welcome! Maybe I can help clarify a little bit.

The code you posted is just for using an alternate sensor source to display a temperature in the circle. It won’t show the temperature difference using the circle as a scale. It will show up like this, with the outline always a full circle.

Getting the circle to show the temperature difference or a countdown is more involved. This is my original post about how to accomplish that, but I’m using it as a countdown to when my laundry is done.

And finally, if you want the button to stay “on” or lit up, you might need an alternate state_on variable in your button code.
The original code will only show a button as active or “on” if the entity state matches one of these states: 'on', 'home', 'cool', 'fan_only', 'playing', 'unlocked'. You can change that by defining an alternate state_on variable in specific buttons.

for instance, I do that with my washing machine by adding this

  variables:
    state_on: >
      [[[ return ['Detecting', 'Washing', 'Rinsing', 'Spinning'].indexOf(!entity || entity.state) !== -1; ]]]

You’ll have to look and see what the entity state is when it’s running vs when it’s off to figure out what states you should add.

1 Like

okay yeah it takes several minutes to load the new background after change and browser cache deleting.

has someone make a own background and whant to share ?

hi,
please, where can I find the correct SVG icons for dishwasher (mdi:dishwasher) and oven (mdi:stove) ?