A different take on designing a Lovelace UI

Ended up solving it (partially) like this. The only issue now is I want to change the button color to on state dependent on the state of the switch triggered in my tap_action. Doable?

      - type: custom:button-card
        entity: sensor.laddbox
        tap_action:
          action: call-service
          service: switch.toggle
          service_data:
            entity_id: switch.laddbox_mode
        hold_action: !include popup/car.yaml
        template:
          - base_charge
        aspect_ratio: 1/1
        show_icon: false
        show_name: false
        show_state: false
        show_label: false
        styles:
          grid:
            - grid-template-areas: |
                "LaddV LaddH"
                "LaddV LaddH"
            - grid-template-columns: 1fr 1fr
            - grid-template-rows: 1fr 1fr
            - gap: 2%
          card:
            - padding: 5%
          name:
            - place-self: start
            - margin-left: 10px
            - text-transform: uppercase
            - font-weight: 400
        custom_fields:
          LaddV:
            card:
              type: custom:button-card
              entity: sensor.laddbox
              template: charge_custom_fields
              icon: false
              size: 120%
              entity_picture: >
                [[[
                  const stateImages = {
                    'CHARGING_FINISHED': '/local/laddbox_green.png',
                    'CHARGING_CANCELLED': '/local/laddbox_green.png',
                    'CHARGING_PAUSED': '/local/laddbox_green.png',
                    'NOT_CONNECTED': '/local/laddbox_green.png',
                    'CONNECTED': '/local/laddbox_green.png',
                    'SEARCH_COMM': '/local/laddbox_green.png',
                    'CHARGING': '/local/laddbox_blue.png',
                    'RCD_FAULT': '/local/laddbox_red.png',
                    'OVERHEAT': '/local/laddbox_blue.png',
                    'CRITICAL_TEMPERATURE': '/local/laddbox_red.png',
                    'INITIALIZATION': '/local/laddbox_green.png',
                    'CABLE_FAULT': '/local/laddbox_red.png',
                    'LOCK_FAULT': '/local/laddbox_red.png',
                    'CONTACTOR_FAULT': '/local/laddbox_red.png',
                    'VENT_FAULT': '/local/laddbox_red.png',
                    'DC_ERROR': '/local/laddbox_red.png',
                    'DISABLED': '/local/laddbox_off.png',
                    'UNAVAILABLE': '/local/laddbox_blue.png',
                    'REMOTE_DISABLED': '/local/laddbox_blue.png',
                    'DC_HARDWARE': '/local/laddbox_red.png',
                    'CP_FAULT': '/local/laddbox_red.png',
                    'CP_SHORTED': '/local/laddbox_red.png'
                    // Add other states and their respective image paths here
                  };
            
                  const mainAttributes = states['sensor.laddbox'].attributes['mainCharger'];
                  console.log('Main Charger Attributes:', mainAttributes);
            
                  const mainStatus = mainAttributes ? mainAttributes['connector'] : null;
                  console.log('Main Charger Connector Status:', mainStatus);
            
                  return stateImages[mainStatus] || `/local/laddbox_${mainStatus === 'NOT_CONNECTED' ? 'off' : 'green'}.png`;
                ]]]
              styles:
                card:
                  - ... # Add styles for the card here
          LaddH:
            card:
              type: custom:button-card
              entity: sensor.laddbox
              template: charge_custom_fields
              icon: false
              size: 120%
              entity_picture: >
                [[[
                  const stateImages = {
                    'CHARGING_FINISHED': '/local/laddbox_green.png',
                    'CHARGING_CANCELLED': '/local/laddbox_green.png',
                    'CHARGING_PAUSED': '/local/laddbox_green.png',
                    'NOT_CONNECTED': '/local/laddbox_green.png',
                    'CONNECTED': '/local/laddbox_green.png',
                    'SEARCH_COMM': '/local/laddbox_green.png',
                    'CHARGING': '/local/laddbox_blue.png',
                    'RCD_FAULT': '/local/laddbox_red.png',
                    'OVERHEAT': '/local/laddbox_blue.png',
                    'CRITICAL_TEMPERATURE': '/local/laddbox_red.png',
                    'INITIALIZATION': '/local/laddbox_green.png',
                    'CABLE_FAULT': '/local/laddbox_red.png',
                    'LOCK_FAULT': '/local/laddbox_red.png',
                    'CONTACTOR_FAULT': '/local/laddbox_red.png',
                    'VENT_FAULT': '/local/laddbox_red.png',
                    'DC_ERROR': '/local/laddbox_red.png',
                    'DISABLED': '/local/laddbox_off.png',
                    'UNAVAILABLE': '/local/laddbox_blue.png',
                    'REMOTE_DISABLED': '/local/laddbox_blue.png',
                    'DC_HARDWARE': '/local/laddbox_red.png',
                    'CP_FAULT': '/local/laddbox_red.png',
                    'CP_SHORTED': '/local/laddbox_red.png'
                    // Add other states and their respective image paths here
                  };
            
                  const twinAttributes = states['sensor.laddbox'].attributes['twinCharger'];
                  console.log('Twin Charger Attributes:', twinAttributes);
            
                  const twinStatus = twinAttributes ? twinAttributes['connector'] : null;
                  console.log('Twin Charger Connector Status:', twinStatus);
            
                  return stateImages[twinStatus] || `/local/laddbox_${twinStatus === 'NOT_CONNECTED' ? 'off' : 'green'}.png`;
                ]]]
            
              styles:
                card:
                  - ... # Add styles for the card here

´´´

you complicate things too much, I recommend to check the documents from custom button card.

I follwed the install steps, and have two questions:

None of the popups work, I have tried adding the patch you mentioned above, but still nothing.

And second, the upcoming media card, I use emby and tried to change the sensor to the emby upcoming media, but nothing works. Any ideas?

How? I tried to get the state for the images from outside the card, but the dual images didn’t show up. I AM obvioulsy a newbie here, and as such I have read the documentation. Yet I find it a bit challenging what’s in the templates as CSS, what’s built into the card and so on.

Do this using variables, where you can add external sensors or whatever to change the card. In your case I would make two cards using horizontal cards side by side. Try to come up with a simple way, you can message me and I’ll try to help you as much as I can.

Hello. Was there any change with kiosk-mode? Why is the menu at the top appearing? Does anyone know how to correct it?

Another thing I can’t do is temporarily disable the bar
http://192.168.1.4:8123/lovelace/0?disable_km

I can’t access the left menu in any way.
Thank you

I dont know what exactly fixed the problem but it works again. Well except for the popups. Looks like Browser mod changed:


Do you know what changed in the past versions with the popups?

1 Like

Hi,

can someone help me out with this code.
I have a google nest protect that i want to make as a button card in mattias config, i need help with the code.

im thinking something like this:
But i needs to be blinking red for exempel when its a fire/smoke detected and so on…
And i dont want 4 row like in the link, only one card button row to fit mattias config. Can be design by somene here.

Skärmavbild 2023-11-24 kl. 20.58.44

Link to the code

type: custom:auto-entities
card:
  square: false
  columns: 4
  type: grid
card_param: cards
filter:
  include:
    - entity_id: '*nest_protect*'
      attributes:
        device_class: heat
      options:
        type: vertical-stack
        cards:
          - type: custom:button-card
            show_name: false
            show_icon: false
            aspect_ratio: 1/1
            extra_styles: |
              @keyframes bgswap_red {
                0% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
                50% {
                  background-image: url("/local/images/protect/nestprotect-red.png");
                }
                100% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
              }
              @keyframes bgswap_green {
                0% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
                50% {
                  background-image: url("/local/images/protect/nestprotect-green.png");
                }
                100% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
              }
              @keyframes bgswap_grey {
                0% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
                100% {
                  background-image: url("/local/images/protect/nestprotect-grey.png");
                }
              }
            styles:
              card:
                - animation: >
                    [[[ if
                    (states[entity.entity_id.replace('heat','smoke')].state ==
                    'off' && states[entity.entity_id.replace('heat','co')].state
                    == 'off') return 'bgswap_grey 2s linear infinite'; else
                    return 'bgswap_red 2s linear infinite';]]]
                - background-size: cover
            entity: this.entity_id
          - show_name: true
            show_icon: false
            type: custom:button-card
            tap_action:
              action: toggle
            entity: this.entity_id
            styles:
              name:
                - font-size: 12px
sort:
  method: name
  numeric: false
  reverse: false

i also forgot:
I want to make a popup when i double tap on the card to show something like this

i see that the newer versions of the dasboard has the fixes for my errors, but i also see the whole setup is build up different, the newer version has button_card_templates folder with sub files in stead of the seperate file with the settings…

if i overwrite my files with the newest version files my dashboard is not working anymore…
can someone please give me a solution for this?

i use this dashboard for 3 years now, i think my version is from march 2020…

thanks in advance!

@VietNgoc hope you can help me wrap my head arround this in your code

