🌻 Lovelace UI • Minimalist

Inspired by you all, my new fan card :slight_smile:
image

  • Small fan icon : decrease speed by 10%
  • Leaf icon : toggle “natural mode”
  • Rotate icon : toggle fan oscillating
  • Big fan icon : increase speed by 10%
6 Likes

Let me try to give you the starting points :slight_smile:

  • [Dashboards] This lovelace interface is better with yaml mode (because this is what the OP is using, less to adapt). I think you should start a new dashboard in yaml mode. You can keep your main dashboard in storage mode and create a new one in yaml mode.
    Check the doc here : Dashboards - Home Assistant (2nd code block, wich shows how to get the 1st dashboard in storage and adding some more dashboards in yaml)
  • [Theme] You MUST apply a theme, thus, you have to add the provided theme. Once again, check the docs here : Home Assistant Frontend - Home Assistant (check the split theme part, wich can be useful to organise better your configuration)
  • [Custom cards] A custom card is in use here (custom:button-card). You have to install it. I recommend usage of HACS (wich is an addon). Check : https://hacs.xyz/
    This will helps you a lot for managing/installing custom integrations or frontend things
  • [Addon] you will need to edit some yaml, then you need an editor. Use samba share and your prefered editor or the nice configurator official addon.

Once you setup this all, you’ll be better to start with this :slight_smile:
For sure you will have to learn, but now you have the tools !

3 Likes

One of my tablets GUI using this awesome work!
Sorry for the quality, I wanted to show it as it is on the tablet.
added some small tweaks like the flashing door stats(for an unlocked door) and spinning fan card.

ezgif.com-gif-maker (1)

3 Likes

Oh, spinning icon for the fan, love it ! Thx for the heads up on that !

@tben You can also generate a github link between the main commits. :slight_smile:

Same Problem here. The Conditional Card is using the horizontal space dynamically.

How it looks in Chrome Developer view:

And the CSS for the Element:

#root > * {
    flex: 1 1 0px;
    margin: var( --horizontal-stack-card-margin, var(--stack-card-margin, 0 4px) );
    min-width: 0px;
}

Tried to modify the CSS for the conditional card. But I am not so familiar with CSS. So without success until now.

1 Like

Created a new “room” navigation card…

button_card_temp

button_card_templates.yaml


########################################################################################################
#                                                                                                      #
#                                              ROOM                                                    #
#                                                                                                      #
########################################################################################################

  room:
    variables:
      name: ""
      path: ""
      label: ""
      icon: "mdi:home"
    name: >
        [[[
          return variables.name;
        ]]]
    label: >-
      [[[
          return variables.label;
      ]]]
    icon: |
      [[[
          return variables.icon;
      ]]]
    tap_action:
      action: navigate
      navigation_path: >
        [[[
          return variables.path;
        ]]]
    styles:
      name:
        - color: >
            [[[
                if (variables.image != null) {
                  return 'white';
                }
                return 'var(--primary-text-color)';
            ]]]
      label:
        - color:  >
            [[[
                if (variables.image != null) {
                  return 'white';
                }
                return '';
            ]]]
      icon:
        - color: >
            [[[
                if (variables.image != null) {
                  return 'white';
                }
                return 'rgba(var(--color-theme),0.2)';
            ]]]
      img_cell:
        - background-color: >
            [[[
                if (variables.image != null) {
                  return 'rgba(255,255,255,0.5)';
                }
                return 'rgba(var(--color-theme),0.05)';
            ]]]
      card:
        - background-blend-mode: multiply
        - background: >
            [[[
                if (variables.image != null) {
                  return 'center / cover url(' + variables.image + ') rgba(0, 0, 0, 0.5)';
                }
                return '';
            ]]]

example code


                  - type: custom:button-card
                    variables:
                      name: "Living Room"
                      label: "3 Devices"
                      path: "/lovelace/living_room"
                    template:
                      - icon_info_bg
                      - room
                  - type: custom:button-card
                    variables:
                      name: "Bureau"
                      label: "6 Devices"
                      path: "/lovelace/bureau"
                      image: "/local/images/tiles/desk.jpg"
                    template:
                      - icon_info_bg
                      - room
11 Likes

Hello @SNoof85
Could you share your card please? thank you

There you go :
Templates :

################################################################################
#                                                                              #
#                                VENTILO                                       #
#                                                                              #
################################################################################
  ventilo:
    tap_action:
      action: more-info
    icon: mdi:fan
    template: bleu_spin
    label: >-
      [[[ 
          if (entity.state == 'off'){
            return 'Off' + ' • ' + entity.attributes.raw_speed + '%';
          } else {
            return entity.attributes.raw_speed + '%';
          }
      ]]]
################################################################################
  ventilo_buttons:
    variables:
      entity: fan.xiaomi_smart_fan
      name: "Ventilateur"
    styles:
      card:
        - border-radius: 20px
        - box-shadow: var(--box-shadow)
        - padding: 12px
      grid:
        - grid-template-areas: '"item1" "item2"'
        - grid-template-columns: 1fr
        - grid-template-rows: min-content  min-content
        - row-gap: 12px
    custom_fields:
      item1:
        card:
          entity: '[[[ return variables.entity ]]]'
          name: '[[[ return variables.name ]]]'
          tap_action:
            action: toggle
          hold_action:
            action: more-info
          template:
            - icon_info
            - ventilo
          type: 'custom:button-card'
      item2:
        card:
          template: list_items
          type: 'custom:button-card'
          custom_fields:
            item1:
              card:
                icon: 'mdi:fan'
                styles:
                  icon:
                    - transform: scale(0.625)
                tap_action:
                  action: call-service
                  service: fan.decrease_speed
                  service_data:
                    entity_id: 'fan.xiaomi_smart_fan'
                    percentage_step: 10
                type: 'custom:button-card'
                template: widget_icon
            item2:
              card:
                icon: 'mdi:leaf'
                tap_action:
                  action: call-service
                  service: switch.toggle
                  service_data:
                    entity_id: 'switch.fan_natural_mode'
                type: 'custom:button-card'
                entity: 'switch.fan_natural_mode'
                template: 
                  - bleu
                  - widget_icon
            item3:
              card:
                icon: 'mdi:rotate-3d-variant'
                tap_action:
                  action: call-service
                  service: switch.toggle
                  service_data:
                    entity_id: 'switch.fan_oscilate'
                type: 'custom:button-card'
                entity: 'switch.fan_oscilate'
                template:
                  - bleu
                  - widget_icon
            item4:
              card:
                icon: 'mdi:fan'
                tap_action:
                  action: call-service
                  service: fan.increase_speed
                  service_data:
                    entity_id: 'fan.xiaomi_smart_fan'
                    percentage_step: 10
                type: 'custom:button-card'
                template: widget_icon
################################################################################
  bleu_spin:
    state:
      - value: 'on'
        spin: true
        styles:
          icon:
            - color: 'rgba(var(--couleur-bleu),1)'
          img_cell:
            - background-color: 'rgba(var(--couleur-bleu), 0.2)'
      - value: 'off'
        spin: false

Card :

            - template:
                - ventilo_buttons
              variables:
                entity: fan.xiaomi_smart_fan
                name: Ventilateur
              type: custom:button-card

:warning: there is still the old named templates that were in the 1st version of the git of Thomas… (bleu wich became blue i guess :thinking: )

I don’t know if you have a Xiaomi fan too, and if yes, if you know how to handle the toggle of natural mode and oscillating mode with switches. If help/code needed just let me know.

4 Likes

i like the spinning fan icon as well as the lock status.

can you share this?

Spining icon and blinking cards are in the button card documentation :slight_smile:

Spin : GitHub - custom-cards/button-card: ❇️ Lovelace button-card for home assistant
Blink : GitHub - custom-cards/button-card: ❇️ Lovelace button-card for home assistant

1 Like

thank you very much, I did not know that.

1 Like

I have problem with theme:

I added this in my configuration.yaml:

frontend: 
  themes: !include lovelace/themes/minimalist_theme.yaml

