Ich werde einfach nicht fertig πŸ™„

Muss ich mal paar Stunden finden und es mir anschauen..
Aber danke fΓΌr die Info

1 β€žGefΓ€llt mirβ€œ

@Technikperry

Was ist das fΓΌr ein Theme?

das sieht wirklich super aus

1 β€žGefΓ€llt mirβ€œ

Hi, das ist kein Theme.
Sind alles Custom Button-Cards.

1 β€žGefΓ€llt mirβ€œ

Ohhh Das klinkt nach richtig viel Arbeit

Gibt es eine MΓΆglichkeit dein Dashboard zu teilen?

1 β€žGefΓ€llt mirβ€œ

Er bietet einzelne Bereiche an aber alles Sprengt den Rahmen :wink:

1 β€žGefΓ€llt mirβ€œ

OK

Das habe ich glaube ΓΌberlesen

mich wΓΌrde speziel der Fahrzeugstatus und Waschmaschine interessieren

Okay, ich geb dir mal die Waschmaschine.
Probiere es aus.

type: custom:button-card
entity: sensor.washer_program_de
triggers_update:
  - sensor.time
  - sensor.waschmaschine_programm_endzeit
  - sensor.waschmaschine_betriebszustand
show_name: false
show_icon: false
show_state: false
variables:
  v_program: sensor.washer_program_de
  v_mode: sensor.waschmaschine_betriebszustand
  v_endtime: sensor.waschmaschine_programm_endzeit
  v_status: sensor.waschmaschine_status_de
  v_connected: binary_sensor.waschmaschine_konnektivitat
  v_idos1: sensor.waschmaschine_niedriger_fullstand_von_i_dos_1
  v_idos2: sensor.waschmaschine_niedriger_fullstand_von_i_dos_2
  v_power: sensor.hwr_waschmaschine_leistung
  v_energy: sensor.hwr_waschmaschine_energiezahler_gesamt
  v_start: input_datetime.waschmaschine_startzeit
  v_bild: /local/pictures/Waschmaschine.png
  v_name: Waschmaschine
  v_energy_offset: 134.391
  v_bar_gradient: linear-gradient(90deg,#8A0E1C,#E8394A,#FF6B78)
styles:
  card:
    - width: 443px
    - height: 377px
    - border-radius: 16px
    - padding: 20px
    - overflow: hidden
    - margin-top: "-11px"
    - margin-left: "-10.5px"
    - border: 1px solid rgba(67,152,195,0.25)
    - background: "linear-gradient(145deg, #1c3a50 0%, #0e2333 40%, #0a1c2b 100%)"
    - box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(67,152,195,0.12)
  grid:
    - grid-template-areas: "\"topbar\" \"main\""
    - grid-template-columns: 1fr
    - grid-template-rows: 0px 1fr
    - z-index: "2"
  custom_fields:
    topbar:
      - position: absolute
      - top: "0"
      - left: "0"
      - right: "0"
      - bottom: "0"
      - pointer-events: none
      - z-index: "1"
    main:
      - z-index: "2"
      - width: 100%
      - height: 100%
custom_fields:
  topbar: |
    [[[
      const mode   = states[variables.v_mode]?.state ?? '';
      const active = mode === 'run';
      return `
        <div style="position:absolute;top:0;left:0;right:0;height:3px;
          background:linear-gradient(90deg,transparent,#4398C3,#7EC8E3,#4398C3,transparent);
          opacity:${active ? '1' : '0.5'};z-index:3;pointer-events:none;"></div>
        <div style="position:absolute;top:-20px;right:-20px;
          width:180px;height:180px;border-radius:50%;
          background:radial-gradient(circle,rgba(67,152,195,0.18) 0%,transparent 70%);
          pointer-events:none;z-index:1;
          opacity:${active ? '1' : '0'};transition:opacity 0.4s ease;"></div>`;
    ]]]
  main: |
    [[[
      // ════════════════════════════════════════════════
      // DATEN LADEN
      // ════════════════════════════════════════════════
      const get     = (id, fb='β€”') => states[id]?.state ?? fb;
      const inv     = ['','unknown','unavailable','none','null'];
      const norm    = v => String(v ?? '').toLowerCase().trim();
      const mode    = get(variables.v_mode,'');
      const conn    = get(variables.v_connected,'off') === 'on';
      const active  = mode === 'run' && conn;
      const prog    = get(variables.v_program,'');
      const progName = inv.includes(norm(prog)) ? 'Programm AUS' : prog;
      const status  = conn ? get(variables.v_status,'STANDBY') : 'STANDBY';
      const endStr  = get(variables.v_endtime,'');
      const startStr = get(variables.v_start,'');
      const power   = parseFloat(get(variables.v_power,'0') || 0).toFixed(1);
      const energy  = (parseFloat(get(variables.v_energy,'0') || 0) - variables.v_energy_offset).toFixed(2);

      // ════════════════════════════════════════════════
      // FORTSCHRITT BERECHNEN
      // ════════════════════════════════════════════════
      let pct = 0;
      if (active && !inv.includes(norm(endStr)) && !inv.includes(norm(startStr))) {
        const start = new Date(startStr).getTime();
        const end   = new Date(endStr).getTime();
        const total = end - start;
        pct = total <= 0 ? 0
          : Math.min(100, Math.max(0, Math.round(((Date.now()-start)/total)*100)));
      }

      // ════════════════════════════════════════════════
      // RESTZEIT BERECHNEN
      // ════════════════════════════════════════════════
      let timeStr = '--:--';
      if (active && !inv.includes(norm(endStr))) {
        const end = new Date(endStr);
        if (!isNaN(end.getTime())) {
          const diff = Math.max(0, Math.floor((end.getTime() - Date.now()) / 1000));
          const hh   = Math.floor(diff / 3600);
          const mm   = Math.floor((diff % 3600) / 60);
          timeStr = `${String(hh).padStart(2,'0')}:${String(mm).padStart(2,'0')}`;
        }
      }

      // ════════════════════════════════════════════════
      // IDOS-STATUS β€” Farben fΓΌr OK / NIEDRIG / unbekannt
      // ════════════════════════════════════════════════
      const mapIDOS = s =>
        s === 'on'  ? { t:'NIEDRIG', c:'rgba(195,67,85,1)',
                        bg:'rgba(195,67,85,0.1)', bd:'rgba(195,67,85,0.25)' }
      : s === 'off' ? { t:'OK',      c:'rgba(67,195,122,1)',
                        bg:'rgba(67,195,122,0.1)', bd:'rgba(67,195,122,0.25)' }
      :               { t:'β€”',       c:'rgba(67,152,195,1)',
                        bg:'rgba(67,152,195,0.05)', bd:'rgba(67,152,195,0.12)' };
      const i1 = mapIDOS(get(variables.v_idos1,'unknown'));
      const i2 = mapIDOS(get(variables.v_idos2,'unknown'));

      // ════════════════════════════════════════════════
      // BAUSTEINE 
      // ════════════════════════════════════════════════

      const pill = (dot, bg, bd, tx, lbl, glow) => `
        <div style="display:inline-flex;align-items:center;gap:6px;
          background:${bg};border:1px solid ${bd};
          border-radius:20px;padding:3px 10px 3px 7px;">
          <div style="width:8px;height:8px;border-radius:50%;
            background:${dot};box-shadow:${glow};flex-shrink:0;"></div>
          <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
            letter-spacing:0.5px;color:${tx};">${lbl}</span>
        </div>`;

      const statusPill = active
        ? pill('#43C37A','rgba(67,195,122,0.1)','rgba(67,195,122,0.22)',
               'rgba(67,195,122,1)','LΓ„UFT','0 0 7px rgba(67,195,122,0.7)')
        : pill('rgba(67,152,195,1)','rgba(67,152,195,0.05)','rgba(67,152,195,0.12)',
               'rgba(67,152,195,1)','STANDBY','none');

      const idosPill = d => `
        <div style="display:inline-flex;align-items:center;gap:5px;
          background:${d.bg};border:1px solid ${d.bd};
          border-radius:20px;padding:3px 8px 3px 6px;">
          <div style="width:8px;height:8px;border-radius:50%;
            background:${d.c};flex-shrink:0;"></div>
          <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
            letter-spacing:0.5px;color:${d.c};">${d.t}</span>
        </div>`;

      const statTile = (icon, val, unit, label, accent) => `
        <div style="flex:1;display:flex;flex-direction:column;align-items:center;
          justify-content:center;background:rgba(67,152,195,0.05);
          border:1px solid rgba(67,152,195,0.12);border-radius:8px;
          padding:10px 6px;gap:5px;text-align:center;">
          <div style="display:flex;align-items:center;gap:4px;">
            <ha-icon icon="${icon}" style="--mdc-icon-size:20px;color:${accent};
              filter:drop-shadow(0 0 4px ${accent}88);"></ha-icon>
            <span style="font-family:'EXO 2';font-size:10px;font-weight:500;
              letter-spacing:0.5px;text-transform:uppercase;
              color:rgba(67,152,195,1);">${label}</span>
          </div>
          <div style="display:flex;align-items:baseline;justify-content:center;gap:2px;">
            <span style="font-family:'EXO 2';font-size:22px;font-weight:500;
              color:#E8F4FC;line-height:1;">${val}</span>
            <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
              color:rgba(126,200,227,1);margin-left:2px;">${unit}</span>
          </div>
        </div>`;

      const barBg   = active ? variables.v_bar_gradient : 'rgba(67,152,195,0.12)';
      const barGlow = active ? '0 0 8px rgba(232,57,74,0.5)' : 'none';
      const pctCol  = active ? '#FF6B78' : 'rgba(67,152,195,1)';

      // ════════════════════════════════════════════════
      // AUSGABE β€” Reihenfolge der BlΓΆcke hier bestimmt
      // was oben/unten auf der Karte steht
      // ════════════════════════════════════════════════
      return `
        <div style="width:100%;height:100%;position:relative;">

          <!-- BLOCK 1: HEADER (Titel + Status-Pill) -->
          <div style="position:absolute;top:0px;left:0;right:0;">
            <div style="display:flex;align-items:center;justify-content:space-between;">

              <!-- Links: Titel -->
              <div style="display:flex;align-items:center;">
                <span style="font-family:'EXO 2';font-size:16px;font-weight:500;
                  letter-spacing:0.5px;text-transform:uppercase;
                  color:rgba(126,200,227,1);">
                  ${variables.v_name}
                </span>
              </div>

              <!-- Rechts: Status-Pill -->
              ${statusPill}

            </div>
          </div>

          <!-- BLOCK 2: BILD + PROGRAMM + RESTZEIT -->
          <!-- Bildgrâße: width Àndern (aktuell 100px) -->
          <div style="position:absolute;top:10px;left:0;right:0;">
          <div style="display:flex;align-items:center;margin-bottom:10px;position:absolute;top:30px;left:0;right:0;">
            <img src="${variables.v_bild}"
              style="width:100px;height:100px;object-fit:contain;flex-shrink:0;
                filter:drop-shadow(0 4px 14px rgba(67,152,195,0.2))
                       drop-shadow(0 2px 6px rgba(0,0,0,0.5));">
            <div style="flex:1;display:flex;flex-direction:column;gap:5px;">
              <!-- Programmname -->
              <div>
                <div style="font-family:'EXO 2';font-size:12px;font-weight:500;
                  letter-spacing:0.5px;text-transform:uppercase;
                  color:rgba(67,152,195,1);margin-bottom:2px;">Programm</div>
                <div style="font-family:'EXO 2';font-size:22px;font-weight:500;
                  color:#E8F4FC;letter-spacing:0.5px;line-height:1.2;">${progName}</div>
              </div>
              <!-- Restzeit -->
              <div>
                <div style="font-family:'EXO 2';font-size:12px;font-weight:500;
                  letter-spacing:0.5px;text-transform:uppercase;
                  color:rgba(67,152,195,1);margin-bottom:2px;">Restzeit</div>
                <div style="font-family:'EXO 2';font-size:36px;font-weight:500;
                  letter-spacing:0.5px;line-height:1.2;
                  color:${active ? '#E8F4FC' : 'rgba(255,255,255,0.5)'};
                  ${active ? 'text-shadow:0 0 25px rgba(67,152,195,0.3);' : ''}">
                  ${timeStr}
                  ${active ? '<span style="font-size:14px;color:#4398C3;margin-left:4px;font-weight:500;">h</span>' : ''}
                </div>
              </div>
            </div>
          </div>


          <!-- BLOCK 3: STAT-KACHELN -->
          <!-- Reihenfolge der Kacheln hier Γ€nderbar -->
          <div style="position:absolute;top:170px;left:0;right:0;">
          <div style="display:flex;gap:8px;margin-bottom:10px;">
            ${statTile('mdi:flash-outline',          power,  'W',   'Leistung',        '#7EC8E3')}
            ${statTile('mdi:meter-electric-outline', energy, 'kWh', 'Jahresverbrauch', '#7EC8E3')}
            ${statTile('mdi:percent-circle-outline', pct,    '%',   'Fortschritt',     active ? '#FF6B78' : '#4398C3')}
          </div>

          <!-- BLOCK 4: FORTSCHRITTSBALKEN -->
          <div style="position:absolute;top:85px;left:0;right:0;">
            <div style="display:flex;align-items:center;
              justify-content:space-between;margin-bottom:3px;">
              <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
                letter-spacing:0.5px;text-transform:uppercase;color:rgba(67,152,195,1);">
                Waschfortschritt
              </span>
              <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
                color:${pctCol};">${pct}%</span>
            </div>
            <div style="height:6px;background:rgba(255,255,255,0.06);
              border-radius:3px;overflow:hidden;">
              <div style="height:100%;width:${pct}%;background:${barBg};
                border-radius:3px;box-shadow:${barGlow};
                transition:width 0.5s ease;"></div>
            </div>
          </div>


          
          <!-- BLOCK 5: FOOTER (Status + iDos 1 + iDos 2) -->
          <div style="position:absolute;top:128px;left:0;right:0;">
          <div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;">

            <!-- Betriebsstatus links -->
            <div style="display:flex;align-items:center;gap:6px;">
              <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
                letter-spacing:0.5px;text-transform:uppercase;color:rgba(67,152,195,1);">
                Status:
              </span>
              <span style="font-family:'EXO 2';font-size:15px;font-weight:500;letter-spacing:0.5px;
                color:${active ? '#E8F4FC' : 'rgba(67,152,195,1)'};">
                ${status}
              </span>
            </div>

            <div style="flex:1;"></div>

            <!-- iDos 1 rechts -->
            <div style="display:flex;align-items:center;gap:6px;">
              <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
                letter-spacing:0.5px;text-transform:uppercase;color:rgba(67,152,195,1);">
                iDos 1
              </span>
              ${idosPill(i1)}
            </div>

            <!-- iDos 2 rechts -->
            <div style="display:flex;align-items:center;gap:6px;">
              <span style="font-family:'EXO 2';font-size:12px;font-weight:500;
                letter-spacing:0.5px;text-transform:uppercase;color:rgba(67,152,195,1);">
                iDos 2
              </span>
              ${idosPill(i2)}
            </div>

          </div>

        </div>`;
    ]]]