I’m trying to implement my plex_recently_added sensor with your added_movies ( recently added movies) section. But my button card shows up blank, with the upcoming tv show on next slide

would this template sensor not work with your added_movies button template? I know I don’t have all the arrays as in the original.


  - sensor:
      - unique_id: added_movies_2
        name: 'Added movies_2'
        state: >-
          {% if has_value("sensor.added_movies_2") %}
            {{ states.sensor.plex_recently_added.attributes.data[1].title }}
          {% endif %}
        attributes:
          data: |
            [
            {%- for movie in states.sensor.plex_recently_added.attributes.data[1:2] -%}
              {
                "title": "{{ movie.title if movie.title is defined else 'Unknown' }}",
                "original_title": "{{ movie.title if movie.title is defined else 'Unknown' }}",
                "number": "{{ movie.number if movie.number is defined else 'Unknown' }}",
                "genre": "{{ movie.genre if movie.genre is defined else 'Unknown' }}",
                "entity_picture": "{{ movie.poster if movie.poster is defined else 'Unknown' }}"
              },
            {%- endfor %}
            ]
          unit_of_measurement: movies
          icon: mdi:movie

This is the data from the sensor.plex_recently_added

data: 
- title: Invincible (2021)
  original_title: Invincible (2021)
  number: S02E04
  genre: Unknown
  entity_picture: /local/Plex_Recently_Added/p14979.jpg

unit_of_measurement: movies
icon: mdi:movie
friendly_name: Added movies_2

can you guide me in the right direction, thanks

This template will definitely not work with a plex sensor or similar. I have my own restful sensor that pulls data from the movie streaming service website I use. I don’t download movies anywhere.

My sensor looks like this, practically it’s just information about subtitles, dubbing, quality etc.

Hoping someone can help, but I will also post this to the custom button card thread. Following instructions posted above, I was able to implement a countdown for timers on my fan card. I would also like to incorporate a progress bar across the bottom of the card using another custom card (timer-bar-card). I can get that card to show just the progress bar, but I am struggling to force it to the bottom of the card. It gets placed right between my name and label. When the timer starts, I would like the progress bar to be all the way across the bottom of the card and as time reduces, so will the progress bar. Here is what the card is looking like when I use it.

image

Here is my fan card code.

fan2:
  template:
    - base
  variables:
    timer: >
      [[[ return states["timer.fan_delay"].state == 'active' ]]]
  tap_action:
    action: toggle
  double_tap_action:
    action: more-info
    entity: timer.fan_delay
  styles:
    custom_fields:
      circle:
        - display: initial
        - width: 88%
        - margin: -3% 2% 0 0
        - justify-self: end
        - opacity: 1
      timer:
        - position: absolute
        - bottom: 0%
        - left: 0%
        - width: 100%
        - margin: 0 0 0 0
  custom_fields:
    circle:
      card:
        type: custom:button-card
        entity: timer.fan_delay
        aspect_ratio: 1/1
        show_icon: false
        show_name: false
        show_state: |
          [[[
            if (states['timer.fan_delay'].state == 'active')
              return true;
            return false;
          ]]]
        styles:
          card:
            - border: none
          state:
            - font-size: 12px
            - color: var(--contrast1)
    timer:
      card:
        type: custom:timer-bar-card
        entity: timer.fan_delay
        bar_width: 100%
        bar_height: 6px
        layout: full_row
        text_width: 0px
        invert: true
        bar_foreground: >
          [[[
            return variables.timer
                ? '#3182b7'
                : '#97989c';
          ]]]
        bar_background: var(--contrast20)
        modifications:
          - elapsed: 90%
            bar_foreground: 'rgb(255,0,0)'
        styles:
          card:
            - padding: 0px

Here is my altered base code to add the timer row at the bottom.

base:
  template:
    - settings
    - extra_styles
  variables:
    state_on: >
      [[[ return ['on', 'home', 'heat_cool', 'Complete', 'Running', 'Fresh', 'Charging', 'Started'].indexOf(!entity || entity.state) !== -1; ]]]
    state: >
      [[[ return !entity || entity.state; ]]]
    entity_id: >
      [[[ return !entity || entity.entity_id; ]]]
    entity_picture: >
      [[[ return !entity || entity.attributes.entity_picture; ]]]
  aspect_ratio: 1/1
  show_state: false
  show_label: false
  show_icon: false
  styles:
    grid:
      - grid-template-areas: |
          "icon   circle"
          "n      n"
          "l      l"
          "s      s"
          "timer  timer"
      - grid-template-columns: repeat(2, 1fr)
      - grid-template-rows: auto repeat(4, min-content)
      - gap: 1.3%
      - align-items: start
      - will-change: transform
    name:
      - justify-self: start
      - line-height: 110%
      - font-size: 15px
      - font-weight: bold
    state:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    label:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    card:
      - border-radius: 10px
      - border-width: 0px
      - -webkit-tap-highlight-color: rgba(0,0,0,0)
      - transition: none
      - --mdc-ripple-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - background-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast20)'
                : 'rgba(115, 115, 115, 0.25)';
          ]]]