and this in minimalist_theme.yaml:

     #Couleurs
      google-red-500 : '#F54436'
      google-green-500 : '#01C852'
      google-yellow-500 : '#FF9101'
      google-blue-500 : '#3D5AFE'
      google-violet-500 : '#661FFF'
      google-grey-500: '#BBBBBB'
      couleur-rouge : 245, 68, 54
      couleur-vert : 1, 200, 82
      couleur-jaune : 255, 145, 1
      couleur-bleu : 61, 90, 254
      couleur-violet : 102, 31, 255
      couleur-gris : 187, 187, 187
      couleur-rose : 233, 30, 99
      couleur-theme : 51,51,51
      # Card
      card-background-color: '#FAFAFA'
      box-shadow: '0px 2px 4px 0px rgba(0,0,0,0.16)'
      border-radius: '20px'
      border-color: '#EAEAEA'
      primary-color: '#434343'
      light-primary-color: '#fce8e6'
      paper-item-icon-color: '#434343'
      paper-toggle-button-checked-ink-color: '#3D5AFE'
      paper-toggle-button-checked-button-color: '#3D5AFE'
      paper-toggle-button-checked-bar-color: '#3D5AFE'
      accent-color: '#ff8100'
      switch-checked-color: '#3D5AFE'
      #Sidebar
      sidebar-selected-text-color: '#d93025'
      sidebar-text-color: '#80868b'
      sidebar-selected-icon-color: '#d93025'
      sidebar-selected-background-color: '#fce8e6'
      mdc-theme-secondary: 'var(-primary-color)'
      #Slider
      slider-color: '#d93025'
      slider-bar-color: '#fce8e6'
      #Background
      secondary-background-color: '#EFEFEF'
      primary-background-color: '#EFEFEF'
      #Custom header
      couleur-header: 239, 239, 239
      couleur-elements: 33, 33, 33
      #Header
      app-header-text-color: '#434343' 
      app-header-background-color: '#EFEFEF'
      paper-tabs-selection-bar-color: '#434343'
      # Journal
      state-icon-color: '#434343'
      # Enlever le header
      card-mod-theme: light_mobile
      card-mod-root: |
        app-toolbar {
          display: none;
        }

I get error:

