A different take on designing a Lovelace UI

Hi!

First of all I need to say a big thanks for sharing your work, it’s amazing!

So I started working on an adaptation to my needs, and I’m a bit puzzle on how to integrate a time-picker-card (https://github.com/GeorgeSG/lovelace-time-picker-card)

I would rather not use a popup for this, and I really don’t see how I could achieve a time picker in a card.
ideally, I would also like an icon that can be colored or not depending on the state of the automation (if active or not)

Could you guide me as how I could achieve this? Also, I’m really starting with home assistant coding so don’t assume much knowledge here :stuck_out_tongue:

Thanks in advance!

This is solved by cloning the repositories in your git and then adding them manually from the three points used to add custom repositories

@Mattias_Persson

perhaps you can help me by a problem, i tried to add a gif with the gradient, the gif should be under the gravient, but i dont get it to work.

its saved under entity_picture

extra_styles: |
                [[[
                  let entity_picture = '/local/weather_back/test3.gif';
                  let cardBgColor = 'rgba(43, 104, 233, 1)';
                  let cardBgImage = 'linear-gradient(0deg, rgba(43, 104, 233, 1) 0%, rgba(85, 187, 240, 1) 100%)';
                  if (entity && entity.state) {
                    switch(entity.state) {
                      case 'partlycloudy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'linear-gradient(0deg, rgba(117,121,128,1) 0%, rgba(90,113,157,1) 38%, rgba(94,108,136,1) 100%)**, url(' + entity_picture +** ')';
                        break;

Hey There,
how would you guys recommend maintaining the Dasboard from matt locally?

Do you have a local git repo where you merge every few weeks or so, or has someone of you automated the merging?

Do you have a full example and an image to illustrate?

alarm

This should keep you busy

- type: custom:button-card
  entity: light.dator
  name: >
    [[[ return ' '; ]]]
  state_display: Alarm
  template:
    - base
  custom_fields:
    time:
      card:
        type: custom:time-picker-card
        entity: input_datetime.alarm_time
        hide:
          name: true
        card_mod:
          style:
            .: |
              .time-picker-content {
                justify-content: space-evenly !important;
                padding-right: 1%;
              }
              .time-separator {
                color: rgba(255, 255, 255, 0.3);
              }
              .time-picker-row {
                display: block !important;
                padding: 0 !important;
                overflow: hidden !important;
              }
              .time-input {
                border-radius: 10px;
              }
              :host {
                --time-picker-elements-background-color: rgba(0, 0, 0, 0.15);
                --time-picker-icon-color: rgba(255, 255, 255, 0.4);
                --time-picker-text-color: rgba(255, 255, 255, 0.6);
                --time-picker-control-padding: 6px;
              }
            time-unit:
              $: |
                .time-input {
                  border-radius: 0.4vw;
                }
                .time-unit {
                  padding: 0 !important;
                }
  styles:
    custom_fields:
      time:
        - position: absolute
        - width: 100%
        - height: 80%
        - clip-path: inset(0 round var(--custom-button-card-border-radius))
        - left: 0
        - top: -8%
  tap_action:
    action: none
  hold_action:
    action: call-service
    service: light.toggle
    service_data:
      entity_id: light.dator
3 Likes

Yes, use the base template

Here’s the reason if anyone’s interested

1 Like

https://community.home-assistant.io/t/a-different-take-on-designing-a-lovelace-ui/162594/2726

This example is correct https://community.home-assistant.io/t/a-different-take-on-designing-a-lovelace-ui/162594/3177

You probably haven’t set up card-mod/theme correctly. It’s not fully applied because the headers don’t line up and footer is not centered

Thanks for the info @Mattias_Persson. Glad they are archived so we can copy/install them if needed. I am more worried about them breaking as this tends to happen from time to time as HA progresses in capability. However, today is not that day (cross fingers) :smiley:

1 Like

Sorry for the late reply. I’m sure you’ve figured out a way to solve this by now, but this is what I’ve done :slight_smile:

  - delay:
      hours: 0
      minutes: 2
      seconds: 0
      milliseconds: 0
  - service: browser_mod.close_popup
    data: {}

(automations.yaml)

1 Like

Wow, great, a lot of thanks! I’ll try that asap.

Hello,

yes, this is the default card with the gradient

test1

here is the card with my gif

test

i want that the gif is under the gradient, or the gradient over the gif.

here is the full code, under extra styles i actually replaced the gradient, but i want the gradient + gif.

weather:
      variables:
        rain: ''        
            
      entity_picture: |
        [[[
          return entity && entity.state
            ? `/local/animated-weather-icons/${entity.state}.svg`
            : '?';
        ]]]
      name: |
        [[[
          return entity && entity.attributes && entity.attributes?.temperature
            ? `${entity.attributes.temperature.toFixed(0)}<sup>°</sup>`
            : '?';
        ]]]
        
      custom_fields:
        rain: |
          
            [[[
              return entity && entity.attributes && entity.attributes?.temperature
                ? `${states[variables.rain].state} % Regen`
                : '?';
            ]]]
            
        home: |
          
            [[[
              return entity 
                ? `Heggen`
                : '?';
            ]]]
       
      show_icon: true
      show_state: false
      show_label: false
      show_entity_picture: true
      aspect_ratio: 1/1
      styles:
        
       
        ############################################################################
        #       GRID (#container)
        ############################################################################
        grid:
          - grid-template-areas: |
              'i'
              'home'
              'n'
              'rain'
            
          - grid-template-columns: 1fr
          - grid-template-rows: min-content repeat(2, 1fr) repeat(2, min-content)
          - gap: 0%
        entity_picture:
          - position: relative
          - margin-top: 0px
          - margin-left: -45%
        icon:
          - align-self: left
          - justify-self: flex-end
        name:
          - justify-self: flex-end
          - font-size: 1.4rem
          - margin-top: 10%
          - margin-bottom: 15%
          - font-weight: bold
          - text-transform: lowercase
        label:
          - width: 100%
        state:
          - justify-self: start
        card:
          - border-radius: var(--custom-button-card-border-radius)
          - padding: 1rem
          - height: 100%
          - background-position: center
          - background-repeat: no-repeat
#          - background-image: >
#                [[[
#                  
#                  return variables.entity_picture === undefined 
#                    ? 'linear-gradient(0deg, rgba(117,121,128,1) 0%, rgba(90,113,157,1) 38%, rgba(94,108,136,1) 100%)'
#                    : 'linear-gradient(0deg, rgba(0,0,0,.1) 0%, rgba(0,0,0,0) 100%), url(' + entity_picture + ')';
#                   
#                ]]]
        color: |
              [[[
                const active = 'var(--nolu-color-active, rgb(22, 22, 22))';
                const inactive = 'var(--nolu-color-inactive, rgb(245, 245, 245))';
                const onState = ['on', 'auto', 'home', 'active', 'enabled', 'heat', 'cool', 'heat_cool', 'fan', 'open'];
                const offState = ['off', 'unknown', 'unavailable', 'disabled', 'closed', 'not_home'];
                return variables && variables.state && onState.some(state => variables.state.toLowerCase() === state) 
                  ? active 
                  : inactive;
              ]]]
              
        
        ############################################################################
        #       CUSTOM FIELDS
        ############################################################################
        custom_fields:
          home:
            - width: 200%
            - place-self: start
            - margin-left: -73%
            - margin-top: 0px
            - font-size: 1.2rem
            - font-weight: light  
          rain:
            - justify-self: flex-end
            - font-size: 0.9rem
            - font-weight: light
      # https://developers.home-assistant.io/docs/core/entity/weather/#recommended-values-for-state-and-condition
      extra_styles: |
                [[[
                  let caase_rainy = '/local/weather_back/rainy1.gif';
                  let caase_cloudy = '/local/weather_back/cloudy.gif';
                  let caase_partly_cloudy = '/local/weather_back/partly_cloudy.gif';
                  let cardBgColor = 'rgba(43, 104, 233, 1)';
                  let cardBgImage = 'linear-gradient(0deg, rgba(43, 104, 233, 1) 0%, rgba(85, 187, 240, 1) 100%)';
                  if (entity && entity.state) {
                    switch(entity.state) {
                      case 'partlycloudy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'url(' + caase_partly_cloudy + ')';
                        break;
                      case 'cloudy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'url(' + caase_cloudy + ')';
                        break;
                      case 'pouring':
                      case 'rainy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'url(' + caase_rainy + ')';
                        break;
                      case 'clear-night':
                        cardBgColor = 'rgb(7,21,45)';
                        cardBgImage = 'linear-gradient(0deg, rgba(7,21,45,1) 0%, rgba(18,45,97,1) 38%, rgba(1,11,32,1) 100%)';
                        break;
                      case 'xxxxx':
                        cardBgColor = '';
                        cardBgImage = '';
                        break;
                    }
                  }
                  return `
                    #aspect-ratio {
                      height: 100%;
                    }
                    #name > sup {
                      color: rgba(255, 255, 255, 0.5);
                      font-size: 2rem;
                    }
                    #wind span,
                    #humidity span,
                    #visibility span {
                      display: block;
                      width: 100%;
                      text-align: center;
                    }
                    #wind ha-icon,
                    #humidity ha-icon,
                    #visibility ha-icon {
                      --mdc-icon-size: 20px;
                      margin-top: 0.5rem;
                    }
                    #wind #title,
                    #humidity #title,
                    #visibility #title {
                      font-size: 0.95rem;
                      font-weight: 500;
                      margin-top: 0.5rem;
                    }
                    #title b {
                      font-size: 0.85rem;
                      color: rgba(255, 255, 255, 0.6);
                    }
                    #wind #subtitle,
                    #humidity #subtitle,
                    #visibility #subtitle {
                      color: rgba(255, 255, 255, 0.6);
                      font-size: 0.90rem;
                      margin-top: 0.5rem;
                      overflow: hidden;
                      text-overflow: ellipsis;
                      white-space: nowrap;
                    }
                    #card {
                      background-color: ${cardBgColor};
                      background-image: ${cardBgImage};
                    }
                    @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);
                      }
                    }
                  `;
                ]]]

i hope you understand what i mean :smiley:

here is the original code with the gradient

switch(entity.state) {
                      case 'partlycloudy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'url(' + entity_picture + ')';
                        cardBgImage = 'linear-gradient(0deg, rgba(117,121,128,1) 0%, rgba(90,113,157,1) 38%, rgba(94,108,136,1) 100%)';
                        break;
                      case 'cloudy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'linear-gradient(0deg, rgba(117,121,128,1) 0%, rgba(117,121,128,1) 38%, rgba(94,108,136,1) 100%)';
                        break;
                      case 'pouring':
                      case 'rainy':
                        cardBgColor = 'rgb(117,121,128)';
                        cardBgImage = 'linear-gradient(0deg, rgba(117,121,128,1) 0%, rgba(90,113,157,1) 38%, rgba(94,108,136,1) 100%)';
                        break;
                      case 'clear-night':
                        cardBgColor = 'rgb(7,21,45)';
                        cardBgImage = 'linear-gradient(0deg, rgba(7,21,45,1) 0%, rgba(18,45,97,1) 38%, rgba(1,11,32,1) 100%)';
                        break;
                      case 'xxxxx':
                        cardBgColor = '';
                        cardBgImage = '';
                        break;
6 Likes

Ah, cool. Don’t have time to test but have you played around with z-index in your browser devtools?

If that doesn’t work try a one-liner

background-image: linear-gradient(to bottom, rgba(245, 246, 252, 0.52), rgba(117, 19, 93, 0.73)), url('images/background.jpg');
1 Like

i tested the one liner, but then the gif is not visible, only the gradient.

cardBgImage = 'linear-gradient(to bottom, rgba(117,121,128,1) 0% , rgba(90,113,157,1) 38%), url(' + caase_cloudy + ')';

test1

i dont know where to add the Z-Index in my code
the problem is i generate the gradient and the gif with the one liner above, and there i cant add the z-index

when i put the gif before the gradient, then the gif is visible but not the gradient

cardBgImage = 'url(' + caase_cloudy + '),linear-gradient(to bottom, rgba(117,121,128,1) 0% , rgba(90,113,157,1) 38%)';

rgbA, your alpha channel is fully opaque

Where did you get the gifs for the background like that?

thats correct, but not the problem, here is my corrected code

cardBgImage = 'linear-gradient(to bottom, rgba(117,121,128,1) 10% , rgba(90,113,157,1) 38%), url(' + caase_partly_cloudy + ')';

when i use the same code but with the gif at the start before the gradient, the gif is visible but not the gradient,.

but the gif is not visible, its only possible to show one , the gradient or the gif, i found no solution.

My dude, opaque means nontransparent. You can’t see your gif if you set alpha to 1

cardBgImage = 'linear-gradient(to bottom, rgba(117,121,128,0.7) 10% , rgba(90,113,157,0.7) 38%), url(' + caase_partly_cloudy + ')';
1 Like

Thanks i set everything good also i learn too much things for yaml and js. But i have problem with fullykiosk cache. If anyone have solution, i need it.
Fully kiosk never delete cache even i select “never use cache”. Tried quit then login just once everything good. After that when auto Reload done new visual gone :frowning: (using pro version)

ps: my english bad but im trying to select best words for my problem.

thanks for your help