Custom Button-Card: Button im Button - ich verzweifle

Guten Abend zusammen,

Ihr kennt das: Wenn man sich einmal an einer Idee festgebissen hat, will man davon nicht mehr loslassen. So geht es mir gerade beim Styling meines Dachboards.

Inspiriert durch das Soft UI Theme habe ich eine angepasste Version davon für mich erstellt. Die normalen Karten lassen sich auch ganz gut anpassen (z.T. über card-mod). Nur die Cover-Card macht mir echt Bauchschmerzen. Umgesetzt ist sie schon mal, auch mit schönen Effekten versehen, wenn sich die Rollade öffnet oder schließt. Spielerei, ich weiß, aber mir gefällts :wink:

Und so sieht sie aus:

Was ich ums Verrecken nicht hinbekomme, ist die drei Buttons dezidiert ansteuern zu können, um über sie die Cover-typischen Funktionen auszulösen.

Hier der Code der Karte:

type: custom:button-card
entity: cover.dachfensterrolladen_1
name: Dachfenster I
icon: mdi:window-shutter
size: 50px
show_state: true
show_label: true
tap_action:
  action: none
styles:
  card:
    - width: 430px
    - height: 125px
    - padding: 10px
  grid:
    - grid-template-areas: "\"i l\" \"n n\" \"s s\""
    - grid-template-columns: 165px 250px
    - grid-template-rows: 50px 30px 16px
    - gap: 3px
  img_cell:
    - justify-content: start
    - align-self: start
    - text-align: start
    - margin: 0px 1px 1px 10px
  label:
    - width: 220px
    - height: 106px
    - justify-content: start
    - align-self: start
    - text-align: start
    - font-size: 50px
    - padding: 0px 0px 0px 0px
  name:
    - justify-self: start
    - align-self: center
    - padding: 0px 1px 1px 10px
    - font-size: 20px
  state:
    - justify-self: start
    - align-self: center
    - padding: 0px 1px 1px 10px
    - font-size: 14px
label: >
  <div style="display: flex; justify-content: space-evenly; align-items: center;
  width: 100%; height: 100%;">
    <button style="width: 55px; height: 55px; margin: 10px; border: 1px solid var(--button-border-color); border-radius: 50%; background: linear-gradient(145deg, #191919, #1e1e1e); color: var(--button-text-color); cursor: pointer; box-shadow: 5px 5px 6px #111111, -5px -5px 6px #272727;"
      tap-action='{"action": "call-service", "service": "cover.open_cover", "service_data": {"entity_id": "cover.dachfensterrolladen_1"}}'>
      <ha-icon icon="mdi:arrow-up" style="width: 24px; height: 24px; color: white;"></ha-icon>
    </button>
    <button style="width: 55px; height: 55px; margin: 10px; border: 1px solid var(--button-border-color); border-radius: 50%; background: linear-gradient(145deg, #191919, #1e1e1e); color: var(--button-text-color); cursor: pointer; box-shadow: 5px 5px 6px #111111, -5px -5px 6px #272727;"
      tap-action='{"action": "call-service", "service": "cover.stop_cover", "service_data": {"entity_id": "cover.dachfensterrolladen_1"}}'>
      <ha-icon icon="mdi:pause" style="width: 24px; height: 24px; color: white;"></ha-icon>
    </button>
    <button style="width: 55px; height: 55px; margin: 10px; border: 1px solid var(--button-border-color); border-radius: 50%; background: linear-gradient(145deg, #191919, #1e1e1e); color: var(--button-text-color); cursor: pointer; box-shadow: 5px 5px 6px #111111, -5px -5px 6px #272727;"
      tap-action='{"action": "call-service", "service": "cover.close_cover", "service_data": {"entity_id": "cover.dachfensterrolladen_1"}}'>
      <ha-icon icon="mdi:arrow-down" style="width: 24px; height: 24px; color: white;"></ha-icon>
    </button>
  </div>
state:
  - value: open
    styles:
      card:
        - border-style: solid
        - border-width: 0px
        - border-color: var(--border-active-color)
        - box-shadow: >-
            var(--box-active-glow), var(--soft-ui-button-up),
            var(--soft-ui-frame-up)
        - background: var(--ha-card-background-pressed)
        - animation: glow-once 2s 1
      icon:
        - filter: drop-shadow(0 0 0.3rem rgb(14 154 182 / 95%))
        - color: var(--icon-open-color)
      name:
        - color: var(--name-open-color)
      state:
        - color: var(--state-open-color)
        - opacity: 0.8
  - value: opening
    styles:
      card:
        - box-shadow: var(--soft-ui-button-up), var(--soft-ui-frame-up)
        - box-shadow: >-
            var(--box-active-glow), var(--soft-ui-button-up),
            var(--soft-ui-frame-up)
        - background: var(--ha-card-background-pressed)
        - animation: glow-pulse 2s infinite
      icon:
        - color: var(--icon-opening-color)
      name:
        - color: var(--name-opening-color)
      state:
        - color: var(--state-opening-color)
        - opacity: 0.8
  - value: closing
    styles:
      card:
        - box-shadow: var(--soft-ui-button-up), var(--soft-ui-frame-up)
        - box-shadow: >-
            var(--box-active-glow), var(--soft-ui-button-up),
            var(--soft-ui-frame-up)
        - background: var(--ha-card-background-pressed)
        - animation: glow-pulse 2s infinite
      icon:
        - color: var(--icon-closing-color)
      name:
        - color: var(--name-closing-color)
      state:
        - color: var(--state-closing-color)
        - opacity: 0.8
  - value: closed
    styles:
      card:
        - box-shadow: var(--soft-ui-button-up), var(--soft-ui-frame-up)
        - background: var(--ha-card-background-pressed)
        - animation: glow-once 2s 1
      icon:
        - color: var(--icon-closed-color)
      name:
        - color: var(--name-closed-color)
      state:
        - color: var(--state-closed-color)
        - opacity: 0.8
  - value: unavailable
    styles:
      card:
        - box-shadow: var(--soft-ui-button-up), var(--soft-ui-frame-up)
        - box-shadow: >-
            var(--box-active-glow), var(--soft-ui-button-up),
            var(--soft-ui-frame-up)
        - background: var(--ha-card-background-pressed)
        - animation: red-glow-pulse 2s infinite
      icon:
        - color: var(--icon-unavailable-color)
      name:
        - color: var(--name-unavailable-color)
      state:
        - color: var(--state-unavailable-color)
        - opacity: 0.8
card_mod:
  style: |
    @keyframes glow-pulse {
      0% {
        box-shadow: 0 0 10px #8af0ff;
      }
      50% {
        box-shadow: 0 0 20px #8af0ff;
      }
      100% {
        box-shadow: 0 0 10px #8af0ff;
      }
    }
    @keyframes glow-once {
      0% {
        box-shadow: 0 0 0 #0fff52;
      }
      50% {
        box-shadow: 0 0 20px #0fff52;
      }
      100% {
        box-shadow: 0 0 0 #0fff52;
      }
    }
    @keyframes red-glow-pulse {
      0% {
        box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
      }
      50% {
        box-shadow: 0 0 20px rgba(255, 0, 0, 0.8);
      }
      100% {
        box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
      }
    }

Hat jemand eine Idee, wo ich falsch abgebogen bin?

Viele Grüße
Martin

2 „Gefällt mir“

Schicke kleine Card. Nimmst du nicht gleich ganz oben mit tap_action: action: none die komplette Funktion des Taps aus der Card?

1 „Gefällt mir“

Stimmt, das hatte ich mal so eingestellt in der irren (irrigen) Annahme, dass die sich eventuell mit den Anweisungen für die Buttons weiter unten überlagert… :sweat_smile:

1 „Gefällt mir“

Wäre für diesen Zweck die Bubble-Card nicht die bessere Wahl?

1 „Gefällt mir“

Danke Dir für den Hinweis mit den Bubble Cards :wink:

Leider bin ich gedanklich im Moment noch zu sehr auf dem Individualisten-Trip und würde alles daran setzen, das Erscheinungsbild wie oben zu sehen umzusetzen.

Falls alles nicht funktioniert, trete ich entweder mein Home Assistant in die Tonne oder nutze einfach die Karten, die da sind :joy:

3 „Gefällt mir“

Hi @HAndy. Das gefällt mir gut, hast Du einen Code dazu?
Bubble Card ist bei mir bisher „nur“ für PopUps zuständig, aber da geht ja echt noch viel mehr.
Danke:)

Hallo @andifidi ,
klar, gerne. Hier ist mal beispielhaft der Code für den Ventilator:

type: custom:bubble-card
card_type: button
name: Ventilator
entity: script.ventilator_power
button_type: state
show_state: false
button_action:
  tap_action:
    action: toggle
sub_button:
  - entity: script.ventilator_power
    icon: mdi:power
    tap_action:
      action: toggle
  - entity: script.ventilator_andersrum
    icon: mdi:arrow-oscillating
    tap_action:
      action: toggle
      target: {}
    show_background: false
  - name: ""
    icon: mdi:numeric-1-circle-outline
    tap_action:
      action: toggle
      target: {}
    show_background: false
    entity: script.ventilator_stufe_1
  - entity: script.ventilator_stufe_2
    icon: mdi:numeric-2-circle-outline
    show_background: false
    tap_action:
      action: toggle
      target: {}
  - entity: script.ventilator_stufe_3
    icon: mdi:numeric-3-circle-outline
    show_background: false
    tap_action:
      action: toggle
      target: {}
  - entity: script.ventilator_stufe_4
    icon: mdi:numeric-4-circle-outline
    show_background: false
    tap_action:
      action: toggle
      target: {}
  - entity: script.ventilator_stufe_5
    icon: mdi:numeric-5-circle-outline
    show_background: false
    tap_action:
      action: toggle
      target: {}
styles: |
  .bubble-button-card-container {
    opacity: 1 !important;
    background: 
      ${
      hass.states['input_text.ventilator_stufe'].state === '0' ?
        '' :
        'linear-gradient(0deg, green 40%, lightgreen 80%)'
      } !important;
  }
  .bubble-icon {
    color: 
      ${
      hass.states['input_text.ventilator_stufe'].state === '0' ? 
      '' :
      'lightgreen'
    } !important;
  }
  .bubble-sub-button-1 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '0' ? 
        'orangered' : 
        'green'
    } !important;
  }
  .bubble-sub-button-2 {
    background-color: ${ 
      hass.states['input_text.ventilator_stufe'].state === '0' ? 
        'black' :
        'purple'
    } !important;
  }
  .bubble-sub-button-3 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '1' ? 
        'green' : 
        'black'
    } !important;
  }
  .bubble-sub-button-4 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '2' ? 
        'green' : 
        'black'
    } !important;
  }
  .bubble-sub-button-5 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '3' ? 
        'green' : 
        'black'
    } !important;
  }
  .bubble-sub-button-6 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '4' ? 
        'green' : 
        'black'
    } !important;
  }
  .bubble-sub-button-7 {
    background-color: ${
      hass.states['input_text.ventilator_stufe'].state === '5' ? 
        'green' : 
        'black'
    } !important;
  }

Habe das gerade mal für dich nachgebaut und funktioniert soweit wie gewünscht mit der custom:button-card. Die Optik sollte auch schon im Großteil wie in deinem Beispiel sein. Den kleinen Rest musst du dir nach deinen Wünschen anpassen. Der erste Button ist noch mit meinem PC Licht verbunden, um die tap_action zu testen. Auf jeden Fall, funktioniert hier die tap_action, was deine eigentliche Eingangsfrage war. :slight_smile:

type: custom:button-card
show_state: true
show_label: true
name: Dachfenster I
state_display: Geöffnet
icon: mdi:window-shutter
layout: vertical
styles:
  card:
    - background: var(--card-background-color)
    - border-radius: 16px
    - box-shadow: 0 0 10px 2px rgba(0, 255, 255, 0.5)
    - padding: 16px
    - color: var(--primary-text-color)
  icon:
    - width: 60px
    - color: "#1799b2"
  name:
    - justify-self: start
    - font-size: 14px
    - font-weight: bold
    - color: "#1799b2"
  state:
    - justify-self: start
    - font-size: 14px
    - color: "#1799b2"
  grid:
    - grid-template-rows: 1fr auto auto
    - gap: 0px
custom_fields:
  controls:
    card:
      type: horizontal-stack
      cards:
        - type: custom:button-card
          icon: mdi:arrow-up
          show_name: false
          styles:
            card:
              - width: 55px
              - height: 55px
              - margin: "-80px 10px 10px 10px"
              - border: 1px solid var(--button-border-color)
              - border-radius: 50%
              - background: linear-gradient(145deg,#191919,#1e1e1e)
              - color: var(--button-text-color)
              - cursor: pointer
              - box-shadow: "5px 5px 6px #111111, -5px -5px 6px #272727"
          tap_action:
            action: call-service
            service: switch.toggle
            service_data:
              entity_id: switch.pc_led_pv_led
        - type: custom:button-card
          icon: mdi:pause
          show_name: false
          styles:
            card:
              - width: 55px
              - height: 55px
              - margin: "-80px 10px 10px 10px"
              - border: 1px solid var(--button-border-color)
              - border-radius: 50%
              - background: linear-gradient(145deg,#191919,#1e1e1e)
              - color: var(--button-text-color)
              - cursor: pointer
              - box-shadow: "5px 5px 6px #111111, -5px -5px 6px #272727"
          tap_action:
            action: call-service
            service: cover.stop_cover
            service_data:
              entity_id: cover.dachfenster
        - type: custom:button-card
          icon: mdi:arrow-down
          show_name: false
          styles:
            card:
              - width: 55px
              - height: 55px
              - margin: "-80px 10px 10px 10px"
              - border: 1px solid var(--button-border-color)
              - border-radius: 50%
              - background: linear-gradient(145deg,#191919,#1e1e1e)
              - color: var(--button-text-color)
              - cursor: pointer
              - box-shadow: "5px 5px 6px #111111, -5px -5px 6px #272727"
          tap_action:
            action: call-service
            service: cover.close_cover
            service_data:
              entity_id: cover.dachfenster
card_mod:
  style: |
    :not(ha-state-icon) ha-icon, ha-state-icon {
      margin-left: -5px !important;
      --mdc-icon-size: 100%;
      --iron-icon-width: 100%;
      --iron-icon-height: 100%;
    }

sieht dann so aus:

Hi @HAndy, super. Danke!

Hey @jayjojayson

1000 Dank für die perfekte Umsetzung!!!

Das bißchen gestalterische Anpassung bekomme ich mit Sicherheit selber hin. Da sieht man mal wieder, wozu Schwarmwissen in der Lage ist!

You made my day! :+1: :grin:

1 „Gefällt mir“