Invalid config for [frontend]: expected a dictionary for dictionary value @ data['frontend']['themes']['accent-color']. Got '#ff8100'
expected a dictionary for dictionary value @ data['frontend']['themes']['app-header-background-color']. Got '#EFEFEF'
expected a dictionary for dictionary value @ data['frontend']['themes']['app-header-text-color']. Got '#434343'
expected a dictionary for dictionary value @ data['frontend']['themes']['border-color']. Got '#EAEAEA'
expected a dictionary for dictionary value @ data['frontend']['themes']['border-radius']. Got '20px'
expected a dictionary for dictionary value @ data['frontend']['themes']['box-shadow']. Got '0px 2px 4px 0px rgba(0,0,0,0.16)'
expected a dictionary for dictionary value @ data['frontend']['themes']['card-background-color']. Got '#FAFAFA'
expected a dictionary for dictionary value @ data['frontend']['themes']['card-mod-root']. Got 'app-toolbar {\n display: none;\n}'
expected a dictionary for dictionary value @ data['frontend']['themes']['card-mod-theme']. Got 'light_mobile'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-bleu']. Got '61, 90, 254'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-elements']. Got '33, 33, 33'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-gris']. Got '187, 187, 187'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-header']. Got '239, 239, 239'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-jaune']. Got '255, 145, 1'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-rose']. Got '233, 30, 99'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-rouge']. Got '245, 68, 54'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-theme']. Got '51,51,51'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-vert']. Got '1, 200, 82'
expected a dictionary for dictionary value @ data['frontend']['themes']['couleur-violet']. Got '102, 31, 255'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-blue-500']. Got '#3D5AFE'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-green-500']. Got '#01C852'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-grey-500']. Got '#BBBBBB'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-red-500']. Got '#F54436'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-violet-500']. Got '#661FFF'
expected a dictionary for dictionary value @ data['frontend']['themes']['google-yellow-500']. Got '#FF9101'
expected a dictionary for dictionary value @ data['frontend']['themes']['light-primary-color']. Got '#fce8e6'
expected a dictionary for dictionary value @ data['frontend']['themes']['mdc-theme-secondary']. Got 'var(-primary-color)'
expected a dictionary for dictionary value @ data['frontend']['themes']['paper-item-icon-color']. Got '#434343'
expected a dictionary for dictionary value @ data['frontend']['themes']['paper-tabs-selection-bar-color']. Got '#434343'
expected a dictionary for dictionary value @ data['frontend']['themes']['paper-toggle-button-checked-bar-color']. Got '#3D5AFE'
expected a dictionary for dictionary value @ data['frontend']['themes']['paper-toggle-button-checked-button-color']. Got '#3D5AFE'
expected a dictionary for dictionary value @ data['frontend']['themes']['paper-toggle-button-checked-ink-color']. Got '#3D5AFE'
expected a dictionary for dictionary value @ data['frontend']['themes']['primary-background-color']. Got '#EFEFEF'
expected a dictionary for dictionary value @ data['frontend']['themes']['primary-color']. Got '#434343'
expected a dictionary for dictionary value @ data['frontend']['themes']['secondary-background-color']. Got '#EFEFEF'
expected a dictionary for dictionary value @ data['frontend']['themes']['sidebar-selected-background-color']. Got '#fce8e6'
expected a dictionary for dictionary value @ data['frontend']['themes']['sidebar-selected-icon-color']. Got '#d93025'
expected a dictionary for dictionary value @ data['frontend']['themes']['sidebar-selected-text-color']. Got '#d93025'
expected a dictionary for dictionary value @ data['frontend']['themes']['sidebar-text-color']. Got '#80868b'
expected a dictionary for dictionary value @ data['frontend']['themes']['slider-bar-color']. Got '#fce8e6'
expected a dictionary for dictionary value @ data['frontend']['themes']['slider-color']. Got '#d93025'
expected a dictionary for dictionary value @ data['frontend']['themes']['state-icon-color']. Got '#434343'
expected a dictionary for dictionary value @ data['frontend']['themes']['switch-checked-color']. Got '#3D5AFE'. (See /config/configuration.yaml, line 13).
Invalid config for [lovelace]: expected a list for dictionary value @ data['lovelace']['resources']. Got OrderedDict(). (See /config/configuration.yaml, line 9).

Answer to my question:

frontend: 
  themes: 
    minimalist: !include lovelace/themes/minimalist_theme.yaml

Another day, another card :

template:
  - icon_info_bg
  - personnes
  - popup_map
type: custom:button-card
entity: person.clemalex
show_entity_picture: true
entity_picture: /local/images/person/clemalex.png
variables:
  gps: google_maps #or 'waze' (open app on phone)
#les modèles (templates)
  personnes:
    show_label: true
    label: |
      [[[
        if (entity.state == 'home'){
          return "Domicile";
        }
        else if (entity.state == 'not_home'){
          return "En Balade";
        }else{
          return entity.state; //dans une zone
        }
      ]]]
    styles:
      entity_picture:
        - transform: scale(2)
      custom_fields:
        notification:
          - transform: scale(1.3)
          - border-radius: 50%
          - position: absolute
          - right: 8px
          - top: 8px
          - height: 16px
          - width: 16px
          - border: 2px solid var(--card-background-color)
          - font-size: 12px
          - line-height: 14px
          - background-color: |
              [[[
                if (entity.state == 'home'){
                  return "rgba(var(--couleur-bleu),1)";
                }else{
                  return "rgba(var(--couleur-vert),1)";
                }
              ]]]
    custom_fields:
      notification: |
        [[[
          var icon = "" ;
          if (entity.state == 'home'){
            icon="mdi:home-variant"
          }else{
              icon="mdi:pine-tree"
          }
          return `<ha-icon icon="${icon}" style="width: 10px; height: 10px; color: white;"></ha-icon>`
        ]]]
  popup_map:
    variables:
      gps: google_maps
    tap_action:
      action: fire-dom-event
      browser_mod:
        command: call-service
        service: browser_mod.popup
        service_data:
          deviceID:
            - this
          title: '[[[ return( "Position de " +  entity.attributes.friendly_name); ]]]'
          style:
            $: |
              .mdc-dialog {
                backdrop-filter: blur(5px) !important;
                -webkit-backdrop-filter: blur(5px) !important;
              }
            .: |
              mwc-icon-button ha-icon {
                font-size: 0;
              }
              .content{padding: 0 10px 10px 10px}
          card:
            type: vertical-stack
            cards:
              - template:
                  - map_card
                type: custom:button-card
                entity: '[[[ return entity.entity_id ]]]'
              - type: entities
                show_header_toggle: false
                entities:
                  - type: weblink
                    name: |
                      [[[
                        if (variables.gps.toUpperCase() == 'GOOGLE_MAPS'){
                          var gps = "(via Google Maps)"
                        }
                        else if (variables.gps.toUpperCase() == 'WAZE'){
                          var gps = "(via Waze)"
                        }
                        return('Itinéraire vers ' + entity.attributes.friendly_name + ' ' + gps);
                      ]]]
                    icon: mdi:map-marker-path
                    url: |
                      [[[
                        if (variables.gps.toUpperCase() == 'GOOGLE_MAPS'){
                          return('https://maps.google.com/maps?q='+entity.attributes.latitude+','+entity.attributes.longitude+'&t=&z=15');
                        }
                        else if (variables.gps.toUpperCase() == 'WAZE'){
                          return('waze://?ll='+entity.attributes.latitude+','+entity.attributes.longitude+'&z=15&navigate=yes');
                        }
                      ]]]
  map_card:
    show_name: false
    show_icon: false
    styles:
      card:
        - border-radius: 20px
        - box-shadow: var(--box-shadow)
        - padding: 12px
      grid:
        - grid-template-areas: '"item1"'
        - grid-template-columns: 1fr
        - grid-template-rows: min-content  min-content
        - row-gap: 12px
    custom_fields:
      item1:
        card:
          type: iframe
          url: |-
            [[[
              var lat = entity.attributes.latitude
              var long = entity.attributes.longitude
              return `https://maps.google.com/maps?q=${lat},${long}&t=&z=13&ie=UTF8&iwloc=&output=embed`
            ]]]
          aspect_ratio: 96%
#Présent de base
  icon_info_bg:
    color: var(--google-grey-500)
    show_icon: true
    show_name: true
    show_label: true
    size: 20px
    custom_fields:
      notification: |
        [[[
          if (entity.state =='unavailable'){
            return `<ha-icon icon="mdi:exclamation" style="width: 12px; height: 12px; color: white;"></ha-icon>`
          }
        ]]]
    state:
      - styles:
          custom_fields:
            notification:
              - border-radius: 50%
              - position: absolute
              - left: 38px
              - top: 8px
              - height: 16px
              - width: 16px
              - border: 2px solid var(--card-background-color)
              - font-size: 12px
              - line-height: 14px
              - background-color: |
                  [[[
                    return "rgba(var(--couleur-rouge),1)";
                  ]]]
        value: unavailable
    styles:
      card:
        - border-radius: 20px
        - box-shadow: var(--box-shadow)
        - padding: 12px
      grid:
        - grid-template-areas: '"i n" "i l"'
        - grid-template-columns: min-content auto
        - grid-template-rows: min-content min-content
      icon:
        - color: rgba(var(--couleur-theme),0.2)
      img_cell:
        - background-color: rgba(var(--couleur-theme),0.05)
        - border-radius: 50%
        - place-self: center
        - width: 42px
        - height: 42px
      name:
        - align-self: end
        - justify-self: start
        - font-weight: bold
        - font-size: 14px
        - margin-left: 12px
      label:
        - justify-self: start
        - align-self: start
        - font-weight: bolder
        - font-size: 12px
        - filter: opacity(40%)
        - margin-left: 12px
      state:
        - justify-self: start
        - align-self: start
        - font-weight: bolder
        - font-size: 12px
        - filter: opacity(40%)
        - margin-left: 12px
