A different take on designing a Lovelace UI

Excellent friend. I work perfect. Thank you very much
The only thing I don’t understand is where the color of the line comes from

You can just add the color parameter at the css styling

- color: '#html_color_code_here'

@Mattias_Persson how did you get it sorted to get the slide animation? Like, when you slide in your gif it has some depth to it. Mine just staticly slides from left to right.

1 Like

If I don’t change it in the repository, it has it as you want.

I was trying with line-color. Thank you

add effect: ‘coverflow’ to the parameters of the swipe card in ui-lovelace.yaml

- type: custom:swipe-card
            parameters:
              effect: 'coverflow'
              speed: 550
              spaceBetween: 40
              threshold: 5

here is the thread with examples

2 Likes

could you show an example were to place the color option in the code?

thx

Just don’t include something like a slider on your card , or do you have a solution for that? I mostly gave up on swiper because I could not have a slider that would not also cause swiping and my wife said “forget it”

Like input_number slider in a card which you can say “I am sliding that and not the card” … I gave up. Gave her a hold_action

I don’t understand exactly what you mean?
I just answered a question from @henkkeumus and provided the solution for the slide effect with deep.

here is my working example

swipe

1 Like

I know. What I meant was that inside your slider you cannot include something like a volume control input_number input … or at least I have never found a “decent” way that functions properly.

Given your example, what if I had this inside the slider?

image

Try then to change the volume. You can, clicking certainly. Sliding the volume control, kludgy at best. I tried many/most of the slider card parameters from slider.js and cannot get it to act like I would want it. Because sliding the volume control also slides the panel.

Oh and in testing again, implementing something with a hold-action seems to not work. I had a series of remote controls for my TVs and changed from swiper card to vertical stack and all hold actions now work (they do not on a PC with swiper).

Too bad because it is pretty … but pretty non-functional too for many cases.

Yes, that’s right, the swiper card is unfortunately very bitchy and hasn’t been developed further for ages.

but I think I would have done it when I had read the thread and tried everything possible.

It was never perfect but I think it was possible to get what you’re trying to do.
If I find the time again, I’ll try the whole thing again and then give you feedback.

EDIT
this can be a solution

allowTouchMove: false

How to add double arrow?

Thanks for the suggestion. In the end I went with collapse cards as they provided a GUI my wife and kids would use. They click to open the remote control and then do as they desire. No sliding involved and everything works.

For Anyone wanting it I created an Octoprint 3D Printer card to use with Matthias’s UI style:

image

button_card_templates.yaml code:

printer:
  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: sensor.octoprint_print_state
  custom_fields:
    circle: >
      [[[
        if (Math.round(states['sensor.octoprint_percentage_complete'].state) > 0 && states['sensor.octoprint_percentage_complete'].state < 100) {
          const input = states['sensor.octoprint_percentage_complete'].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>
          `;
        }
      ]]]

Modify the line below in the “base” template to include “Printing” as an “on” state:

Note: This is what controls when a card’s background turns white for future reference…

base:
  template:
    - settings
  variables:
    state_on: >
      [[[ return ['on', 'home', 'cool', 'fan_only', 'playing','Printing'].indexOf(entity === undefined || entity.state) !== -1; ]]]
    state: >
     . 
     .
     .
#Rest of base template

Icon Code (to be added to the bottom of button_card_templates.yaml):

icon_3dprinter:
  styles:
    custom_fields:
      icon:
        - width: 77%
        - margin-left: 1%
        - margin-top: 5%
  custom_fields:
    icon: >
      <svg viewBox="0 0 90 73">
        <<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g><rect fill="#9da0a2" x="0" y="63" width="90" height="10" rx="3"></rect><rect fill="#9da0a2" transform="translate(10.000000, 33.000000) rotate(90.000000) translate(-10.000000, -33.000000) " x="-23" y="30" width="66" height="6" rx="3"></rect><rect fill="#9da0a2" transform="translate(78.000000, 34.000000) rotate(90.000000) translate(-78.000000, -34.000000) " x="44" y="31" width="68" height="6" rx="3"></rect><path d="M7,3 C7,1.34314575 8.34757814,6.41357826e-15 9.99253964,6.2593707e-15 L78.0074604,-1.16714867e-16 C79.6601944,-2.71651068e-16 81,1.34651712 81,3 L81,3 C81,4.65685425 79.6524219,6 78.0074604,6 L9.99253964,6 C8.33980564,6 7,4.65348288 7,3 L7,3 Z" fill="#9da0a2"></path><rect fill="#9da0a2" x="16" y="56" width="56" height="3"></rect><rect fill="#9da0a2" transform="translate(44.000000, 26.500000) scale(1, -1) translate(-44.000000, -26.500000) " x="12" y="25" width="64" height="3"></rect><rect fill="#9da0a2" transform="translate(44.000000, 19.500000) scale(1, -1) translate(-44.000000, -19.500000) " x="12" y="18" width="64" height="3"></rect><rect fill="#9da0a2" x="25" y="23" width="15" height="10"></rect><rect fill="#9da0a2" x="31" y="31" width="3" height="4"></rect></g></g>>
      </svg>

lovelace.yaml code: add this to where you want the card to live in your dashboard

          - type: custom:button-card
            entity: sensor.octoprint_print_state
            tap_action: !include popup/Printer.yaml
            name: 3D Printer
            template:
              - base
              - printer
              - icon_3dprinter

and popup/Printer.yaml code: (this requires the threedy card from HACS)

action: fire-dom-event
browser_mod:
  command: popup
  title: Printer
  style:
    .: |
      :host .content {
        width: calc(385px + 510px);
        max-width: 90vw;
      }
      threedy-card div div div:nth-child(2) {
        height: auto !important;
        opacity: 1 !important;
            transform: none !important;
      }
    layout-card$grid-layout:
      $: |
        hui-vertical-stack-card {
          animation: border 1s forwards;
        }
        @keyframes border {
          0%, 100% {
              border-right: 1.5px solid rgba(0, 0, 0, 0.2);
          }
        }
        /* phone */
        @media screen and (max-width: 800px) {
          hui-vertical-stack-card {
              border-bottom: 1.5px solid rgba(0, 0, 0, 0.2);
              padding-right: 0;
              animation: none;
          }
        }
      $hui-vertical-stack-card:
        $: |
          hui-horizontal-stack-card {
            padding: 0em 2em 2.3em 2em;
          }
        $hui-entities-card$: |
          .card-content {
            padding: var(--card-content-padding);
          }
        $hui-horizontal-stack-card$: |
          #root {
            justify-content: space-evenly;
          }
  card:
    type: custom:threedy-card
    base_entity: sensor.octoprint
    monitored:
      - Status
      - ETA
      - Elapsed
      - Hotend
      - Bed
      - Remaining
    printer_type: I3
    name: Prusa Mk2.5S Bear
    theme: Default
    temperature_unit: C

NOTE: using this card requires you to add the following template sensors:

template:
  - sensor:
      - unique_id: OctoPrint Time Elapsed
        name: "OctoPrint Time Elapsed"
        unit_of_measurement: "s"
        availability: >
          {{ not is_state('sensor.octoprint_start_time', 'unavailable') }}
        state: >
          {% set start = as_timestamp(states('sensor.octoprint_start_time')) %}
          {% if is_number(start) %}
            {{ (as_timestamp(now()) - start) | int }}
          {% else %}
            unknown
          {% endif %}
        attributes:
          start_time: "states('sensor.octoprint_start_time')"

      - unique_id: OctoPrint Time Remaining
        name: "OctoPrint Time Remaining"
        unit_of_measurement: "s"
        availability: >
          {{ not is_state('sensor.octoprint_estimated_finish_time', 'unavailable') }}
        state: >
          {% set finish = as_timestamp(states('sensor.octoprint_estimated_finish_time')) %}
          {% if is_number(finish) %}
            {{ (finish - as_timestamp(now())) | int }}
          {% else %}
            unknown
          {% endif %}
        attributes:
          start_time: "states('sensor.octoprint_estimated_finish_time')"

      - unique_id: OctoPrint Percentage complete
        name: "OctoPrint Percentage Complete"
        unit_of_measurement: "%"
        state: >
          {{ states['sensor.octoprint_job_percentage'].state | round(0)}}

      - unique_id: OctoPrint Print State
        name: "OctoPrint Print State"
        state: >
          {% if is_state('sensor.octoprint_current_state', 'Operational') %}
            idle
          {% elif is_state('sensor.octoprint_current_state', 'Printing from SD') %}
            Printing
          {% elif is_state('sensor.octoprint_current_state', 'Starting print from SD') %}
            Printing
          {% else %}
            Down
          {% endif %}

Threedy Card can be found here although be warned it seems to be a dead project:
https://github.com/dangreco/threedy

BE WARNED: The pop-up card does not currently scale to mobile resolutions as the code above stands… I’m not an expert by any means but I THINK it’s because the threedy card does not support it but if someone wants to swing by the thread and see if I messed up the scaling somewhere along the way let me know…

4 Likes

you mean behind the name?

title: Wohnzimmer ↔

easy copy it here and paste it in your ui-lovelace.yaml behind the name

2 Likes

anyone else having issue with sidebar not showing after update to Home Assistant 2022.7.0 my sensor.template_sidebar doesn’t exsist anymore the state list

1 Like

Mine is working fine. Did you check the update blog to see what breaking changes they did? They did some changes to Google Calendars so maybe that might be affecting you.

Indeed! I have it too.

Thought it was the sonoff update at first but maybe its the version update… ill rollback the backup from yesterday.

Hello. How do I identify if it is the battery percentage or the lock, what I want to see in the upper right space.

Because the circle is configured with a width of 45 and so the padlock looks good but the percentage does not. Since the two share the same configuration. Do I have a way to put a condition to know who I am setting that width for? Thank you

Sin título

lock:
  tap_action:
    loader: |
      [[[
        let elt = this.shadowRoot;
        if (variables.state_on && variables.lock === 'locked') {
          elt.getElementById('lock').classList.add('locked');
          window.setTimeout(() => {
            elt.getElementById('lock').classList.remove('locked');
          }, 1100);
        } else {
          let loader = (id, style, timeout) => {
              elt.getElementById(id) && (elt.getElementById(id).style.display = style,
                window.setTimeout(() => {
                  elt.getElementById('loader').style.display = 'none'
                }, 20000))
          };
          loader('circle', 'none', 'initial'),
          loader('loader', 'initial', 'none');
        }
      ]]]
  custom_fields:
    circle: >
      [[[
        if(entity) {
          let state = states[entity.entity_id + '_estado_de_sesion'].state.toLowerCase();
          if (state === 'locked') {
            return `
              <svg viewBox="0 0 50 50">
                <style>
                  @keyframes locked {
                    from,
                    to {
                      transform: translateX(0);
                    }
                    10%,
                    30%,
                    50%,
                    70%,
                    90% {
                      transform: translateX(-8%);
                    }
                    20%,
                    40%,
                    60%,
                    80% {
                      transform: translateX(8%);
                    }
                  }
                  .locked {
                    animation: locked 1.1s;
                  }
                </style>
                <path id="lock" class="${state}" d="M8.2 22.6h2.4v-7.2C10.6 7.5 17.1 1 25 1s14.4 6.4 14.4 14.4v7.2h2.4V49H8.2m26.4-26.4v-7.2c0-5.3-4.3-9.6-9.6-9.6s-9.6 4.3-9.6 9.6v7.2"/>
              </svg>
            `;
          } else {
            let bateria = "";        
            const stroke_color = '#b2b2b2';
            const fill_color = 'none';
            if(entity.state == 'online') {
              if(entity.entity_id == 'sensor.pc_florencia') 
                bateria = states['sensor.pc_florencia_bateria_charge_remaining_percentage'].state + "%";
              if(entity.entity_id == 'sensor.pc_milena') 
                return;
              let stroke_color = '#b2b2b2';
              let fill_color = 'rgba(255,255,255,0.04)';
              return `
                <svg viewBox="0 0 50 50">
                  <circle cx="29" cy="21" r="20.5" stroke="${stroke_color}" stroke-width="1.5" fill="${fill_color}" />
                  <text x="60%" y="45%" fill="#8d8e90" font-size="14" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle">${bateria}</text>
                </svg>
              `;
            }
          }
        }
      ]]]
  styles:
    custom_fields:
      circle:
        - width: 45%
        - fill: var(--state-icon-color)
        - margin: 1% 2% 0 0
        - justify-self: end
        - opacity: 1
        - display: grid

Hey Lars,

I’ve restored a backup from yesterday. This backup is on the latest version 2022.7.0 and sidebar works.

I’m now going to update the Sonoff LAN intergration from HACS as that was something I updated too as the intergration broke yesterday due to an issue with an ID hidden in the code.

… Maybe that breaks it… I’ll report back in a min :slight_smile: