A different take on designing a Lovelace UI

When I look in my logfile I get "*

[homeassistant.helpers.template] Template variable warning: ‘None’ has no attribute ‘state’ when rendering ' {% set lights = [

what does that mean ?

Probably you have at least one wrong entity in the sidebar.yaml . Did you replace Mattias’es ones with yours?

      active: >
          <b>
          {% set lights = [
            states.light.vardagsrum_tv,
           ...........
            states.switch.deltaco_sh_p01_socket
          ] %}

image
looking great on desktop.

Bildschirmfoto 2023-02-03 um 15.03.36
Any ideas, on how to add a line break, or marquee on mobile?

what do you mean by “wrong” ? a typo ?

Well if I understand it correctly for HA - “None” is a state which means undefined. Thus you might have a sensor, but it has not been initialized to a value yet, or there is a misspelling and thus that sensor doesn’t actually exist and therefore it is “None”.

You could check this in various ways, either by checking them through Developer Tools>States for each sensor/entity which you added in your template; Or copying your template in Developer Tools>Templates and then testing that one to check which is the one which returns “None”

So if the template was like this

{% set lights = [
            states.light.vardagsrum_tv
             ] %}
.......

It would return the None template issue because the light doesn’t actually exist as seen below.

This has been bothering me, too.
Your question was just the push I needed to try and come up with a temporary solution - and I think I got something working.
I’d much prefer if the root cause got fixed, but let’s make this a learning experience.
It’s not the most elegant, but it does the job – hopefully.

Preview

Plex Recently Added Backup

image

Requirements

Helper (Helper entity, to store the info)

Example: input_text.backup_plex_recently_added

I created one via the GUI:
Navigate using command: Press the letter C → Type: Helpers → Press enter

image

Or, browse here: Settings → Devices & Services → Helpers → Create Helper → Text

image

OBS: Maximum length should be 255

Template sensor (To make it easier with JavaScript later)

This is unnecessary, but it makes sense to me that we have a sensor with attributes.
I tried creating an attribute with a dict similar to the ‘Recently Added’ sensor, but jinja and the formatting got weird on me, so I just did this for now:

This sensor is grabbing the state of the input_text helper, and cleans it up.

Like this

Template select

Updated the select template to handle the new sensor.

Automation (To take backup of 1 item in the ‘Recently Added’ sensor)

Not tested properly yet…

Triggers

platform: state
entity_id:
  - sensor.recently_added_mix
to: Online

Conditions