5 Likes

Hello Thomas,
I tried your new light/dark themes.
Added

  modes:
    light:
      !include mobile_light.yaml
    dark:
      !include mobile_dark.yaml

With light theme everything works as expected. But the theme didn’t switch to dark if I change theme settings in Browser or HA companion app.

The dark theme by itself is working and looks great if I change the include mobile_light.yamlto mobile_dark.yaml. But automatic switching is not working.
Any hint what I could do to get automatic switching working?

Is there a reason you use the ‘label’ of the buttoncard to display the state, instead of using ‘state_display’ ?
For the simple on/off (outlet) button, this would mean the translation (‘on’ / ‘off’) can be removed altogether.

Also: this would allow people to display the time the entity last changed (if they desire so)

1 Like

I’m trying to utilise the swipe-card for some navigation, but the overflow: hidden it adds causes some problems with the drop shadows of the cards. Does anyone know any tricks with card-mod to try and rectify?

image

Why theme not working:
16.08.2021_15.48.32_REC

configuration.yaml:

frontend: 
  themes: 
    minimalist: !include lovelace/themes/minimalist_theme.yaml

minimalist_theme.yaml:

     #Colors
      google-red-500 : '#F54436'
      google-green-500 : '#01C852'
      google-yellow-500 : '#FF9101'
      google-blue-500 : '#3D5AFE'
      google-violet-500 : '#661FFF'
      google-grey-500: '#BBBBBB'
      couleur-red : 245, 68, 54
      couleur-green : 1, 200, 82
      couleur-yellow : 255, 145, 1
      couleur-blue : 61, 90, 254
      couleur-violet : 102, 31, 255
      couleur-grey : 187, 187, 187
      couleur-rose : 233, 30, 99
      couleur-theme : 51,51,51
      #Card
      card-background-color: '#FAFAFA'
      box-shadow: '0px 2px 4px 0px rgba(0,0,0,0.16)'
      border-radius: '20px'
      border-color: '#EAEAEA'
      primary-color: '#434343'
      light-primary-color: '#fce8e6'
      paper-item-icon-color: '#434343'
      paper-toggle-button-checked-ink-color: '#3D5AFE'
      paper-toggle-button-checked-button-color: '#3D5AFE'
      paper-toggle-button-checked-bar-color: '#3D5AFE'
      accent-color: '#ff8100'
      switch-checked-color: '#3D5AFE'
      #Sidebar
      sidebar-selected-text-color: '#d93025'
      sidebar-text-color: '#80868b'
      sidebar-selected-icon-color: '#d93025'
      sidebar-selected-background-color: '#fce8e6'
      mdc-theme-secondary: 'var(-primary-color)'
      #Slider
      slider-color: '#d93025'
      slider-bar-color: '#fce8e6'
      #Background
      secondary-background-color: '#EFEFEF'
      primary-background-color: '#EFEFEF'
      #Custom header
      couleur-header: 239, 239, 239
      couleur-elements: 33, 33, 33
      #Header
      app-header-text-color: '#434343' 
      app-header-background-color: '#EFEFEF'
      paper-tabs-selection-bar-color: '#434343'
      #Journal
      state-icon-color: '#434343'
      #Remove header
      card-mod-theme: light_mobile
      card-mod-root: |
        app-toolbar {
          display: none;
        }

I am using latest button_card:template and latest views .

@lpt2007 If you’re using the latest templates you’ll have to update your theme variables.

google-red-500 → google-red
google-green-500 → google-green
google-yellow-500 → google-yellow
google-blue-500 → google-blue
google-violet-500 → google-violet
google-grey-500 → google-grey
couleur-rouge → color-red
couleur-vert → color-green
couleur-jaune → color-yellow
couleur-bleu → color-blue
couleur-violet → color-purple
couleur-gris → color-grey
couleur-rose → color-pink
couleur-theme → color-theme

Or download the latest version of the theme again from the github repo :wink: