A different take on designing a Lovelace UI

Is the theme on for that device?
can you provide the yaml for the dashboard?
can you provide more info on “Tried different things”, what are the things you have tried?

Hi everyone - I’m an extreme noob when it comes to yaml. :slightly_smiling_face: Hoping someone can help me out with what I am sure is a super dumb question.

I’m just starting to try to implement this UI and am running into this issue with every card:

Because I have multiple yaml dashboards going, I’ve had to edit my configuration.yaml slightly, but everything else is largely the same save for some entity/name references. It seems like I’m just not referencing the “extra_styles.yaml” somehow? I’m trying to keep my config organized, so it’s currently in config/ui-lovelace/button_card_templates with the rest of the light.yaml, icon_hue.yaml, etc. And for reference, this is the button_card code:

      - type: grid
        title: Kitchen
        view_layout:
          grid-area: kitchen
        columns: 2
        cards:

          - type: custom:button-card
            entity: light.kitchen_cabinet_sink_lights_2
            name: Cabinet & Sink Lights
            template:
              - light
              - icon_hue

         - type: custom:button-card
            entity: light.laundry_room_cabinet_lights
            name: Laundry Lights
            template:
              - light
              - icon_shade

What am I doing wrong? Any help would be appreciated!

hi Amanda, welcome, and don’t worry we are all noobs at some point.

can I confirm a few things?
do you have this line at the top of your dashboard yaml?

button_card_templates:
 !include_dir_merge_named button_card_templates

button_card_templates is a relative path to the folder that contains all the templates.
so as you have moved the folder you may need to change this line depending on the location of your dashboard yaml

it also looks like you need to set up the theme, have you done this?

thank you for providing a good questions. :star:

1 Like

Im updating my version of this UI from pre browser mod 2, i believe i have fixed all the breaking changes apart from this one:

it seems like the “placeholder grid areas” are having borders generated, i tried applying the fix mentioned here: HA 2022.11 introduces border to cards - theme update required to resolve. · Issue #118 · matt8707/hass-config · GitHub

but it seems to have not fixed the issue. Does anyone have any suggestions? I can post snippets if you need them, i don’t know where to look to resolve this as other who had the border issue appeared to not have it specifically here. will post snippets of my work if someone can point me in the right direction, cheers,

post ui-lovelace.yaml and I’ll have a look

Hi Mason,

Do you have an idea how I can add a sound? So as soon as the timer ends, there should be a sound.

Use a normal home assistant automation, the timer finishing will send out an event that an automation can listen for. I have it sending a notification to my tv and my phone for now but I have plans to expand the automation. You could send a service call to the tablet and play a sound if your tablet supports that.

1 Like

Thanks Mattias,

heres my lovelace. its a pretty old version

button_card_templates:
  !include_dir_merge_named button_card_templates

views:

  - type: custom:grid-layout
         
    layout:
      #default
      grid-gap: calc(var(--custom-layout-card-padding) * 0.8)
      grid-template-columns: 1.175fr repeat(3, 1fr) 0
      grid-template-rows: 0 repeat(2, fit-content(100%)) 0fr
      grid-template-areas: |
        "sidebar  .           .         .           ."
        "sidebar  hvac        bedrooms  cameras     ."
        "sidebar  media       bathroom  home        ."
        "sidebar  footer      footer    footer      ."
      mediaquery:
        #phone
        "(max-width: 800px)":
          grid-gap: calc(var(--custom-layout-card-padding) * 1.5)
          grid-template-columns: 0 repeat(2, 1fr) 0
          grid-template-rows: 0 repeat(5, fit-content(100%)) 0fr
          grid-template-areas: |
            ".  .           .           ."
            ".  sidebar     sidebar     ."
            ".  bedrooms    bathroom    ."
            ".  hvac        cameras     ."
            ".  media       home        ."
            ".  footer      footer      ."
            ".  .           .           ."
        #portrait
        "(max-width: 1200px)":
          grid-gap: var(--custom-layout-card-padding)
          grid-template-columns: repeat(3, 1fr) 0
          grid-template-rows: 0 repeat(3, fit-content(100%)) 0fr
          grid-template-areas: |
            "sidebar  .           .           ."
            "sidebar  bedrooms    bathroom    ."
            "sidebar  hvac        cameras     ."
            "sidebar  media       home        ."
            "sidebar  footer      footer      ."
            "sidebar  .           .           ."
    cards:

      - type: custom:button-card #extra_styles fix

      #################################################
      #                                               #
      #                    SIDEBAR                    #
      #                                               #
      #################################################

      - type: vertical-stack
        view_layout:
          grid-area: sidebar
        cards:
          - type: custom:button-card
            entity: sensor.template_sidebar
            template: sidebar_template

          - type: custom:popup-card
            entity: weather.openweathermap
            card:
              type: custom:weather-card
              template: sidebar_template          
              style: 
                  .: |
                    ha-card {
                      width: 80%;
                      border-width: 0px
                    }
              entity: weather.openweathermap       
              forecast: false
              hourly_forecast: false
              details: true
              current: true
          
          - type: grid       
            cards:
              - type: button
                icon: custom:roborock-vacuum
                
                tap_action:
                  !include popup/sidebar_vacuum.yaml
                hold_action:
                  action: none

              - type: button
                icon: mdi:information-outline
                tap_action:
                  !include popup/sidebar_information.yaml
                hold_action:
                  action: none

              - type: button
                icon: mdi:arrow-up-bold-circle-outline
                tap_action:
                  !include popup/sidebar_update.yaml
                hold_action:
                  action: call-service
                  service: homeassistant.update_entity
                  service_data:
                    entity_id: sensor.hacs

      #################################################
      #                                               #
      #                  Cameras                      #
      #                                               #
      #################################################

      - type: grid
        title: Cameras
        view_layout:
          grid-area: cameras
        columns: 2
        cards:

          - type: custom:button-card
            entity:
            name: camera1
            template:
              - light
#              - icon_hue

          - type: custom:button-card
            entity: 
            name: Camera2
            template:
              - light
#              - icon_shade

          - type: custom:button-card
            entity:
            name: camera3
            hold_action:
            template:
              - base
 #             - icon_tv
 #             - loader

          - type: custom:button-card
            entity:
            name: Camera4
            hold_action:
            template:
              - base
              - icon_hue
              - loader

      #################################################
      #                                               #
      #                    HVAC                       #
      #                                               #
      #################################################

      - type: grid
        title: Home Climate
        view_layout:
          grid-area: hvac
        columns: 2
        cards:

          - type: custom:button-card
            entity: climate.hvac
            name: Main HVAC
            tap_action:
              !include popup/mainhvac.yaml
            template:
              - base
              - icon_climate
              - climate
            variables:
              circle_input: >
                [[[
                  if (entity) {
                    return entity.state == 'cool' ?
                      entity.attributes.temperature :
                      entity.attributes.current_temperature;
                  }
                ]]]

          - type: custom:button-card
            entity: input_select.sync_climate_type
            name: '[[[ return entity.state]]]'
            show_state: false
            styles:
              name:
                - white-space: normal
                - text-align: left
                - vertical-align: text-top
            tap_action:
                action: call-service
                service: input_select.select_next
                service_data:
                  entity_id: input_select.sync_climate_type
            hold_action:
              action: none
            template:
              - base
              - icon_sync
              
          - type: custom:button-card
            entity: switch.hallway_double_2
            name: Fresh Air Intake
            show_state: false
            styles:
              name:
                - white-space: normal
                - text-align: left
            template:
              - base
              - loader
              - icon_fan2
              
          - type: custom:button-card
            entity: script.quick_climate
            name: >
              [[[
                return states['input_select.quick_climate_mode'].state;
              ]]]
            hold_action:
              !include popup/quickclimate.yaml
            template:
              - base
              - loader
              - icon_quick_mode
                

      #################################################
      #                                               #
      #                    BATHROOM                   #
      #                                               #
      #################################################

      - type: grid
        title: Bathroom
        view_layout:
          grid-area: bathroom
        columns: 2
        cards:

          - type: custom:button-card
            entity: input_boolean.bathroom_auto
            name: Auto Mode
            template:
              - base
              - icon_sync

          - type: custom:button-card
            entity: climate.bathroom1ecobee
            name: Bathroom
            tap_action:
              !include popup/bathroom1climate.yaml
            template:
              - base
              - icon_climate
              - climate
            variables:
              circle_input: >
                [[[
                  if (entity) {
                    return entity.state == 'cool' ?
                      entity.attributes.temperature :
                      entity.attributes.current_temperature;
                  }
                ]]]
                

 
          - type: custom:button-card
            entity: switch.equipment_1
            name: Heated Mirror
            hold_action:
              !include popup/mirror.yaml #heated mirror popup, settings, timer etc
            template:
              - base
              - icon_mirror
              - loader

              
          - type: custom:button-card
            entity: fan.extractor_fan #change to fan.bathroom_extractor
            name: Extractor Fan
            hold_action:
              !include popup/bathroom_extractor_fan.yaml # popup with fan settings, timer etc
            template:
              - base
              - icon_fan2
              - loader

      #################################################
      #                                               #
      #                     MEDIA                     #
      #                                               #
      #################################################

      - type: grid
        title: Media
        view_layout:
          grid-area: media
        columns: 1
        cards:
        
          - type: custom:button-card
            entity: sensor.plex_recently_added
            tap_action:
              !include popup/media_plexplayer.yaml
            template:
            - conditional_media
            - recently_downloaded
            - icon_plex
            - base
            - loader

