A different take on designing a Lovelace UI

my suggestion would only have change the direction of the slider to LTR not any of the text. (LTR slider top is 100% bottom is 0 RTL slider top is 0 bottom is 100)

yup that worked :slight_smile: and didn’t break anything else! thanks again so much

Replaced the background.png and themes.yaml and background appears to be working again :slight_smile:

Awesome. Would you mind sharing the code for this Plex pop up? It looks incredibly useful as a footer and would love to incorporate this.

Thanks for your numerous replies. I’ll have a look into this later this week! :slight_smile:

happy to, share the updated code, I had shared it already A different take on designing a Lovelace UI - #3715 by masoncrawford1994

action: fire-dom-event
browser_mod:
  service: browser_mod.popup
  data:
    title: Plex
    style: >
      --ha-card-border-radius: 0;
    content:
      type: custom:mod-card
      card_mod:
        style:
          hui-vertical-stack-card:
            $: |
              hui-horizontal-stack-card {
                padding: 0em 2em 2.3em 2em;
              }
            $hui-horizontal-stack-card$: |
              #root {
                justify-content: space-evenly;
              }
      card:
        type: vertical-stack
        cards:
          - type: entities
            state_color: true
            card_mod:
              class: content
            entities:
              - entity: switch.docker_plex
                secondary_info: last-changed
                name: Power state
                icon: mdi:power
              - type: custom:bar-card
                width: 55%
                height: 2em
                decimal: 0
                unit_of_measurement: '%'
                positions:
                  icon: outside
                  indicator: 'off'
                  name: outside
                severity:
                  - color: '#6d2525'
                    from: 90
                    to: 999
                entity_row: true
                entities:
                  - entity: sensor.template_plex_cpu
                  - entity: sensor.template_plex_mem
              - entity: sensor.template_plex_state
                name: health
                icon: mdi:heart-pulse
              - type: divider
              - entity: sensor.plex_crawfordnas
                name: Activity
                icon: mdi:progress-upload
              - entity: sensor.plex_audiobooks_folder_used_2
                type: custom:multiple-entity-row
                name: Audiobooks
                state_header: current
                show_state: false
                icon: "mdi:folder-eye"
                entities:
                  - entity: sensor.plex_audiobooks_folder_items_2
                    name: Amount
                  - entity: sensor.plex_audiobooks_folder_used_2
                    name: Usage
              - entity: sensor.plex_tv_shows_folder_used_2
                type: custom:multiple-entity-row
                name: TV Shows
                state_header: current
                show_state: false
                icon: "mdi:folder-play"
                entities:
                  - entity: sensor.plex_tv_shows_folder_items_2
                    name: Amount
                  - entity: sensor.plex_tv_shows_folder_used_2
                    name: Usage
              - entity: sensor.plex_movies_folder_used_2
                type: custom:multiple-entity-row
                name: Movies
                state_header: current
                show_state: false
                icon: "mdi:folder-play"
                entities:
                  - entity: sensor.plex_movies_folder_items_2
                    name: Amount
                  - entity: sensor.plex_movies_folder_used_2
                    name: Usage
          - type: horizontal-stack
            cards:
              - type: custom:button-card
                name: Scan Libraries
                icon: mdi:refresh
                tap_action:
                  action: call-service
                  service: script.plex_refresh_all
                template: icon_name
              - type: custom:button-card
                name: Scan Clients
                icon: mdi:magnify
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: button.scan_clients_crawfordnas
                template: icon_name
3 Likes

Hello again. :slight_smile:

Im pretty sure, someone of you can help me with my problem. :sweat_smile:
At the Moment I got these two cards, the left one is for my climate and the left one for dehumidifier.
The entity_id of the card are climate.xxx and humidifier.xxx, aswell as the “18°C” and the graph at the bottom.
Screenshot 2022-11-15 093515

But im tryining to show there two different sensor which are not from the device. But I have no clue how to get this.

This is the code from the climate in ui-lovelace.yaml:

          - type: custom:button-card
            entity: climate.wohnzimmer_hz
            name: Heizung
            tap_action:
              action: call-service
              service: |
                [[[ return variables.state === 'off' ? 'climate.turn_on' : 'climate.turn_off']]]
              service_data:
                entity_id: climate.wohnzimmer_hz
            double_tap_action:
              !include popup/wohnzimmer_heizung_2.yaml
            custom_fields:
              graph:
                card:
                  entities:
                    - entity: sensor.temperature_7
                    - entity: sensor.nightstate
                      color: gray
                      y_axis: secondary
                      show_line: false
                      show_points: false
                      show_legend: false
                      show_labels: false
                  double_tap_action: !include popup/wohnzimmer_heizung_2.yaml
            template:
              - climate
              - icon_climate
              - circle
            variables:
              circle_input: >
                [[[
                  if (entity) {
                      return entity.state === 'heat'
                          ? Math.round(entity.attributes.temperature).toString()
                          : Math.round(entity.attributes.current_temperature).toString();
                  }
                ]]]
              circle_input_unit: '°C'

And this from the dehumidifier:

          - type: custom:button-card
            entitiy: humidifier.midea_dehumidifier_142936511696163
            name: Entfeuchter
            tap_action:
              action: call-service
              service: |
                [[[ return variables.state === 'off' ? 'humidifier.turn_on' : 'humidifier.turn_off']]]
              service_data:
                entity_id: humidifier.midea_dehumidifier_142936511696163
            double_tap_action:
               !include popup/humidity.yaml
            custom_fields:
              graph:
                card:
                  entities:
                    - entity: sensor.humidity_8
                    - entity: sensor.nightstate
                      color: gray
                      y_axis: secondary
                      show_line: false
                      show_points: false
                      show_legend: false
                      show_labels: false
                  double_tap_action: !include popup/humidity.yaml
            variables: 
              state_on: >
                [[[
                  if (entity) {
                      return entity.state
                  }
                ]]]
              circle_input: >
                [[[
                  if (entity) {
                      return Math.round(entity.state).toString()
                  }
                ]]]
              circle_input_unit: '%'
            template:
              - humidity
              - icon_humidity
              - circle

Could someone help me?


Edit: Solved my problem:

            variables: 
              circle_input: >
                [[[
                  if (entity) {
                      return entity.state === 'on'
                          ? Math.round(entity.attribute.humidity).toString()
                          : Math.round(states['sensor.humidity_8'].state).toString();
1 Like

i have updated browser_mod to the v2 and now my tap actions are not working

I have tried different code but again “nothing pops up”

code is currently

                    entity: cover.all_kitchen_windows
                    tap_action:
                      action: call-service
                      service: browser_mod.popup
                      service_data:
                        content: !include popup/velux.yaml
                    name: Velux

can anyone help please?

Browser_Mod 2 is completely rewriten:

i understand and can see the changes in the files

however it does not cover the code changes required in ui-lovelace.yaml

let me expand abit more

For example on the footer area the button “sensors”

this is the lovelace-ui.yaml code for sensors…

          - type: custom:button-card
            name: >
              <ha-icon icon="mdi:robot-vacuum-variant"></ha-icon>SENSORS
            tap_action:
              !include popup/studio_flakt.yaml
            template: footer

this is the code inside the studio_flakt.yaml file

action: fire-dom-event
browser_mod:
   service: browser_mod.popup

nothing pops up.

I can think of 2 possible issues
1: the code in the popup file should be

action: fire-dom-event
browser_mod:
  service: browser_mod.popup
  data:
    title: title
    content:

followed by the content of the popup.

2: after you make a change to the popup file you will need to make a change in ui-lovelace.yaml for the update to take effect. just delete a letter save, add it back and save.

this is a limitation with home assistant

mason i have excatly that.

Code from popup file…

action: fire-dom-event
browser_mod:
  service: browser_mod.popup
  data:
    title: "Fläkt\u00B2"
    content:
      type: vertical-stack
      cards:
        - type: entities
          state_color: true
          card_mod:
            class: content
          entities:

            - entity: switch.gosund_fan_switch
              secondary_info: last-changed

            - type: custom:slider-entity-row
              entity: input_number.fan_timer
              hide_state: false

code from lovelace-ui.yaml

          - type: custom:button-card
            name: >
              <ha-icon icon="mdi:robot-vacuum-variant"></ha-icon>SENSORS
            tap_action: !include popup/studio_flakt.yaml
            template: footer

tried saving / restarting / cleared cash

have you followed all steps of the browser mod installation?

  • Install browser mod
  • Thoroughly clear your browser cache
  • Go to the Browser Mod panel in your sidebar
  • Make sure the “Register” toggle is checked.
    This is required in order to enable backend services to target this browser.
  • Refresh the page (F5)
  • Go to Developer Tools → Services Open your Home Assistant instance and show your service developer tools.
  • Select service “Browser Mod: popup (browser_mod.popup)”
  • Check the “Title” checkbar and write something as a title
  • Enter some text in the “Content” text box
    Not yaml or anything, just any text for now.
  • Click “CALL SERVICE”
    The button is likely grayed out. That’s a Home Assistant visual bug. Click it anyway.
  • A popup dialog should now open on all your Registered Browsers.
1 Like

Hey there! I am struggling to make the On & Off sound work on my wall mounted tablet with fully kiosk. Haptic feedback works fine, if I call the service manually, the sound does play. I am using fully kiosk integration for media_player and screensaver, tried playing the sound with Browser mod media_player on the same tablet, no luck. Here is my base template code:

  tap_action:
    ui_sound_tablet: |
      [[[
        const tablet = states['switch.galaxy_tab_screensaver'];
        const screensaver = states[tablet] === undefined || states[tablet].state;
        if (variables.state === 'off' && screensaver === 'off') {
            hass.callService('media_player', 'play_media', {
                entity_id: media_player.galaxy_tab,
                media_content_id: '/local/sound/on.m4a',
                media_content_type: 'music'
            });
        }
        if (variables.state_on && screensaver === 'off') {
            hass.callService('media_player', 'play_media', {
                entity_id: media_player.galaxy_tab,
                media_content_id: '/local/sound/off.m4a',
                media_content_type: 'music'
            });
        }
      ]]]
    action: toggle
    haptic: medium

Any and all help is very much appreciated! Have a good one :slight_smile:

Hi dear, how did u put the person in the sidebar? Can u show me the code?

2 Likes

Could you share the code for the weather button you have?

1 Like

hass-config-lajv de lukevink

1 Like

Wow, this looks amazing… did you happen to make a dryer one?

2 Likes

happy to, it was from this post A different take on designing a Lovelace UI - #3268 by htpc2308 and I made a few modifications.

this is a more advanced card and vary custom to my use case, and still a WIP

use

- type: custom:button-card
  entity: weather.home_2
  template:
    - base
    - weather
  tap_action:
    !include ../popup/weather.yaml

weather template

#################################################
#                                               #
#                    Weather                    #
#                                               #
#################################################

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}<sup>°</sup>`
        : '?';
    ]]]
    
  custom_fields:
    rain: |
        [[[
          return entity && entity.attributes && entity.attributes?.forecast
            ? `${ entity.attributes.forecast[0].precipitation_probability} % Rain`
            : '?';
        ]]]
        
    home: |
        [[[
          return entity 
            ? entity.state 
            : '?';
        ]]]
  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 n'
          'home home'
          'home home'
          'rain 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
      - width: 60%
      - justify-self: flex-end
    name:
      - justify-self: flex-end
      - font-size: 2.4rem
      - margin-top: 10%
      - font-weight: bold
      - text-transform: lowercase
    label:
      - width: 100%
    state:
      - justify-self: start
    card:
      - border-radius: calc(var(--button-card-border-radius) / 2)
      - padding: 1rem
      - height: 100%
      - background-position: center
      - background-size: cover
      - background-repeat: no-repeat
    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.7rem
        - font-weight: light  
      rain:
        - justify-self: flex-end
        - font-size: 1.4rem
        - font-weight: light
  # https://developers.home-assistant.io/docs/core/entity/weather/#recommended-values-for-state-and-condition
  extra_styles: |
            [[[
              let is_day = states['sun.sun'].state === 'above_horizon';
              let image_path = '/local/weather_back/';
              let cardBgColor = '';
              let cardBgImage = '';
              let image_name = '';
              if (entity && entity.state) {
                switch(entity.state) {
                  case 'sunny':
                  case 'clear-night':
                    image_name = is_day ? 'sunny_small.gif':'clear_night_small.gif';
                    break;
                  case 'windy':
                  case 'windy-variant':
                  case 'cloudy':
                    image_name = is_day ? 'cloudy_small.gif':'cloudy_night.gif';
                    break;
                  case 'fog':
                    image_name = 'fog_small.gif';
                    break;
                  case 'hail':
                    image_name = 'hail_small.gif';
                    break;
                  case 'lightning':
                  case 'lightning-rainy':
                    image_name = 'lightning_small.gif';
                    break;
                  case 'partlycloudy':
                    image_name = is_day ? 'partly_cloudy_small.gif':'partlycloudy_night.gif';
                    break;
                  case 'pouring':
                    image_name = is_day ? 'pouring.gif':'pouring_night.gif';
                    break;
                  case 'rainy':
                    image_name = is_day ? 'rainy_small.gif':'rainy_night.gif';
                    break;
                  case 'snowy':
                  case 'snowy-rainy':
                    image_name = 'snowy_small.gif';
                    break;
                  default:
                    cardBgColor = 'rgba(43, 104, 233, 1)';
                    image_name = '';
                    break;
                }
                cardBgColor = 'rgb(117,121,128)';
                cardBgImage = image_name != ''?'linear-gradient(to bottom, rgba(117,121,128,0.4) 10% , rgba(0,0,0,0.4) 38%), url(' + image_path + image_name + ')':none;
              }
              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);
                  }
                }
              `;
            ]]]

popup

action: fire-dom-event
browser_mod:
  command: popup
  title: Forecast  
  card:
    type: vertical-stack
    cards:
      - type: custom:mushroom-chips-card
        chips:
          - type: entity
            entity: sun.sun
          - type: template
            content: >-
              Sunrise  {% if states.sun.sun %} {{
              (as_timestamp(states.sun.sun.attributes.next_rising)) |
              timestamp_custom(('%H:%M') )}} {% endif %}
            icon: mdi:weather-sunset-up
          - type: template
            content: >-
              Sunset  {% if states.sun.sun %} {{
              (as_timestamp(states.sun.sun.attributes.next_setting)) |
              timestamp_custom(('%H:%M') )}} {% endif %}
            icon: mdi:weather-sunset-down
          - type: entity
            entity: sensor.moon_phase
        alignment: center
      - type: weather-forecast
        entity: weather.home_2
        secondary_info_attribute: humidity
        show_current: true
        show_forecast: true

backgrounds

note: the “pouring” image was too big you will need to hunt one down

Click to view images

clear_night_small
cloudy_night
cloudy_small
fog_small
hail_small
lightning_small
partly_cloudy_small
partlycloudy_night
pouring_night
rainy_night
rainy_small_new
snowy_small
sunny_small

8 Likes