A different take on designing a Lovelace UI

Hi @djoaza, thanks for the reply! On what yaml file? do you have the name ? Thxs!!

button_card_templates/settings.yaml
Search for the rest on github matt8707.
Enter the name in Swedish in the search engine and you will find the file and replace it

@Mattias_Persson
I have updated/migrated my setup after about 6 months of pause to the actual version.
Most of the features work well.
But mushroom popups don’t appear at all. Non-mushroom popups work well after minor fixes.
At glance, there are no related errors in the logs.
All core/themes/hacs/integrations are updated.
Is there any idea where to start to dig**?**…
I don’t really want to reinstall everything from scratch…

2022-10-22 01:41:56.157 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration pirateweather which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-10-22 01:41:56.159 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration webrtc which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-10-22 01:41:56.161 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration monitor_docker which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-10-22 01:41:56.162 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-10-22 01:41:56.164 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration browser_mod which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2022-10-22 01:42:10.895 ERROR (MainThread) [homeassistant.components.media_player] The androidtv platform for the media_player integration does not support platform setup. Please remove it from your config.
2022-10-22 01:42:13.426 WARNING (MainThread) [homeassistant.components.weather] custom_components.pirateweather.weather::DarkSkyWeather is overriding deprecated methods on an instance of WeatherEntity, this is not valid and will be unsupported from Home Assistant 2023.1. Please report it to the custom integration author.
2022-10-22 01:42:16.922 WARNING (MainThread) [homeassistant.helpers.frame] Detected integration that uses pressure utility. This is deprecated since 2022.10 and will stop working in Home Assistant 2023.4, it should be updated to use unit_conversion.PressureConverter instead. Please report issue to the custom integration author for pirateweather using this method at custom_components/pirateweather/weather.py, line 169: return round(convert_pressure(pressure, PRESSURE_HPA, PRESSURE_INHG), 2)
2022-10-22 01:42:19.355 WARNING (MainThread) [homeassistant.setup] Setup of rest is taking over 10 seconds.
2022-10-22 01:42:23.011 WARNING (MainThread) [homeassistant.config_entries] Config entry 'C7000v2 (Gateway)' for upnp integration not ready yet: Device not discovered: uuid:upnp-InternetGatewayDevice-1_0-94a67e8f165e::urn:schemas-upnp-org:device:InternetGatewayDevice:1; Retrying in background
2022-10-22 01:42:26.106 ERROR (MainThread) [homeassistant.components.calendar] Entity id already exists - ignoring: calendar.kupit

hi @Nayre, I will assume that you have restated home assistant and confirmed that mushroom UI installed correctly and is working, on normal dashboards. and that you testes double tap to open the popup not hold.

if so this is the location of the light popup that uses mushroom hass-config/light.yaml at d76ee602acf69754125e17ec91a1d356c0cc42c8 · matt8707/hass-config · GitHub

I would compare the above with your file and see if it is the same.

Hi Davide,

You button cards look great - would you have any code around displaying them or pointers to similar configurations on the forum?

Thanks,

J

1 Like

OMG… I spent already more than 5 hours in total trying to resolve that (reviewing configs, templates etc)…
But I really missed the point - it’s double tap now…
Sorry, seems everything works as it should, I just missed the point that the interactions have been changed from hold to double tap…
Thanks!!!

1 Like

don’t worry about it, it was hard for me to get use to, and im still finding buttons with custom action’s that I don’t use much are still on hold

hey together, im lost in the coding and would greatly appreciate if someone could help me what im doing from with my code…

what i want to achieve see in the pic (a custom element with a graphical diagramm of my energy usage):
grafik

what i have done:

  1. added this to icons.yaml
icon_energy:
  custom_fields:
    icon: >
      <svg viewBox="0 0 1000 1000">
        <path fill="#9da0a2" d="M496.2,10L255.5,499.5h185.9L212.5,990l568.2-667.6H552.2L787.5,10H496.2z"/>
      </svg>
  1. added a new energy.yaml in button_card_Templates folder with the following content:
#################################################
  #                                               #
  #                  Energy                  #
  #                                               #
  #################################################

energy:
  template:
    - base
  show_name: false # Hides Card Name
  show_state: true # Hides Card state
  state_display: >
    [[[ return '&nbsp;'; ]]]
  custom_fields:
    circle: >
      [[[ {
      let stromzaehler_online = states['sensor.funktionsstecker_buero_power'],
        stromzaehler_color = stromzaehler_online.state === 'off' ? '#8b0000' : 'none';
      const energy = Math.round(entity.state * 10) / 10;
      return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="20.5" stroke="#313638" stroke-width="1.5" fill="${stromzaehler_color}" style="
      transform: rotate(-90deg); transform-origin: 50% 50%;" />
      <text x="50%" y="54%" fill="#8d8e90" font-size="16" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle" dominant-baseline="middle">${energy}<tspan font-size="10"> kWh</tspan></text></svg>`; } ]]]
    graph:
      card:
        type: "custom:mini-graph-card"
        height: 140
        hours_to_show: 12
        points_per_hour: 6
        line_width: 8
        font_size: 75
        decimals: 0
        show:
          name: false
          icon: false
          state: true
          legend: false
          labels: false
          labels_secondary: false
          points: false
        color_thresholds:
          - value: 100
            color: "#276696"
          - value: 300
            color: "#228C22"
          - value: 600
            color: "#d35400"
          - value: 1000
            color: "#c0392b"
      card_mod:
        style: |
          .states {
            padding-bottom: 3px;
          }     
  styles:
        custom_fields:
          graph: [bottom: 0%, left: 0%, width: 128%, position: absolute, margin: 0% 0% -13% -14%]
          card: 
            - padding-bottom: 3px
          state_display: 
            - padding-bottom: 3px
          icon:
            - width: 67%
            - fill: "#9da0a2"
          circle:
            - display: initial
            - width: 90%
            - margin: -6% -5% 0 0
            - justify-self: end
            - opacity: 1
  1. added this to ui-lovelace.yaml
          - type: custom:button-card
            entity: sensor.funktionsstecker_buero_power
            name: Energy
            #tap_action: !include popup/livingroom_temperature.yaml
            hold_action: 
              action: none
            custom_fields:
              graph:
                card:
                  entities:
                    - entity: sensor.funktionsstecker_buero_energy
                card_mod:
                  style: |
                    .states {
                      padding-bottom: 3px;
                    } 
            template:
              - energy
              - icon_energy

but the result is not correct, see the following picture.
grafik

assistance would be great as im lost…
many thanks

Hi everyone! Can you help me work out why the icon on this button shows WHITE instead of BLUE elements?

The entity is sensor.asic_online | State is “online” | I have added online in base.yaml

many thanks

When cards display like that, its usually due to misconfiguration in the YAML. Indentation is important.

In your energy.yaml file, the indentation on the custom_fields: element (and all subsequent elements) under styles: needs to be reduced by 4 characters, e.g.

  styles:
    custom_fields:
      graph: ...

many thanks for the tipp!!

unfortunately, not the right effect… i changed it according to your hints

#################################################
#                                               #
#                  Energy                       #
#                                               #
#################################################

energy:
  template:
    - base
  show_name: false # Hides Card Name
  show_state: true # Hides Card state
  state_display: >
    [[[ return '&nbsp;'; ]]]
  custom_fields:
    circle: >
      [[[ {
      let stromzaehler_online = states['sensor.funktionsstecker_buero_power'],
        stromzaehler_color = stromzaehler_online.state === 'off' ? '#8b0000' : 'none';
      const energy = Math.round(entity.state * 10) / 10;
      return `<svg viewBox="0 0 50 50"><circle cx="25" cy="25" r="20.5" stroke="#313638" stroke-width="1.5" fill="${stromzaehler_color}" style="
      transform: rotate(-90deg); transform-origin: 50% 50%;" />
      <text x="50%" y="54%" fill="#8d8e90" font-size="16" text-anchor="middle" alignment-baseline="middle" dominant-baseline="middle" dominant-baseline="middle">${energy}<tspan font-size="10"> kWh</tspan></text></svg>`; } ]]]
    graph:
      card:
        type: "custom:mini-graph-card"
        height: 140
        hours_to_show: 12
        points_per_hour: 6
        line_width: 8
        font_size: 75
        decimals: 0
        show:
          name: false
          icon: false
          state: true
          legend: false
          labels: false
          labels_secondary: false
          points: false
        color_thresholds:
          - value: 100
            color: "#276696"
          - value: 300
            color: "#228C22"
          - value: 600
            color: "#d35400"
          - value: 1000
            color: "#c0392b"
      card_mod:
        style: |
          .states {
            padding-bottom: 3px;
          }     
  styles:
    custom_fields:
      graph: [bottom: 0%, left: 0%, width: 128%, position: absolute, margin: 0% 0% -13% -14%]
      card: 
        - padding-bottom: 3px
      state_display: 
        - padding-bottom: 3px
      icon:
        - width: 67%
        - fill: "#9da0a2"
      circle:
        - display: initial
        - width: 90%
        - margin: -6% -5% 0 0
        - justify-self: end
        - opacity: 1

but still the same.
grafik

Im going to assume that you added “online” to state_on in base.yaml.
can you share the code for the icon that you are using?

you should not have { in

custom_fields:
    circle: > 

it should be [[[ not [[[ {

it also looks like you might have a font size or padding issue but that could be on my end
Screen Shot 2022-10-24 at 9.47.21 pm

if you still have an issue confirm you installed mini-graph-card and added { url: /hacsfiles/mini-graph-card/mini-graph-card-bundle.js, type: module }, to resources in your configuration.yaml

2 Likes

I have just entered using this dashboard design a it provides big and nicely designed buttons, which should be great for the NSPanel Pro.
The light card is working great, but now I am looking for a cover card, which is not part of the original GitHub, if I am not mistaken. At least I did not find a cover base template nor did I find a cover icon.
I looked through all the forks of his repository thinking it must be a quite common use case and there is no need to start from scratch, but I was not able to find a definition anywhere.
Is there anybody who has done this already? I have seen screenshots im this thread that show cover icons, so I am sure there is something out there. Is anyone willing to share his or hers experience?

hi @T1ppes, are you simple after a cover icon? look back to this post I made about how to add custom icons A different take on designing a Lovelace UI - #3799 by masoncrawford1994

if you would like an animated cover icon, what kind of cover are you looking for, I have 2 examples of a garage door but no window or bind options

@Quinnod34 has a few custom icons that are amazing, look for his post in this thread, he might have something that will work

  icon_garage:
    custom_fields:
      icon: >
        [[[
          if (variables.state === 'on') {
            return `
              <svg viewBox="0 0 50 50">
                <path d="M37.4 15.3V34H34V18.7H6.8V34H3.4V15.3L20.4 8.5 37.4 15.3M32.3 20.4H8.5V23.8H32.3V20.4Z" fill="#9da0a2" />
              </svg>
            `;
          } 
            return `
              <svg viewBox="0 0 50 50">
                <path d="M37.4 15.3V34H34V18.7H6.8V34H3.4V15.3L20.4 8.5 37.4 15.3M32.3 20.4H8.5V23.8H32.3V20.4M32.3 30.6H8.5V34H32.3V30.6M32.3 25.5H8.5V28.9H32.3V25.5Z" fill="#9da0a2" />
              </svg>
            `;
        ]]]

and

icon_garage:
    styles:
      custom_fields:
        icon:
          - width: 100%
          - margin-left: -7%
          - margin-top: -10%
    custom_fields:
      icon: >
        [[[
          let garage;
          if (variables.state === 'on' && variables.timeout < 2000) {
            garage = '#b68349';
          } 
          if (variables.state === 'off' && variables.timeout < 2000) {
            garage = 'gray';
          }
          if (variables.state === 'on' && variables.timeout > 2000) {
            garage = '#b68349';
          }
          if (variables.state === 'off' && variables.timeout > 2000) {
            garage = 'gray';
          }
          let handle;
          if (variables.state === 'on' && variables.timeout < 2000) {
            handle = 'hon';
          } 
          if (variables.state === 'off' && variables.timeout < 2000) {
            handle = 'hoff';
          }
          if (variables.state === 'on' && variables.timeout > 2000) {
            handle = 'hon_timeout';
          }
          let state;
          if (variables.state === 'on' && variables.timeout < 2000) {
            state = 'on';
          } 
          if (variables.state === 'off' && variables.timeout < 2000) {
            state = 'off';
          }
          if (variables.state === 'on' && variables.timeout > 2000) {
            state = 'on_timeout';
          }
          return `
            <svg stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:vectornator="http://vectornator.io" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><clipPath id="TextBounds">
            <path  d="M88.1901 187.348h322.372v269.59H88.1901z"/></clipPath></defs><g id="Layer-1" vectornator:layerName="Layer 1">
            <path clip-path="url(#TextBounds)" d="M134.401 440.057h13.482C152.186 440.057 155.815 438.598 158.773 435.678 161.731 432.759 163.21 429.187 163.21 424.961V396.268L119.075 375.18V424.961C119.075 429.187 120.535 432.759 123.454 435.678 126.373 438.598 130.022 440.057 134.401 440.057zm228.51.0H376.508C380.811 440.057 384.421 438.598 387.341 435.678 390.26 432.759 391.719 429.187 391.719 424.961V375.18L347.7 396.268V424.961C347.7 429.187 349.16 432.759 352.079 435.678 354.998 438.598 358.609 440.057 362.911 440.057zM255.397 408.368C265.077 408.368 275.294 408.252 286.05 408.022 296.805 407.792 307.368 407.484 317.739 407.1 328.11 406.716 337.617 406.255 346.259 405.717 354.902 405.18 361.951 404.603 367.405 403.989 375.241 403.067 381.252 400.493 385.439 396.268 389.626 392.043 391.719 386.204 391.719 378.752V358.471C391.719 352.018 391.258 346.333 390.337 341.417 389.415 336.5 387.878 331.91 385.727 327.646 383.576 323.382 380.734 318.946 377.2 314.336L367.405 301.776C366.022 294.862 364.351 288.025 362.392 281.264 360.433 274.504 358.474 268.435 356.515 263.057 354.556 257.68 352.924 253.57 351.618 250.727 348.545 244.274 344.108 239.127 338.308 235.286 332.508 231.445 325.805 228.986 318.2 227.911 315.588 227.603 311.228 227.334 305.121 227.104 299.013 226.874 291.677 226.682 283.111 226.528 274.545 226.374 265.307 226.297 255.397 226.297 245.487 226.297 236.249 226.374 227.683 226.528 219.118 226.682 211.781 226.874 205.674 227.104 199.566 227.334 195.245 227.603 192.71 227.911 185.027 228.833 178.305 231.252 172.544 235.17 166.782 239.088 162.365 244.274 159.292 250.727 157.909 253.57 156.257 257.68 154.337 263.057 152.416 268.435 150.457 274.504 148.46 281.264 146.462 288.025 144.772 294.862 143.389 301.776L133.71 314.336C130.099 318.946 127.237 323.382 125.125 327.646 123.012 331.91 121.476 336.5 120.515 341.417 119.555 346.333 119.075 352.018 119.075 358.471V378.752C119.075 386.204 121.188 392.043 125.413 396.268 129.638 400.493 135.63 403.067 143.389 403.989 148.844 404.603 155.892 405.18 164.535 405.717 173.177 406.255 182.684 406.716 193.055 407.1 203.426 407.484 213.99 407.792 224.745 408.022 235.5 408.252 245.717 408.368 255.397 408.368zM172.313 377.254C167.012 377.254 162.595 375.487 159.061 371.954 155.527 368.42 153.76 364.002 153.76 358.702 153.76 353.478 155.527 349.099 159.061 345.565 162.595 342.031 167.012 340.264 172.313 340.264 177.614 340.264 182.031 342.031 185.565 345.565 189.099 349.099 190.866 353.478 190.866 358.702 190.866 364.002 189.099 368.42 185.565 371.954 182.031 375.487 177.614 377.254 172.313 377.254zM224.975 372.76C220.981 372.76 217.754 371.512 215.296 369.015 212.837 366.518 211.608 363.311 211.608 359.393 211.608 355.475 212.837 352.268 215.296 349.771 217.754 347.274 220.981 346.026 224.975 346.026H285.934C289.852 346.026 293.04 347.274 295.499 349.771 297.957 352.268 299.186 355.475 299.186 359.393 299.186 363.311 297.957 366.518 295.499 369.015 293.04 371.512 289.852 372.76 285.934 372.76H224.975zM338.481 377.254C333.257 377.254 328.878 375.487 325.344 371.954 321.811 368.42 320.044 364.002 320.044 358.702 320.044 353.478 321.811 349.099 325.344 345.565 328.878 342.031 333.257 340.264 338.481 340.264 343.782 340.264 348.199 342.031 351.733 345.565 355.267 349.099 357.034 353.478 357.034 358.702 357.034 364.002 355.267 368.42 351.733 371.954 348.199 375.487 343.782 377.254 338.481 377.254zM166.667 292.211C167.512 287.986 168.664 283.53 170.124 278.844 171.583 274.158 173.081 269.798 174.618 265.765 176.154 261.732 177.537 258.601 178.766 256.374 180.303 253.685 182.031 251.687 183.952 250.381 185.872 249.075 188.369 248.23 191.442 247.846 195.821 247.232 203.119 246.751 213.337 246.406 223.554 246.06 237.574 245.887 255.397 245.887 273.22 245.887 287.259 246.041 297.515 246.348 307.771 246.655 315.05 247.155 319.352 247.846 322.502 248.307 324.999 249.171 326.842 250.439 328.686 251.707 330.415 253.685 332.028 256.374 333.334 258.601 334.736 261.732 336.234 265.765 337.732 269.798 339.192 274.158 340.613 278.844 342.034 283.53 343.244 287.986 344.243 292.211 344.781 294.362 344.608 295.861 343.724 296.706 342.841 297.551 341.285 297.896 339.057 297.743 332.681 297.359 325.671 296.974 318.027 296.59 310.383 296.206 301.51 295.899 291.408 295.668 281.306 295.438 269.302 295.323 255.397 295.323 241.492 295.323 229.489 295.438 219.386 295.668 209.284 295.899 200.43 296.206 192.825 296.59 185.219 296.974 178.229 297.359 171.852 297.743 169.624 297.896 168.069 297.551 167.185 296.706 166.302 295.861 166.129 294.362 166.667 292.211z" fill="#2c2c2c" fill-rule="evenodd" opacity="1" stroke="none"/><g opacity="1">
            <path class="${state}" d="M79.4908 151.521H435.399V419.425H79.4908V151.521z" fill="#fff" fill-rule="evenodd" opacity="1" stroke="none"/>
            <path d="M77.9652 164.82H433.004v92.404H77.9652V164.82z" fill="${garage}" fill-rule="evenodd" opacity="1" stroke="none"/>
            <path class="${state}"d="M81.04 263.026H430.772V352.135H81.04V263.026z" fill="#858585" fill-rule="evenodd" opacity="1" stroke="none"/>
            <path class="${state}"d="M78.2453 357.809H433.85V443.086H78.2453V357.809z" fill="#828282" fill-rule="evenodd" opacity="1" stroke="none"/>
            <path class="${handle}" d="M239.68 314.889 275.762 314.469" fill="#ffffff" fill-rule="evenodd" opacity="1" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="7.8284"/>
            <path class="${handle}" d="M248.241 314.869C248.241 310.103 252.662 306.239 258.117 306.239 263.571 306.239 267.992 310.103 267.992 314.869 267.992 319.636 263.571 323.5 258.117 323.5 252.662 323.5 248.241 319.636 248.241 314.869z" fill="#ffffff" fill-rule="evenodd" opacity="1" stroke="none"/></g>
            <path d="M256.439 68.023 400.495 137.373 427.219 150.238 81.2766 151.521 256.439 68.023z" fill="#5f5f5f" fill-rule="evenodd" opacity="1" stroke="#757575" stroke-linecap="butt" stroke-linejoin="round" stroke-width="12.466"/>
            <path  d="M75.8011 444.381V153.619L256 67.619l180.199 86V444.381" fill="none" fill-rule="evenodd" opacity="1" stroke="#6b6b6b" stroke-linecap="butt" stroke-linejoin="round" stroke-width="12.466"/></g>
            <style>
                @keyframes off {
                  0% {
                    transform: translateY(-60%);
                    opacity: 0;
                    animation-timing-function: cubic-bezier(0.7, 0, 0.84, 0);
                  }
                  
                  
                  50% {
                    transform: translateY(-30%);
                    animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
                  }
                  
                  100% {
                    transform: translateY(0%);
                  }
                }
                @keyframes on_timeout {
                  0% {
                    transform: translateY(0%);
                    
                  }
                  
                  70% {
                    transform: translateY(-40%);
                  
                  }
                  80% {
                    opacity: 0;
                  }
                  100% {
                    transform: translateY(-60%);
                    opacity: 0;
                  }
                }
                @keyframes on {
                  0% {
                    transform: translateY(0%);
                    
                  }
                  
                  70% {
                    transform: translateY(-40%);
                  
                  }
                  80% {
                    opacity: 0;
                  }
                  100% {
                    transform: translateY(-60%);
                    opacity: 0;
                  }
                }
                .on {
                  animation: on 0.7s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.1s;
                }
                .off {
                  animation: off 0.7s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.4s;
                }
                .on_timeout {
                  animation: on_timeout 0.7s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.1s;
                }
                @keyframes hoff {
                  0% {
                    transform: translateY(-21%);
                    
                  }
                  
                  
                  100% {
                    transform: translateY(0%);
                  }
                }
                @keyframes hon {
                  0% {
                    transform: translateY(0%);
                    
                  }
                  
                  
                  
                  100% {
                    transform: translateY(-21%);
                    
                  }
                }
                .hon {
                  animation: hon 0.1s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.1s;
                }
                .hoff {
                  animation: hoff 0.7s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.4s;
                }
                .hon_timeout {
                  animation: hon 0.1s;
                  transform-origin: 40% 20%;
                  animation-fill-mode: forwards;
                  animation-delay: -0.1s;
                }
              </style>
            </svg>
          `;
        ]]]

About to start jumping into this project. I read through the github and am prepared (as much as I can be). Is there any best practices during set-up at this time? Thanks for the INSTALL.md for step by step.

New to github so bear with me, but seeing that this project is constantly getting updated, is there a way I could have HA simply read Git and if any updates are posted to the main repository, the same changes will be made on my system? Would be a pain to constantly be making small changes for the latest features. Wanted to ask that before I jump in and begin manually copying everything.

Any other tips or notices on Install is also appreciated. Thanks!

I agree, but I’m just sharing my config, like a springboard for you to create your own dashboard. I try to keep button-card-templates so you can just copy that whole directory on changes. Also anyone is welcome to edit INSTALL.md to flesh it out more

1 Like

That makes sense. Very daunting task ahead from a newbie like me. Love all the effort you’ve already done!

I’m sure i’m not the only one here, but being a visual learner, a long screen-share walkthrough of a fresh install or simply pointing out common problems you see on this thread / important things to note / how the documents work would help significantly for the future and especially newbies like me who want to do this but have trouble figuring out where they messed up throughout the process.

Im also a visual learner, so don’t let that stop you from trying.

The best skill I would recommend would be how to ask for help / how to provide all the details need so people can help.

provide screenshots, error messages (as text is better than an image) and the code itself for the best help. get the error messages from the browser console, or home assistant logs

1/4 times I find what my issues was myself, after I have given up trying to fix it and start writing a post asking for help.