Animated Mushroom card for washing machine -> problems

Hello dear community,

I have been working with Home Assistant for a good two years now. My primary focus has been on automation. Since many of them work to my satisfaction, I would like to develop a nice dashboard for them. But this is where my gaps in knowledge of YAML and Jinja2 become apparent :slightly_smiling_face:. On my dashboard, I mainly use the Mushroom Theme and Mushroom Cards. Here is an example of my card for a person, zone, smartphone battery level and information on whether the smartphone is charging or not.

Mushroom Card

In the same style, I selected animation 42 from Anashost on GitHub and attempted to adapt it. I made some progress with the assistance of Gemini and ChatGPT, but I am not entirely satisfied yet. Perhaps you could assist me?

What do I have?

  • An automation that works
  • A helper that switches when the machine is running or finished
  • A power sensor for the washing machine socket
  • A helper that calculates the running time
  • An animation that basically works, but is not ‘perfect’ and in 2 cards
  • Template from Anashost and inspiration from member @LiQuid_cOOled and his post
  • YAML code, see attachment

What is my target?

  • An animated card where I can see whether
    → whether the machine is running (animated) including a badge (icon), the text ‘running’ and the current consumption in watts
    → is standing but still on (pulsing green? or icon in green) including badge (icon), the text ‘finished’ and the running time
    → is off, without animation and grey, including badge (icon), the text ‘off’
  • all in ONE card

Conditions that are implemented:

  • Machine running = helper input.boolean is on and power sensor is above 20 watts
  • Machine finished = helper input.boolean is off BUT power sensor is above 5 watts
  • Machine off = helper input.boolean is off and power sensor is 0 watts

I can’t get the three states to appear in the animated icon and I can’t get it to work on ONE map. Unfortunately, I’m stuck here and hope you can help me.

I know:
‘Much to learn you still have.’ and ‘Patience you must have, my young Padawan.’

Perhaps someone can point me in the right direction or also another ideas. :wink::+1:

YAML Person Card

type: custom:mushroom-template-card
secondary: |-
  {% set bl = states('sensor.poco_x7_pro_ronny_battery_level') | int %}
  {% set bs = states('sensor.poco_x7_pro_ronny_battery_state') %}

  {% if bl < 15 %}
    đŸȘ« {{ bl }} %
  {% elif bs == 'charging' %}
    ⚡ {{ bl }} %
  {% else %}
    🔋 {{ bl }} %
  {% endif %}
icon: mdi:account
features_position: bottom
entity: person.ronny
primary: |-
  {% set loc = states('person.ronny') %}
  {% set map = {
    "home": "Zuhause",
    "not_home": "Unterwegs",
    "Schule": "Schule",
    "Uni Freiberg PrĂŒferstraße": "Uni",
    "Uni Freiberg Gustav-Zeuner-Straße": "Uni",
    "Uni Freiberg Winklerstraße": "Uni",
    "Constantins Wohnung": "Wohnung"
  } %}
  {{ map.get(loc, loc) }}
picture: "{{ state_attr('person.ronny', 'entity_picture') }}"
badge_icon: |-
  {% set location = states(entity) %}
  {% if location == 'not_home' %}
    mdi:home-export-outline
  {% elif location == 'home' %}
    {{ state_attr('zone.home', 'icon') or 'mdi:home' }}
  {% else %}
    {{ states.zone | selectattr('name', 'eq', location) 
       | map(attribute='attributes.icon') | first | default('mdi:map-marker') }}
  {% endif %}
badge_color: |-
  {% if is_state(entity, "home") %}
    green
  {% elif is_state(entity, "not_home") %}
    red
  {% else %}
    light-blue
  {% endif %}
color: |2-
   {% if is_state(entity, ["home"]) -%}
      var(--rgb-accent-color)
      {%- endif %}
multiline_secondary: false
grid_options:
  columns: 5
  rows: auto
card_mod:
  style: |
    ha-card {
      background: transparent;
      border-color: transparent;
      border-radius: 18px;
      color: #ffffff;
    }

current animation washing-machine

type: custom:mushroom-entity-card
entity: input_boolean.waschmaschine_lauft
tap_action:
  action: toggle
icon: mdi:washing-machine
icon_color: blue
name: Waschmaschine
primary_info: none
secondary_info: none
card_mod:
  style:
    mushroom-shape-icon$: >
      {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
      float(0) %}

      {% set running = is_state('input_boolean.waschmaschine_lauft', 'on') %}

      {% set active = running and power > 0 %}

      {% set ready = (not running) and power > 0 %}


      .shape {

        {% if active %}
          --icon-color: rgb(var(--rgb-blue));
          --wash-glow: ultra-wash-glow 1.8s ease-in-out infinite;
          --wash-drum: spin-laundry 0.6s linear infinite;
          animation: ultra-wash-thump 1.8s ease-in-out infinite;
          opacity: 1;
        {% elif ready %}
          --icon-color: rgb(var(--rgb-green));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 1;
        {% else %}
          --icon-color: rgb(var(--rgb-disabled));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 0.6;
        {% endif %}

        isolation: isolate;
        position: relative;
      }


      .shape::after {
        content: "";
        position: absolute;
        top: 58%;
        left: 50%;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background: conic-gradient(
          transparent,
          var(--icon-color),
          transparent
        );
        transform: translate(-50%, -50%);
        animation: var(--wash-drum);

        {% if not active %}
          display: none;
        {% endif %}
      }


      .shape::before {
        content: "";
        position: absolute;
        inset: -4px;
        border-radius: 50%;
        animation: var(--wash-glow);
      }


      @keyframes spin-laundry {
        0%   { transform: translate(-50%, -50%) rotate(0deg); }
        100% { transform: translate(-50%, -50%) rotate(360deg); }
      }


      @keyframes ultra-wash-glow {
        0% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
        50% {
          box-shadow:
            0 0 18px 6px rgba(var(--rgb-blue), 0.9),
            0 0 32px 12px rgba(var(--rgb-blue), 0.4);
        }
        100% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
      }
    .: |
      ha-card {
        background: transparent;
        border-color: transparent;
        border-radius: 18px;
        color: #ffffff;
      }

2nd card washing machine

type: custom:mushroom-template-card
entity: sensor.steckdose_waschmaschine_energy_power
primary: |
  {% set power = states(entity) | float(0) %} {% if power == 0 %}
    aus
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
    lÀuft
  {% else %}
    fertig/bereit
  {% endif %}
secondary: |-
  {% set power = states(entity) | float(0) %}
  {% if power == 0 %}
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
  {{ power | round(0) }} W
  {% else %}
  {{ states('input_number.dauer_letzter_waschgang') | int }} min
  {% endif %}
icon: mdi:power-plug
badge_icon: |
  {% set power = states(entity) | float(0) %} {% if power == 0 %}
    mdi:power-off
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
    mdi:progress-clock
  {% else %}
    mdi:check-circle
  {% endif %}
badge_color: |
  {% set power = states(entity) | float(0) %} {% if power == 0 %}
    grey
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
    blue
  {% else %}
    green
  {% endif %}
features_position: bottom
multiline_secondary: false
card_mod:
  style: |
    ha-card {
      background: transparent;
      border-color: transparent;
      border-radius: 18px;
      color: #ffffff;
    }
visibility:
  - condition: screen
    media_query: "(min-width: 768px)"
grid_options:
  columns: 5
  rows: 1

Little legend for translation:

Schule = School
steckdose_waschmaschine = plug washing machine
waschmaschine_lauft = washmachine is running
dauer_letzter Waschgang = duration of last wash cycle

Thank you all in advance for trying to help me.

Ronny

I’ll have to look at all your code closer when I have time. For now, here is a quick stab at updating the code for the washing machine animation.

type: custom:mushroom-template-card
entity: input_boolean.test
icon: mdi:washing-machine
color: orange
features_position: bottom
card_mod:
  style:
    ha-tile-icon$: |
      .container:after {
       content: '';
       position: absolute;
       width: 28%;
       height: 27%;
       border-radius: 100%;
       border: 1px solid white;
       background:black;
       top: 14.2px;
        }
      .container:before {
       content: '';
        z-index: 1; 
       position: absolute;
       width: 26.1% !important; 
       height: 26% !important;        
       opacity: 100%  !important;   
       top: 43.1% !important;        
       left: 36.7% !important;      
       background: deepskyblue !important;      
       animation:spin 2s linear infinite;
       clip-path: inset(0 0 50% 0 round 50% 50% 0 0); 
           }
       @keyframes spin {
       0% {transform: rotate(0deg);}
       100% {transform:rotate(360deg);}
        }

example

3 Likes

Hello @LiQuid_cOOled .

Many thanks in advance. I will try it at weekend :wink:.

Have a nice week and please stay healthy.

Ronny

Frist attempt:

type: custom:mushroom-template-card
entity: input_boolean.geschirrspueler_laeuft
icon: mdi:dishwasher
color: orange
features_position: bottom
primary: >-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
     aus
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
     lÀuft
  {% else %}
     fertig/bereit
  {% endif %}
secondary: >-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %} {% elif is_state('input_boolean.geschirrspueler_laeuft',
  'on') %} {{ power | round(0) }} W {% else %} {{
  states('input_number.dauer_letzte_geschirrreinigung') | int }}min {% endif %}
badge_icon: |-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
    mdi:power-off
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
    mdi:progress-clock
  {% else %}
    mdi:check-circle
  {% endif %}
badge_color: |
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
    grey
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
    blue
  {% else %}
    green
  {% endif %}
card_mod:
  style:
    ha-tile-icon$: |
      .container:after {
       content: '';
       position: absolute;
       width: 28%;
       height: 27%;
       border-radius: 100%;
       border: 1px solid white;
       background:black;
       top: 14.2px;
        }
      .container:before {
       content: '';
        z-index: 1; 
       position: absolute;
       width: 26.1% !important; 
       height: 26% !important;        
       opacity: 100%  !important;   
       top: 43.1% !important;        
       left: 36.7% !important;      
       background: deepskyblue !important;      
       animation:spin 2s linear infinite;
       clip-path: inset(0 0 50% 0 round 50% 50% 0 0); 
           }
       @keyframes spin {
       0% {transform: rotate(0deg);}
       100% {transform:rotate(360deg);}
       }

I struggling a little bit with the transparent background of the card. Your code is “only” for washing machines, isn’t it? Nevertheless you did a great job. I will try to implement the code in my card. If you have some hint, please let me know .:wink:

Thanks a lot and have a nice weekend.

Ronny

P.S. The animation doesn’t stops. Did I something wrong?

Unfortunately, I’m just not getting anywhere. The animation in entity card works, in the template card doesn’t. I have no idea why not. Has anybody a hint? :wink:

works >

type: custom:mushroom-entity-card
entity: input_boolean.waschmaschine_lauft
tap_action:
  action: toggle
icon: mdi:washing-machine
icon_color: blue
name: Waschmaschine
primary_info: none
secondary_info: none
card_mod:
  style:
    mushroom-shape-icon$: >
      {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
      float(0) %}

      {% set running = is_state('input_boolean.waschmaschine_lauft', 'on') %}

      {% set active = running and power > 0 %}

      {% set ready = (not running) and power > 0 %}


      .shape {

        {% if active %}
          --icon-color: rgb(var(--rgb-blue));
          --wash-glow: ultra-wash-glow 1.8s ease-in-out infinite;
          --wash-drum: spin-laundry 0.6s linear infinite;
          animation: ultra-wash-thump 1.8s ease-in-out infinite;
          opacity: 1;
        {% elif ready %}
          --icon-color: rgb(var(--rgb-green));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 1;
        {% else %}
          --icon-color: rgb(var(--rgb-disabled));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 0.6;
        {% endif %}

        isolation: isolate;
        position: relative;
      }


      .shape::after {
        content: "";
        position: absolute;
        top: 58%;
        left: 50%;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background: conic-gradient(
          transparent,
          var(--icon-color),
          transparent
        );
        transform: translate(-50%, -50%);
        animation: var(--wash-drum);

        {% if not active %}
          display: none;
        {% endif %}
      }


      .shape::before {
        content: "";
        position: absolute;
        inset: -4px;
        border-radius: 50%;
        animation: var(--wash-glow);
      }


      @keyframes spin-laundry {
        0%   { transform: translate(-50%, -50%) rotate(0deg); }
        100% { transform: translate(-50%, -50%) rotate(360deg); }
      }


      @keyframes ultra-wash-glow {
        0% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
        50% {
          box-shadow:
            0 0 18px 6px rgba(var(--rgb-blue), 0.9),
            0 0 32px 12px rgba(var(--rgb-blue), 0.4);
        }
        100% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
      }
    .: |
      ha-card {
        background: transparent;
        border-color: transparent;
        border-radius: 18px;
        color: #ffffff;
      }

works not

type: custom:mushroom-template-card
entity: input_boolean.waschmaschine_lauft
icon: mdi:washing-machine
features_position: bottom
primary: >-
  {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
  float(0) %} {% if power == 0 %}
     aus
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
     lÀuft
  {% else %}
     fertig/bereit
  {% endif %}
secondary: >-
  {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
  float(0) %} {% if power == 0 %} {% elif
  is_state('input_boolean.waschmaschine_lauft', 'on') %} {{ power | round(0) }}
  W {% else %} {{ states('input_number.dauer_letzter_waschgang') | int }}min {%
  endif %}
badge_icon: >-
  {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
  float(0) %} {% if power == 0 %}
    mdi:power-off
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
    mdi:progress-clock
  {% else %}
    mdi:check-circle
  {% endif %}
badge_color: >
  {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
  float(0) %} {% if power == 0 %}
    grey
  {% elif is_state('input_boolean.waschmaschine_lauft', 'on') %}
    blue
  {% else %}
    green
  {% endif %}
multiline_secondary: false
visibility:
  - condition: screen
    media_query: "(min-width: 0px)"
grid_options:
  columns: 5
  rows: 1
card_mod:
  style:
    mushroom-shape-icon$: |
      {% set power = states('sensor.steckdose_waschmaschine_energy_power') |
      float(0) %}

      {% set running = is_state('input_boolean.waschmaschine_lauft', 'on') %}

      {% set active = running and power > 0 %}

      {% set ready = (not running) and power > 0 %}


      .shape {

        {% if active %}
          --icon-color: rgb(var(--rgb-blue));
          --wash-glow: ultra-wash-glow 1.8s ease-in-out infinite;
          --wash-drum: spin-laundry 0.6s linear infinite;
          animation: ultra-wash-thump 1.8s ease-in-out infinite;
          opacity: 1;
        {% elif ready %}
          --icon-color: rgb(var(--rgb-green));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 1;
        {% else %}
          --icon-color: rgb(var(--rgb-disabled));
          --wash-glow: none;
          --wash-drum: none;
          animation: none;
          opacity: 0.6;
        {% endif %}

        isolation: isolate;
        position: relative;
      }


      .shape::after {
        content: "";
        position: absolute;
        top: 58%;
        left: 50%;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background: conic-gradient(
          transparent,
          var(--icon-color),
          transparent
        );
        transform: translate(-50%, -50%);
        animation: var(--wash-drum);

        {% if not active %}
          display: none;
        {% endif %}
      }


      .shape::before {
        content: "";
        position: absolute;
        inset: -4px;
        border-radius: 50%;
        animation: var(--wash-glow);
      }


      @keyframes spin-laundry {
        0%   { transform: translate(-50%, -50%) rotate(0deg); }
        100% { transform: translate(-50%, -50%) rotate(360deg); }
      }


      @keyframes ultra-wash-glow {
        0% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
        50% {
          box-shadow:
            0 0 18px 6px rgba(var(--rgb-blue), 0.9),
            0 0 32px 12px rgba(var(--rgb-blue), 0.4);
        }
        100% {
          box-shadow:
            0 0 10px 3px rgba(var(--rgb-blue), 0.6),
            0 0 20px 8px rgba(var(--rgb-blue), 0.3);
        }
      }
    .: |
      ha-card {
        background: transparent;
        border-color: transparent;
        border-radius: 18px;
        color: #ffffff;
      }

Hello community members.

I have now made same progress :wink:.