#
#          - type: custom:swipe-card
#            start_card: 1
#            parameters:
#              roundLengths: true
#              effect: coverflow
#              speed: 650
#              spaceBetween: 20
#              threshold: 7
#              coverflowEffect:
#                rotate: 80
#                depth: 300
#            cards:
#
#              - type: horizontal-stack
#                cards:
#
#                  - type: conditional
#                    conditions:
#                      - entity: input_select.conditional_media
#                        state: Recently Downloaded
#                    card:
#                      type: custom:button-card
#                      entity: sensor.plex_recently_added
#                      tap_action:
#                        !include popup/Media_plexplayer.yaml
#                      template:
#                        - conditional_media
#                        - recently_downloaded
#                        - icon_plex
#                        - base
#                        - loader
#              - type: grid
#                columns: 2
#                cards:
#
#                  - type: custom:button-card
#                    entity: media_player.vardagsrum
#                    name: Vardagsrum
#                    template:
#                      - media
#                      - icon_apple_tv
#
#                  - type: custom:button-card
#                    name: Sovrum
#                    entity: media_player.sovrum
#                    template:
#                      - media
#                      - icon_apple_tv
#
#                  - type: custom:button-card
#                    entity: media_player.spotify
#                    name: Spotify
#                    template:
#                      - media
#                      - icon_spotify
#
#                  - type: custom:button-card
#                    entity: media_player.kok
#                    name: Nest Mini
#                    template:
#                      - media
#                      - icon_nest_mini

      #################################################
      #                                               #
      #                    BEDROOMS                   #
      #                                               #
      #################################################

      - type: grid
        title: Bedrooms
        view_layout:
          grid-area: bedrooms
        columns: 2
        cards:

          - type: custom:button-card
            entity: switch.hallway_double_1
            name: Hallway Light          
            hold_action:
              action: none
            template:
              - icon_hue
              - light        
        
          - type: custom:button-card
            entity: climate.bedroom1ecobee
            name: Bedroom 1
            tap_action:
              !include popup/bedroom1climate.yaml
            template:
              - base
              - icon_climate
              - climate
            variables:
              circle_input: >
                [[[
                  if (entity) {
                    return entity.state == 'cool' ?
                      entity.attributes.temperature :
                      entity.attributes.current_temperature;
                  }
                ]]]

          - type: custom:button-card
            entity: climate.bedroom2ecobee
            name: Bedroom 2
            tap_action:
              !include popup/bedroom2climate.yaml
            template:
              - base
              - icon_climate
              - climate
            variables:
              circle_input: >
                [[[
                  if (entity) {
                    return entity.state == 'cool' ?
                      entity.attributes.temperature :
                      entity.attributes.current_temperature;
                  }
                ]]]

          - type: custom:button-card
            entity: climate.bedroom3ecobee
            name: Bedroom 3
            tap_action:
              !include popup/bedroom3climate.yaml
            template:
              - base
              - icon_climate
              - climate
            variables:
              circle_input: >
                [[[
                  if (entity) {
                    return entity.state == 'cool' ?
                      entity.attributes.temperature :
                      entity.attributes.current_temperature;
                  }
                ]]]
              
      #################################################
      #                                               #
      #                     HOME                      #
      #                                               #
      #################################################

      - type: grid
        title: Home
        view_layout:
          grid-area: home
        columns: 2
        cards:

          - type: custom:button-card
            entity: person.ash
            name: Ash
            tap_action:
              !include popup/home_ash.yaml
            hold_action:
              action: none
            template: person

          - type: custom:button-card
            entity: device_tracker.pet_cleo
            name: Cleo
            tap_action:
              !include popup/home_cleo.yaml
            hold_action:
              action: none
            template: cat
            
          - type: custom:button-card
            entity: device_tracker.pet_molly
            name: Porker
            tap_action:
              !include popup/home_molly.yaml
            hold_action:
              action: none
            template: cat
            
          - type: custom:button-card
            entity: person.grace
            name: Grace
            tap_action:
              !include popup/home_grace.yaml
            hold_action:
              action: none
            template: person


      #################################################
      #                                               #
      #                    FOOTER                     #
      #                                               #
      #################################################

#      - type: custom:button-card
#        view_layout:
#          grid-area: footer
#        entity: sensor.covid_19_folkhalsomyndigheten
#        template: coronavirus
      - type: custom:hui-element
        card_type: horizontal-stack
        cards:
        - type: custom:button-card

Hi all – I’m seeking some template help.

My heating system reports hvac_action: however the default state is hvac_modes: which always displays as auto on my button cards.

How could I tweak the base template to use hvac_action: instead? Do I need to create a sensor or is there a better way?

base:
  template:
    - settings
    - tilt
    - extra_styles
  variables:
    state_on: >
      [[[ return ['on', 'home', 'heating', 'fan_only', 'playing', 'unlocked'].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; ]]]
    timeout: >
      [[[ return !entity || Date.now() - Date.parse(entity.last_changed); ]]]
    is_youtube: >
      [[[
        let is_youtube = entity?.attributes?.app_id === 'com.google.ios.youtube',
            sensor = this?._config?.triggers_update,
            media_title = entity?.attributes?.media_title,
            watching_title = states[sensor]?.attributes?.title;
        if (is_youtube && media_title === watching_title) {
            return true;
        }
      ]]]

hi @tomplums

1st don’t do that, I would not recommend changing base ever, you can over ride everything so there should never be a need to make a change to base

2nd why are you not using the climate template? that has hvac_action as the state, along with lots more.

3rd this is how

  variables:
    state: >
      [[[
        if (entity) {
          return entity.attributes.hvac_action 
        }
      ]]]
    state_on: >
      [[[ 
        return ['cooling','heating'].indexOf(!entity || entity.attributes.hvac_action) !== -1; 
      ]]]
1 Like

set display none on this

- type: custom:button-card #extra_styles fix

https://github.com/matt8707/hass-config/blob/7c69cd3069db32c799c9a7261d132bd994511a7a/ui-lovelace.yaml#L49-L70

3 Likes

Perfect thanks for this. I’m an idiot – I’d templated the cards/layout before populating the entities and was trying to apply climate to a section of code meant for lights.

it happens,

I recommend keeping @Mattias_Persson repo open, that way you can always look at how he did it.

I use to use github1s, but now I just have a clone of the repo on my PC that I reference for both helping people with issues and when i’m working on my own config

Yes I practice that approach too.

But actually which climate template are you referring to? I don’t see any that use hvac_action in the repo.

my apologies I must have written that myself

this is the template I use for climate

#################################################
#                                               #
#                    CLIMATE                    #
#                                               #
#################################################

climate:
  template:
    - base
    - circle
  variables:
    state: >
      [[[
        if (entity) {
          return entity.attributes.hvac_action 
        }
      ]]]
    state_on: >
      [[[ 
        return ['cooling','heating'].indexOf(!entity || entity.attributes.hvac_action) !== -1; 
      ]]]
    circle_input: >
      [[[
        if (entity) {
            return entity.state === 'off'
                ? Math.round(entity.attributes.current_temperature).toString()
                : entity.attributes.hvac_action === "cooling"
                  ? Math.round(entity.attributes.target_temp_low).toString()
                  : Math.round(entity.attributes.target_temp_high).toString();
        }
      ]]]
    circle_input_unit: '°C'
  state_display: |
    [[[
        return variables.state.charAt(0).toUpperCase() + variables.state.substr(1).toLowerCase();
    ]]]
1 Like

wow super clean weather section, are the backgrounds animated or are they images?

what are the bars on the bottom of the side bar?

Simple as that!

cheers mate, worked a charm :beer:

The weather icons are all animated. Backgrounds are pictures. Those bars are the rain forecast of the next 2 hours.

EDIT:

every bar represents the rain probability in % for every 12 minutes range.

wow smart, that would be handy for me, as I have a motorbike so knowing rain is on the way would come in handy, what weather integration do you use? would you mind posing the logic for the bars for a reference?

I’m not using any integration, I’m using straight the Accuweather API. They only allow 24 calls per day in its free plan for Minutecast, so I created three tokens so I can make a request every 20 mins.

https://developer.accuweather.com/

I’m using NR to make the call but it can be done creating a rest sensor or command or whatever in HA itself. It’s a GET request and the url should look something like this:

http://dataservice.accuweather.com/forecasts/v1/minute?q=43.016666%2C%20-7.550000&apikey=YOUR_API_KEY_HERE&language=es-es

Regarding those bars, I link you to a different post where I thoroughly exlained how it works. The config is shared in posts 16 and 17 but there’s the full explanation:

1 Like