A different take on designing a Lovelace UI

Hey Mason,

you’ve helped me a few times already, so sorry for all the questions. I’ve made a few icons in photoshop but not sure how to animate them. I can animate in after effects but not sure what to export or how to get that into HA. Any documentation or videos that show this process? Also, would you possible share the icons you’ve made, specifically the garage icon? This UI is the most complicated thing I’ve done in HA and its teaching me a ton, so thanks for all your help!

3 Likes

I don’t have the skills to create a simple icon or an animated icons, all the icons I have are from this thread or from this method A different take on designing a Lovelace UI - #3799 by masoncrawford1994

Hi all again. Need some help.

how do I set up the pperson persistence.
I see the yaml file and i know I need mqtt but beyind that i feel like im 2 years old …:stuck_out_tongue:

Hi, i like your bottom columns. I’m stuggling both with update part and the RPi pop-up with info. Is this anything you could share with me? Really nice UI!

Is there anyway to improve the image-quality of the plex-media button?

image

Referring to image_resolution in the recently_added sensor

Of course, I just didn’t do anything other than Mattias and experience a number of problems with this myself. that I didn’t fix yet

lovelace.yaml

      - type: horizontal-stack
        view_layout:
          grid-area: footer
        cards:
          - type: custom:button-card
            name: >
              <ha-icon icon="mdi:home-assistant"></ha-icon> Home Assistant
            tap_action: !include popup/footer/hass.yaml
            template: footer

          - type: custom:button-card
            name: >
              <ha-icon icon="mdi:arrow-up-bold-circle-outline"></ha-icon> Update
            tap_action: !include popup/footer/footer_updates.yaml
            variables:
              notify: >
                [[[ 
                  let id = states['sensor.total_update_count'];
                  if (id) {
                    return parseInt(id.state);
                  }
                ]]]
            template: footer

          - type: custom:button-card
            name: >
              <ha-icon icon="cil:roborock-vacuum-map"></ha-icon> Wall_e
            tap_action: !include popup/footer/vacuum.yaml
            variables:
              notify: >
                [[[
                  let id = states['sensor.wall_e_tijd_sinds_laatste_schoonmaak'];
                  if (id) return parseInt(id.state);
                ]]]
            template: footer

          - type: custom:button-card
            name: >
              <ha-icon icon="phu:dyson-floor"></ha-icon> Purifier
            tap_action: !include popup/footer/purifier.yaml
            template: footer

          - type: custom:button-card
            name: >
              <ha-icon icon="mdi:raspberry-pi"></ha-icon> RPi
            tap_action: !include popup/footer/rpi.yaml
            variables:
              notify: >
                [[[
                  let ping = states['binary_sensor.rpi_ping'];
                  if (ping) {
                    return ping.state === 'off';
                  }
                ]]]
            template: footer

footer_updates.yaml

action: fire-dom-event
browser_mod:
  service: browser_mod.popup
  data:
    title: Updates
    card_mod:
      style:
        #popup header
        .:
    content:
      type: custom:mod-card
      card_mod:
        style:
          hui-grid-card:
            $: |
              button-card:nth-child(2) {
                margin: 0.6em 0 2.1em 0.8em;
              }
              button-card:nth-child(4) {
                margin: 0.6em 0 0.5em 0.8em;
              }
              #root {
                grid-gap: 0 !important;
                padding: var(--tablet-popup-content-padding);
              }
      card:
        type: grid
        columns: 1
        square: false
        cards:
          - type: custom:button-card
            entity: sensor.current_version
            template: updates_hass
            variables:
              available: sensor.template_updates_matt
              latest: sensor.hass_latest_website
              latest_beta: sensor.hass_latest_beta
              release_notes: sensor.hass_release_notes
              release_notes_beta: sensor.hass_release_notes_beta

          - type: custom:button-card
            entity: sensor.current_version
            name: Update HASS
            variables:
              latest: sensor.hass_latest_website
              latest_beta: sensor.hass_latest_beta
            tap_action: []
            template: updates_hass_icon_name

          ############################################

          - type: custom:button-card
            variables:
              updates: sensor.template_updates_matt
              other_updates: sensor.template_updates_matt
              hacs_installed: sensor.hacs_installed
            template: updates

          - type: custom:button-card
            entity: sensor.template_updates
            name: Update
            template:
              - updates_icon_name
              - >
                [[[
                  return window.navigator.userAgent.match(/iPhone/i)
                    ? 'hacs_navigate_ios'
                    : 'hacs_iframe';
                ]]]
            hold_action:
              action: call-service
              service: browser_mod.sequence
              service_data:
                sequence:
                  - service: browser_mod.notification
                    data:
                      message: Söker efter uppdateringar...
                  - service: homeassistant.update_entity
                    data:
                      entity_id:
                        - sensor.updates_esphome_latest
                        - sensor.updates_kemper