condition: template
value_template: >-
  {{ trigger.to_state.state not in [trigger.from_state.state, 'cannot be
  reached', 'unavailable', 'undefined','unknown','none','null'] }}

Actions

service: input_text.set_value
data:
  value: >-
    {% if not states('sensor.recently_added_mix') in
    ['unavailable','undefined','unknown','none','null','0'] %}
      {% set state = namespace(return='') %}
      {% set data = state_attr('sensor.recently_added_mix','data') %}
      {%- for value in data %}
        {%- if not loop.first and value is defined and state.return == '' %}
          {%- if not value.number is defined %}
            {% set state.return = 
              "aired:" + value.aired + "|" +
              "title:" + value.title  + "|" +
              "fanart:" + value.fanart + "|" +
              "poster:" + value.poster
            %}
          {%- else %}
            {% set state.return = 
              "aired:" + value.aired + "|" +
              "title:" + value.title  + "|" +
              "number:" + value.number  + "|" +
              "fanart:" + value.fanart + "|" +
              "poster:" + value.poster
            %}
          {%- endif %}
        {%- endif %}
      {%- endfor %}
      {{ state.return }}
    {% endif %}
target:
  entity_id: input_text.backup_plex_recently_added

lovelace.yaml – swipe-card update

button_card_templates.yaml – conditional_media update

(state_display and background-image)

Edit: Added a change in the text color.
This is optional, of course, but I wanted another indicator that something was wrong.

conditional_media:

        - color: >
            [[[
              if (entity.state === "Active") {
                return entity === undefined
                    ? '#97989c'
                    : 'rgba(239, 239, 239, 0.5)';
              }
              else {
                return entity === undefined
                    ? '#97989c'
                    : '#efefef';
              }
            ]]]

PS: I haven’t tested it fully yet, so try at your own risk :wink:

6 Likes

Where do put my enitiy for the temperature on the clima tab?
image

The original one is set up like this. If the entity state is ‘cool’, it’ll display entity.attributes.temperature if the state is anything other than cool, it’ll display entity.attributes.current_temperature. If your device doesn’t have those attributes, you’ll have to modify the circle_input for that button card.

Thank you for clarifying, However my air cleaner from Electrolux does not have attributes… Is it possible to add a entity instead?

yep, you should add the temp sensor entity to triggers_update: if you want the temp to update on the card without the button card entity updating. You’ll also want to modify circle_input to use the triggers_update entity. Here’s an example

- type: custom:button-card
  entity: climate.downstairs
  name: HVAC
  double_tap_action:
    !include popup/downstairs_climate.yaml
  triggers_update: sensor.fireplace_temp
  template:
    - base
    - icon_climate
    - circle
  variables:
    circle_input: "[[[ return Math.round(states[this._config?.triggers_update].state).toString(); ]]]"
    circle_input_unit: '°F'
4 Likes

Well… THANK YOU! <3
image

Hi Br3b, would you share the code from the weather widget? Mine looks like this…

Bildschirm­foto 2023-02-06 um 17.40.31

what do I have to adjust?

After spending lots of time a beautiful picture on the wall! Thanx a lot Mattias!!!

I read everything and learned a lot. But I’m not clear how the sidebar works.

The date has now disappeared, it was in the sidebar.yml, I placed it in a sidebar_time.yml, unfortunately that didn’t work either. It’s also not clear to me where to put what. Do you make a separate yml file for each item? Hopefully someone can help me with this. Can be done via DM or comment. Many thanks in advance!

Hi @weaverprojects,
the card template is not mine.
I just adjusted the “- margin-left: 10%” for all objects in the card. Hope it helps.

  widget_weather:
    variables:
      temp_min: ''
      temp_max: ''
      precip: ''
    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%
      card:
        - color: rgba(255, 255, 255, 0.8)
        - background: |
            [[[
              if (states['sun.sun'].state == 'below_horizon'){
                return 'linear-gradient(to top, rgba(53,59,83,1) 0%, rgba(10,14,34,1) 100%)';
              } else
                return 'linear-gradient(to top, rgba(123,168,197,1) 0%, rgba(61,132,176,1) 100%)';
            ]]]        
      state:
        - margin-left: 12%
      name:
        - place-self: start
        - margin-left: 10%
        - text-transform: uppercase
        - font-weight: 400
      img_cell:
        - margin-left: 10%
        - justify-content: start
      icon:
        - width: 25%
        - margin-left: 7%
      label:
        - margin-left: 7%
        - place-self: start
      custom_fields:
        temp:
          - place-self: start
          - margin-left: 10%
    custom_fields:
      temp: |
        [[[ return entity.attributes.temperature + "°"; ]]]    
    label: |
      [[[
          if (window.navigator.userAgent.match(/iPhone/i)) {
            return         `<ha-icon
            icon="mdi:arrow-up-thin"
            style="width: 15px; height: 15px; margin-right: -6px;">
            </ha-icon><span> ${states[variables.temp_max].state}°</span>
                  <ha-icon
            icon="mdi:arrow-down-thin"
            style="width: 15px; height: 15px; margin-right: -6px;">
            </ha-icon><span> ${states[variables.temp_min].state}° </span>       
          `;
                }
          else {
                    return `<ha-icon
            icon="mdi:arrow-up-thin"
            style="width: 15px; height: 15px; margin-right: -5px;">
            </ha-icon><span> ${states[variables.temp_max].state}°</span>
                  <ha-icon
            icon="mdi:arrow-down-thin"
            style="width: 15px; height: 15px; margin-right: -5px; margin-left: -5px;">
            </ha-icon><span> ${states[variables.temp_min].state}° </span>       
                  <ha-icon
            icon="mdi:weather-pouring"
            style="width: 14px; height: 14px; margin-right: -2px; margin-left: -1px;">
            </ha-icon><span> ${states[variables.precip].state}%</span>
          `}
      ]]]
    entity_picture: |
      [[[
        return entity && entity.state
          ? `/local/animated-weather-icons/${entity.state}.svg`
          : '?';
      ]]]
    extra_styles: |
      [[[
        return `
          #name {
            font-size: 1vw;
          }
          #temp {
            font-size: 1.9vw;
          }
          #state {
            font-size: 0.60vw;
          }  
          #label {
            font-size: 0.60vw;
          }
          /* portrait */
          @media screen and (max-width: 1200px) {
            #name {
              font-size: 1.3vw;
            }
            #temp {
              font-size: 4.5vw;
            }
            #state {
              font-size: 1.1vw;
            }  
            #label {
              font-size: 1.1vw;
            }
          }
          /* phone */
          @media screen and (max-width: 800px) {
            #name {
              font-size: 3vw;
            }              
            #temp {
              font-size: 2.5vw;
            }    
            #state {
              font-size: 1.8vw;
            }
            #label {
              font-size: 2.25vw;
            }
                   
          }
          @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);
            }
          }
        `
      ]]]
1 Like

sidebar.yaml (at least the one in the base directory) is nothing more than a template sensor. The sections themselves like time, date, greet are attributes of that sensor. If you look in button_card_templates/sidebar.yaml you’ll see how they’re displayed.

If you did want to separate things out or display some other info in a different template sensor, you can put yaml files in the packages folder, but include template: as the first line.

template:
  - sensor:
    ...

You’ll then have to add any new sensor to the sidebar section of ui-lovelace.yaml for it to show up.

A quick example would be
packages/sun_rising.yaml

template:
  - sensor:
    - unique_id: Sun Rising
      state: template
      attributes:
        sun: >
          {% if is_state("sun.sun", "above_horizon") -%}
            The sun rose {{ relative_time(states.sun.sun.last_changed) }} ago.
          {%- else -%}
            The sun will rise at {{ as_timestamp(state_attr('sun.sun', 'next_rising'), '%Y-%m-%d %H:%M:%S') | timestamp_custom("%A @ %-I:%M %p") }}.
          {%- endif %}

ui-lovelace.yaml

...
      #################################################
      #                                               #
      #                    SIDEBAR                    #
      #                                               #
      #################################################

      - type: vertical-stack
        view_layout:
          grid-area: sidebar
        cards:

          - type: custom:button-card
            entity: sensor.template_sidebar
            template: sidebar

          - type: custom:button-card
            entity: sensor.sun_rising
            template: sidebar
...

An alternate option is creating new attributes in sidebar.yaml to display whatever you want. Those will automatically be added since the sidebar template loops through all available attributes of the sensor.

1 Like

Hey guys, any idea how i can change this gap:

THNX!! Did the trick!

hello,

i tried to replace the background of the theme, its the background.png under local or www or?

i tried to replace an reboot and deletet my browser cache but no luck

Just add a padding in the template

... card:
      - padding: 10.9% 9.9% 8.9% 10.9%;
 #Additional padding to the template (Based on the % found on the extra_styles.yaml)
1 Like

check what path you have assigned based on the themes.yaml file
Matts is like:

    card-mod-root: |
      ha-app-layout {
        background: url('/local/background.png');
        background-size: cover;
      }

The file would be in: www/background.png

Based on my own experiences the background was sometimes missing (full-on black) when a card would be broken (Erroring out). Not sure why is this thing; but that’s what I use as an early identifier of a broken card sometimes😂