type: custom:mushroom-template-card
entity: input_boolean.geschirrspueler_laeuft
icon: mdi:dishwasher
features_position: bottom
primary: >-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
     aus
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
     lÀuft
  {% else %}
     bereit
  {% endif %}
secondary: >-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %} {% elif is_state('input_boolean.geschirrspueler_laeuft',
  'on') %} {{ power | round(0) }} W {% else %} {{
  states('sensor.steckdose_geschirrspuler_power') | int }}min {% endif %}
badge_icon: >-
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
    mdi:power-off
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
    mdi:progress-clock
  {% else %}
    mdi:check-circle
  {% endif %}
badge_color: >
  {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
  {% if power == 0 %}
    grey
  {% elif is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
    blue
  {% else %}
    green
  {% endif %}
multiline_secondary: false
visibility:
  - condition: screen
    media_query: "(min-width: 0px)"
grid_options:
  columns: 5
  rows: 1
card_mod:
  style: |
    ha-state-icon {
      {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
      {% set running = is_state('input_boolean.geschirrspueler_laeuft', 'on') %}
      
      {% if running and power > 0 %}
        /* WEISS: LĂ€uft */
        filter: brightness(0) invert(1) !important;
        animation: ultra-wash-thump 1.8s ease-in-out infinite, ultra-wash-glow-white 1.8s ease-in-out infinite;
        /* Schwarzer Ring */
        border: 4px solid black !important;
        border-radius: 50%;
        padding: 1px;
      {% elif (not running) and power > 0 %}
        /* GRÜN: Fertig / Bereit */
        filter: invert(48%) sepia(79%) saturate(2476%) hue-rotate(86deg) brightness(118%) contrast(119%) !important;
        animation: ultra-wash-glow-green 2s ease-in-out infinite;
        border: 3px solid black !important;
        border-radius: 50%;
        padding: 1px;
        background: transparent !important;
      {% else %}
        /* GRAU: Aus */
        filter: none !important;
        animation: none !important;
        background: none !important;
      {% endif %}
      position: relative;
    }

    ha-state-icon::after {
      {% set power = states('sensor.steckdose_geschirrspuler_power') | float(0) %}
      {% if is_state('input_boolean.geschirrspueler_laeuft', 'on') and power > 0 %}
        content: "";
        position: absolute;
        top: 50%;
        left: 50%;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        /* Weißer Schimmer fĂŒr die Trommel */
        background: conic-gradient(transparent 0deg, rgba(255, 255, 255, 0.8) 180deg, transparent 360deg);
        animation: spin-laundry 1.0s linear infinite;
        display: block;
        opacity: 1.2;
        /* Neutralisiert eventuelle Farbverschiebungen durch den Filter */
        filter: none !important; 
      {% else %}
        display: none;
      {% endif %}
    }


    @keyframes spin-laundry {
      0%   { transform: translate(-50%, -50%) rotate(0deg); }
      100% { transform: translate(-50%, -50%) rotate(360deg); }
    }

    /* THE REQUESTED ULTRA GLOW (Double Shadow Layer) */
    @keyframes ultra-wash-glow {
      0% {
        box-shadow:
          0 0 10px 3px rgba(var(--rgb-white), 0.6),
          0 0 20px 8px rgba(var(--rgb-white), 0.3);
      }
      50% {
        box-shadow:
          0 0 18px 6px rgba(var(--rgb-white), 0.9),
          0 0 32px 12px rgba(var(--rgb-white), 0.4);
      }
      100% {
        box-shadow:
          0 0 10px 3px rgba(var(--rgb-white), 0.6),
          0 0 20px 8px rgba(var(--rgb-white), 0.3);
        }
      }

    @keyframes ultra-wash-thump {
      0%   { transform: scale(0.85); }
      50%  { transform: scale(0.9); } 
      100% { transform: scale(0.85); }
    }

    ha-card {
      background: transparent;
      border: none;
    }

It look good for me. Nevertheless I have a further question. Is it possible to change the grey circle of icon to transperant or another color in my code? At the moment the circle is filled grey. Is that a requirement from Mushroom Card?

Thanks for help and have a nice weekend and please stay healthy.

Update: I can answer by myself. > change Tap action on icon to none > no grey circle is shown anymore.