A different take on designing a Lovelace UI

Hey Se7enair. Love your Thermostat changes from over a year ago :joy:.
I’ve set it up. I get no errors, the temperature shows in the button. It shows it “off” as it should be.
All seems fine. But when I click on it, nothing happens. I don’t get that blue circle that usually shows up when I click hold a button for the popup.
When I turn on the Thermostat the whole button disappears.
I have a nest thermostat.
I did install Thermostat pop up card and added the resources.
Did you figure anything else from a year ago? :sweat_smile:
Am I missing anything else?
Maybe an update to the card which breaks something? Seeing that you did this over a year ago…

I meant… my nas? I’m guessing? Too bad I use a Qnap and it doesn’t seem like HA integrates with the model I have TS-251. Argh!

How can I change this code so that the person button shows Home if home, a known zone if the zone is known and away if not home and the zone is not known?

person:
    template:
      - base
      - circle
    state_display: >
      [[[ return variables.state === 'home' ? 'Home' : 'Away'; ]]]
    triggers_update: sensor.time
    styles:
      custom_fields:
        icon:
          - clip-path: circle()
          - width: 79%
          - pointer-events: none
          - display: grid
    custom_fields:
      icon: >
        [[[ return entity === undefined ? null : `<img src="${states[entity.entity_id].attributes.entity_picture}" width="100%">`; ]]]
      circle: >
        [[[
          const time = c => {
            const s = (c / 1000);
            const m = (c / (1000 * 60));
            const h = (c / (1000 * 60 * 60));
            const d = (c / (1000 * 60 * 60 * 24));
            if (s < 60) {
              return parseInt(s) + 's';
            } else if (m < 60) {
              return parseInt(m) + 'm';
            } else if (h < 24) {
              return parseInt(h) + 'h';
            } else {
              return parseInt(d) + 'd';
            }
          };
          let last_changed = entity === undefined  ? ' ' : (time(Date.now() - Date.parse(states[entity.entity_id].last_changed)));
          const stroke_color = variables.state === 'Home' ? '#b2b2b2' : 'none';
          const fill_color = variables.state === 'Away' ? 'rgba(255,255,255,0.04)' : 'none';
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="20.5" stroke="${stroke_color}" stroke-width="1.5" fill="${fill_color}" />
              <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${last_changed}</text>
            </svg>
          `;
        ]]]

I solved it like this. Probably not the most elegant way but it works :slight_smile:

    state_display: |
      [[[ if (variables.state === 'home' ) {return 'Zuhause';}
          else if (variables.state === 'Karls Arbeit') {return 'Auf Arbeit';}
          else if (variables.state === 'Yuhes Arbeit') {return 'Auf Arbeit';}
          else {return 'Abwesend';}
      ]]]

Greetings

2 Likes

How can I make a different presentation on PC and phone? I don’t see how to do it or how to do it.
Actually my PC dashboard is the same as on my iphone apps. it’s not responsive at all.
I think it must come from ui-lovelace but I don’t see what’s wrong.

button_card_templates: !include button_card_templates.yaml

views:
  - type: custom:grid-layout
    path: 0
    layout:
      #default
      grid-gap: var(--custom-layout-card-padding)
      grid-template-columns: repeat(4, 1fr) 0
      grid-template-rows: 0 repeat(2, fit-content(100%)) 0fr
      grid-template-areas: |
        "sidebar  .        .       .           ."
        "sidebar  salon  toi_moi  temperature  ."
        "sidebar  media  ch_enfants  maison    ."
        "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    ."
          ".  salon       toi_moi    ."
          ".  temperature media      ."
          ".  ch_enfants  maison     ."
          ".  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  salon     toi_moi       ."
          "sidebar  temperature media       ."
          "sidebar  ch_enfants maison       ."
          "sidebar  footer      footer      ."
          "sidebar  .           .           ."
    cards:

      - type: custom:button-card

maybe you need to play around with the max-width for the phone?

I am very impressed with your work.
I’m trying to copy your configuration to Homeassistant Core, but I can’t.

Can you explain to me in small steps how it works, that I get it to work?

Thanks in advance.

I tried to overwrite the variable for the circle_input on my humidifier card.
But I only get this:
image

What is wrong? Tried many options for the variable, but I dont get it.

ui-lovelace.yaml

            variables:
              circle_input: >
                states['sensor.wohnzimmer_luftbefeuchter_fuellstand'].state;
            template:
              - base
              - circle
              - luftfeuchtigkeit
              - icon_fan
              - light

button-card-templates isn’t modified in the parts circle and light

Sounds like there is a problem with the naming. I think the states has other names then on my system.
The popup has to be investigated.
Can you show us your code?

Post Deleted

I used your code straight up. Just changed one or two colors to match the Nest thermostat color scheme.

ui-lovelace

- type: custom:button-card
            entity: climate.living_room
            name: Climate
            style:
              top: 20.35%
              left: 55.18%
              width: 10%
            template: climate

button_card_template

climate:
    template: ['base']
    aspect_ratio: 1/1
    show_state: true
    show_icon: false
    show_name: true
    show_current_temperature: true
    show_control: true
    state:
      - operator: template
        value: >
          [[[ return (states[entity.entity_id].attributes.preset_mode == 'none') && (states[entity.entity_id].state == 'heat') ]]]
        styles:
          card: [background-color: 'rgba(255, 255, 255, 0.8)']
          name: [color: 'rgba(0, 0, 0, 0.6)']
          state: [color: 'rgba(0, 0, 0, 0.6)']
      - operator: template
        value:  >
          [[[ return (states[entity.entity_id].attributes.preset_mode == 'Full Power') ]]]
        styles:
          card: [background-color: 'rgba(250, 0, 49, 0.4)']
    tap_action:
      action: call-service
      service: browser_mod.popup
      service_data:
        title: '[[[ return entity.attributes.friendly_name ]]]'
        deviceID: this
        card:
          type: entities
          entities:
            - type: custom:thermostat-popup-card
              entity: '[[[ return entity.entity_id ]]]'
              icon: none
              fullscreen: false
              brightnessWidth: 130px
              brightnessHeight: 360px
              borderRadius: 1.7em
              sliderColor: '#c7c7c7'
              sliderTrackColor: rgba(25, 25, 25, 0.9)
              actionSize: 4.5em
              actionsInARow: 2
    custom_fields:
      circle_current: >
        [[[ {
        const temperature = entity.attributes.current_temperature;
        const stroke_color = entity.state === 'heat' ? '#b2b2b2' : '#313638'; 
        const fill_color = entity.state === 'heat' ? '#F29B00' : '#FFFFFF08';
        const radius = 28;
        return `<svg viewBox="0 0 60 60"><circle cx="30" cy="30" r="${radius}" stroke="${stroke_color}" stroke-width="1.5" fill="${fill_color}" style="
        transform: rotate(-90deg); transform-origin: 50% 50%; " />
        <text x="50%" y="54%" fill="#f7f8fa" font-size="18" text-anchor="middle" alignment-baseline="middle">${temperature}<tspan font-size="10">°</tspan></text></svg>`; } ]]]
      circle_target: >
        [[[ if (entity.state === 'heat' && entity.attributes.temperature) {
        const temperature = entity.attributes.temperature;
        const valve_position = entity.attributes.valve_position;
        const valve_position_num = valve_position.slice(0, -1);
        const stroke_color = entity.state === 'heat' ? '#b2b2b2' : '#313638'; 
        const fill_color = entity.state === 'heat' ? 'none' : '#FFFFFF08';
        const radius = 20.5; const circumference = radius * 2 * Math.PI; 
        return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="${radius}" stroke="${stroke_color}" stroke-width="1.5" fill="${fill_color}" style="
        transform: rotate(-90deg); transform-origin: 50% 50%; stroke-dasharray: ${circumference}; stroke-dashoffset: ${circumference - valve_position_num / 100 * circumference};" />
        <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle">${temperature}<tspan font-size="10">°</tspan></text></svg>`; } ]]]
    styles:
      name:
        [top: 57.7%, left: 11%, line-height: 2vw, position: absolute]
      state:
        [top: 74%, left: 11%, line-height: 2vw, position: absolute]
      card:
        [font-family: Sf Display, letter-spacing: 0.05vw, font-weight: 400, color: 'rgba(255, 255, 255, 0.3)', font-size: 1.34vw, background-color: 'rgba(115, 115, 115, 0.2)', border-radius: 0.8vw, box-shadow: none, transition: none]
      custom_fields:
        circle_target: 
          [top: 6.5%, left: 54.5%, width: 3.5vw, position: absolute, letter-spacing: 0.03vw]
        circle_current: 
          [top: 6.5%, left: 6%, width: 3.5vw, position: absolute, letter-spacing: 0.03vw]

And this is my climate.livingroom state info

hvac_modes: heat, off, heat_cool, cool, fan_only
min_temp: 7
max_temp: 35
fan_modes: on, off
preset_modes: none, eco
current_temperature: 22.2
temperature: null
target_temp_high: null
target_temp_low: null
fan_mode: off
hvac_action: off
preset_mode: none
friendly_name: Living Room
supported_features: 27

haha nice… yeah, not so nice but I’ll take it… Works… Thanks a ton

Another quick question, when I see some styling like this:

font-family: SF Text

But my font name is SF-UI-Text-Regular, SF-UI-Text-Bold, etc
Will font-family: SF Text understand that or should I change it to
font-family: SF-UI-Text
?

You indentation is wrong under mediaquery

  • Are you sure that you’re not meaning to access the attribute instead of state?

  • Do you have any comments under the [[[ ]]] thats messing up the js?

  • Have you tried name: "[[[ return states['sensor.wohnzimmer_luftbefeuchter_fuellstand'].state; ]]]" to better see the output?

yes, I want the state

no comments under [[]]

name: “[[[ return states[‘sensor.wohnzimmer_luftbefeuchter_fuellstand’].state; ]]]”
image

The other thing I can see, the name is aligned to the center?

If i add a new custom_field directly to the button-card, everything is working as expected

            custom_fields:
              circle: >
                [[[
                  if (variables.state === 'on') {
                    const input = states['sensor.wohnzimmer_luftbefeuchter_fuellstand'].state;
                    const radius = 20.5;
                    const circumference = radius * 2 * Math.PI;
                    return `
                      <svg viewBox="0 0 50 50">
                        <style>
                          circle {
                            transform: rotate(-90deg);
                            transform-origin: 50% 50%;
                            stroke-dasharray: ${circumference};
                            stroke-dashoffset: ${circumference - input / 100 * circumference};
                          }
                          tspan {
                            font-size: 10px;
                          }
                        </style>
                        <circle cx="25" cy="25" r="${radius}" stroke="#b2b2b2" stroke-width="1.5" fill="none" />
                        <text x="50%" y="54%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${input}<tspan font-size="10">%</tspan></text>
                      </svg>
                    `;
                  }
                ]]]

For the popup, did you installed the thermostat-popup-card? Back then I used a addon. Now I am using the integrated thermostat card as Matt did.

Try to delete the second operator under state. Your system does not have a “Full Power”. So this can cause a problem.

Tackar!
Nano gjorde susen :slight_smile:

1 Like

So you aren’t doing your color thing anymore? I loved the color thing you had going in the temperature circle itself. Quite smart. Yes, I am using the thermostat popup that you were using. Oh you are still using the colors. it’s in the climate template.
I did try to change the modes around but it didn’t seem to work either. When I turn the thermostat on from the thermostat, the whole bottom row of buttons just disappear!

I tried to make the Living Room square be on a swipe card. It work fine but now I can’t click hold on the lights to get the light popups nor the thermostat that gives me the living room_climate.yaml popup. Could any one tell em what I did wrong?

**      - type: grid
        title: Living Room
        view_layout:
          grid-area: livingroom
        columns: 1
        cards:
          - 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: grid
                columns: 2
                cards:
                  - type: custom:button-card
                    entity: light.livingroom_group #hue_group
                    name: Hue Lights
                    template:
                      - light
                      - icon_hue

                  - type: custom:button-card
                    entity: light.vera_main_lights
                    name: Main
                    template:
                      - light
                      - icon_shade

                  - type: custom:button-card
                    entity: climate.living_room
                    name: Climate
                    style:
                      top: 20.35%
                      left: 55.18%
                      width: 10%
                    template:
                      - climate
                    tape_action: !include popup/livingroom_climate.yaml

                  - type: custom:button-card
                    entity: light.vera_livingroom_fan
                    name: Fan
                    hold_action: !include popup/fan.yaml
                    template:
                      - base
                      - icon_fan2
                      - loader

              - type: grid
                columns: 2
                cards:
                  - type: custom:button-card
                    entity: light.hue_livingroom_corner
                    name: Corner
                    template:
                      - light
                      - icon_hue

                  - type: custom:button-card
                    name: TV
                    entity: light.hue_livingroom_tvlights
                    template:
                      - light
                      - icon_tv

                  - type: custom:button-card
                    entity: light.hue_livingroom_phonelamp
                    name: Phone
                    template:
                      - light
                      - icon_hue

                  - type: custom:button-card
                    entity: light.hue_livingroom_imac
                    name: iMac
                    template:
                      - light
                      - icon_shade**

:sweat_smile::grimacing:
I know I’m abusing all of you and I’m really sorry. But this is so nice… I have to get it. :wink:

By the way Mattias, how do you deal with updates? I’m still reading this thread, at post 1100 at the moment and I often read people complaining about broken things after an update. Is core-2021.11.0 that just came out safe?
It seems like all my adons cards are also being updated. Do we wait for the go? Or do we all just go for it?