rpi.yaml

update_entities:
  action: >
    [[[
      hass.callService('homeassistant', 'update_entity', {
          entity_id: [
            'binary_sensor.rpi_ping',
            'sensor.processor_temperature',
            'sensor.processor_use',
            'sensor.memory_use_percent',
            'sensor.last_boot'
          ]
      });
    ]]]
action: fire-dom-event
browser_mod:
  service: browser_mod.popup
  data:
    title: Raspberry Pi 4B
    content:
      type: vertical-stack
      cards:
        - type: entities
          state_color: true
          card_mod:
            class: content
          entities:
            - entity: binary_sensor.rpi_ping
              secondary_info: last-changed
              name: Anslutning
              icon: mdi:raspberry-pi

            - type: custom:bar-card
              width: 55%
              height: 2em
              decimal: 0
              unit_of_measurement: "%"
              positions: &positions
                icon: outside
                indicator: "off"
                name: outside
              severity: &severity
                - color: "#6d2525"
                  from: 90
                  to: 999
              entity_row: true
              entities:
                - entity: sensor.processor_temperature
                  tap_action:
                    action: call-service
                    service: homeassistant.update_entity
                    service_data:
                      entity_id: sensor.processor_temperature

                - entity: sensor.processor_use
                  tap_action:
                    action: call-service
                    service: homeassistant.update_entity
                    service_data:
                      entity_id: sensor.processor_use

                - entity: sensor.memory_use_percent
                  tap_action:
                    action: call-service
                    service: homeassistant.update_entity
                    service_data:
                      entity_id: sensor.memory_use_percent

            - entity: sensor.last_boot
              tap_action:
                action: call-service
                service: homeassistant.update_entity
                service_data:
                  entity_id: sensor.last_boot

Ola,

Question, when I hit a button with an entity like a light or switch the button becomes white when active.
Now I’ve also made a button for my A/C which is a climate.

When I click this the button won’t change color, I reckon that is due to it’s state not being “on” but rather “heat_cool”; “cool” or w/e the state is.

I tried looking in the docs and code to see where you configured the buttons to get white when state is ‘on’ but can’t find it anywhere to add those actions for my ACs.

Any help is greatly appreciated.

Thanks!

Also interessted in the yaml for the weather button :slight_smile:

That’s determined by the state_on variable in button_card_templates/base.yaml which is set to 'on', 'home', 'cool', 'fan_only', 'playing', 'unlocked'. If you don’t want to alter the base files, you can add the states to individual buttons like this:

  - type: custom:button-card
    entity: alarm_control_panel.home_alarm
    name: Security
    tap_action: !include popup/alarm.yaml
    template:
      - base
      - icon_home_shield
    variables:
      state_on: >
        [[[ return ['armed_night', 'armed_away', 'armed_home'].indexOf(!entity || entity.state) !== -1; ]]]
      state_off: >
        [[[ return ['disarmed'].indexOf(!entity || entity.state) !== -1; ]]]
      state: >
        [[[ return !entity || entity.state; ]]]
...
1 Like

Hi Mattias! how can i add that little phone circle beeneth in the picture below?

image

Hi, i have a same template, I just add some background images according weather state and modify font size. :slight_smile:

SCR-20230421-18t SCR-20230421-185 SCR-20230421-17h SCR-20230421-16x

button template:

widget_weather:
  template:
    - base
  variables:
    temp_min: ''
    temp_max: ''
    humidity: ''
    current_weather: ''
    is_bellow_horrizon: >
      [[[
        if (states['sun.sun'].state == 'below_horizon') {
            return true;
        }
      ]]]
  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%
      - overflow: visible
    card:
      - padding: 11.5% 10.5% 10.5% 11.5%
      - color: rgba(255, 255, 255, 0.6)
      - background: >
          [[[
            let weather = states[variables.current_weather].state.toLowerCase();
              return variables.is_bellow_horrizon
                ? `linear-gradient(to top, rgba(53,59,83,0.8) 0%, rgba(0,0,0,0.4) 100%) 100% / cover, url(/local/svg/weather/${weather}.png)`
                : `linear-gradient(to top, rgba(155, 109, 129, 0.5) 0%, rgba(63,74,113,1) 100%) 100% / cover, url(/local/svg/weather/${weather}.png)`;
          ]]]
      - background-size: cover

    state:
      - text-transform: uppercase
      - margin-top: 5px
      - line-height: 100%
    name:
      - place-self: start
      - text-transform: uppercase
      - font-weight: 500
      - font-family: Futura
      - letter-spacing: 0.1vw
      - margin-top: -7%
    img_cell:
      - justify-content: start
      - overflow: visible
    icon:
      - width: 35%

    label:
      - place-self: start
      # - margin-left: -5px
      - margin-top: 3%
      - margin-bottom: -7%
    custom_fields:
      temp:
        - place-self: start
        # - margin-top: -5px
        - font-family: Futura
        - color: rgba(240, 255, 255, 0.8)
  label: >
    [[[
      return `
        <ha-icon icon="mdi:water-percent" style="width: 1em; height: 1em; margin-right: -0.3em;"></ha-icon>
        <span>${states[variables.humidity].state}%</span>
        <ha-icon icon="mdi:chevron-up" style="width: 1.5em; height: 1.5em; margin-right: -0.3em;"></ha-icon>
        <span>${states[variables.temp_max].state}°</span>
        <ha-icon icon="mdi:chevron-down" style="width: 1.5em; height: 1.5em; margin-right: -0.3em;"></ha-icon>
        <span>${states[variables.temp_min].state}°</span>
      `
    ]]]
  custom_fields:
    temp: >
      [[[ return entity.attributes.temperature + "°"; ]]]
  entity_picture: >
    [[[
      let weather = states[variables.current_weather].state.toLowerCase();
      if ((weather == 'sunny') && (states['sun.sun'].state == 'above_horizon'))
        return "/local/svg/weather/clear-day.svg";
        if ((weather == 'sunny') || (weather == 'clear-night') && (states['sun.sun'].state == 'below_horizon'))
          return "/local/svg/weather/clear-night.svg";
            if (weather == 'fog')
              return "/local/svg/weather/fog.svg";
                if ((weather == 'partlycloudy') && (states['sun.sun'].state == 'above_horizon'))
                  return "/local/svg/weather/partly-cloudy-day.svg";
                    if ((weather == 'partlycloudy') && (states['sun.sun'].state == 'below_horizon'))
                      return "/local/svg/weather/partly-cloudy-night.svg";
                        if (weather == 'rainy')
                          return "/local/svg/weather/rain.svg";
                            if (weather == 'sleet')
                              return "/local/svg/weather/sleet.svg";
                                if (weather == 'snow')
                                  return "/local/svg/weather/snow.svg";
                                    if (weather == 'cloudy')
                                      return "/local/svg/weather/cloudy.svg";
      else (weather == 'wind')
        return "/local/svg/weather/wind.svg";
    ]]]
  extra_styles: |
    [[[
      return `
        #name {
          font-size: 0.9vw;
        }
        #temp {
          font-size: 1.4vw;
        }
        #state {
          font-size: 0.7vw;
        }
        #label {
          font-size: 0.6vw;
        }
        @media screen and (max-width: 1500px) {
          #name {
            font-size: 1.3vw;
          }
          #temp {
            font-size: 2vw;
          }
          #state {
            font-size: 1.2vw;
          }
          #label {
            font-size: 1.2vw;
          }
        @media screen and (max-width: 800px) {
          #name {
            font-size: 3vw;
            margin-top: -5%;
          }
          #temp {
            font-size: 6vw;
          }
          #state {
            font-size: 2.7vw;
          }
          #icon {
            display: none !important;
          }
          #label {
            font-size: 1.9vw;
            font-weight: 500 !important;
            margin-top: 5%;
            margin-bottom: 0%;
            margin-left: -4%;
          }
        }
      `
    ]]]

lovelace:

    - type: custom:button-card
      entity: weather.prague
      name: Prague
      variables:
        temp_min: sensor.weather_min_temp
        temp_max: sensor.weather_max_temp
        humidity: sensor.openweathermap_humidity
        current_weather: weather.prague
      template:
        - widget_weather
7 Likes

Thanks so much! I’m wanting to take some stuff from your sidebar so I took a dive into your config. I am trying to create the special occasions template sensor in my sensor.yaml file and it is giving me all sorts of errors. Tried pasting in the same layout you have, and this is what I’m getting. Any ideas? Thanks!

1 Like

My guess is that it’s probably in the wrong location/format.

The following is the correct structure:

template:
  sensor:
    - unique_id: special_occasions
      name: 'Special Occasions'
      state: >

There’s a difference between “template sensor” and “sensor template”.
If you’re pasting this where you’re using the legacy method, you’ll get errors.

Could this be it?

Thanks for that code. Could you also share the svg’s that you are using?

and the PNGs for the background :slight_smile:

Thank you so much!
Davide

Here is the original post, thanks @pex81

Just screenshot some weather background and rename it same as svg, I have just for cloudy, partly cloudy, rainy, clear-day, clear-night :sweat_smile: :sweat_smile: or you can use gif background… they looks realy nice.

Screen_Recording_2023-04-21_at_12_44_08_AdobeExpress

2 Likes

Can u share your icons file, Like the icons you have used for Rooms, Camera, door etc.?