add styles for area time in template base, something like this

styles:
      timer:
        - bottom: -40%
        - width: 130%
        - position: absolute

@Mattias_Persson Im hoping you could help me. I love the work you have done and I have been able to get most things working:

  1. Where do i get the sensors.yaml file from? as I suspect im missing a few sensors.
  2. I tried changing the entity for upcoming media from plex to emby, but nothing shows. Any ideas on why? They both work with the upcoming media card.

Wanted to add a card type: tile for the climate popup but got an error that Unknown type encountered: tile. It’s a built-in card, so I expected it to work. The reason I want to use it is for the presets. Mushroom doesn’t support it to my knowledge (only heating and off). Could anyone please help me out?

This is what I wanted to add:

entities:
  - type: tile
    entity: climate.nappali_dual_smart_thermostat
    features:
      - style: icons
    	preset_modes:
    	  - eco
    	  - home
    	  - comfort
    	type: climate-preset-modes
      - type: target-temperature
    tap_action:
      action: more-info
    hide_state: false
    state_content:
      - current_temperature
      - hvac_action

This also shows an error:

- type: thermostat
  entity: climate.nappali_dual_smart_thermostat

I tried to add something like that. I removed the overlap, but moved everything else way up on the card and still did not push the progress bar to the bottom or expand for the full width. I added the timer styles to the base code. See below. I tried to move the left point and adjusted the width to account for the card padding that is included in the extra_styles template. It didn’t seem to change anything though.

image

base:
  template:
    - settings
    - extra_styles
  variables:
    state_on: >
      [[[ return ['on', 'home', 'heat_cool', 'Complete', 'Running', 'Fresh', 'Charging', 'Started'].indexOf(!entity || entity.state) !== -1; ]]]
    state: >
      [[[ return !entity || entity.state; ]]]
    entity_id: >
      [[[ return !entity || entity.entity_id; ]]]
    entity_picture: >
      [[[ return !entity || entity.attributes.entity_picture; ]]]
  aspect_ratio: 1/1
  show_state: false
  show_label: false
  show_icon: false
  styles:
    grid:
      - grid-template-areas: |
          "icon   circle"
          "n      n"
          "l      l"
          "s      s"
          "timer  timer"
      - grid-template-columns: repeat(2, 1fr)
      - grid-template-rows: auto repeat(3, min-content) auto
      - gap: 1.3%
      - align-items: start
      - will-change: transform
    name:
      - justify-self: start
      - line-height: 110%
      - font-size: 15px
      - font-weight: bold
    state:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    label:
      - justify-self: start
      - line-height: 110%
      - font-size: 12px
    timer:
      - position: absolute
      - bottom: -40%
      - left: -10.9%
      - width: 121%
    card:
      - border-radius: 10px
      - border-width: 0px
      - -webkit-tap-highlight-color: rgba(0,0,0,0)
      - transition: none
      - --mdc-ripple-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - color: >
          [[[
            return variables.state_on
                ? 'var(--contrast1)'
                : '#97989c';
          ]]]
      - background-color: >
          [[[
            return variables.state_on
                ? 'var(--contrast20)'
                : 'rgba(115, 115, 115, 0.25)';
          ]]]

I have been playing with values all morning. It seems the card is stuck on the “bottom” value. I moved the styling back into my template card. I can change the width and left values and get the bar to where I want it. It doesn’t matter what change I put in for bottom though, the bar will not budge vertically.

I tried changing it to “top” instead of “bottom” and it moved the bar to the bottom, but once there, it won’t budge based on the value I put in. It stays in the same location and is not visible on my mobile device.

image

So at this point I am 70% of the way there, but struggling to get the card to accept any vertical changes.

Entities Card doesn’t accept other built-in cards.

remove rows area “timer” from base template. work only in fan template. edit custom_fields for timer.

styles:
  custom_fields:
      timer:
        - bottom: -40%
        - width: 130%
        - position: absolute