Jak stworzyć kartę sterowania czajnikiem w Home Assistant (Button Card + Tuya)

Aby przygotować interaktywną kartę z przyciskami, będziesz potrzebować:

  • integracji HACS (Home Assistant Community Store),

  • dodatku Button Card – dostępnego bezpośrednio przez HACS.

Po instalacji obu integracji należy sprawdzić konfigurację w narzędziach deweloperskich i ponownie uruchomić Home Assistanta. Dzięki temu karty będą dostępne w panelu Lovelace.


💡 Tworzenie karty Button Card

Po instalacji przejdź do wybranego panelu w Home Assistant, kliknij „Dodaj kartę”, wybierz „Button Card” i wklej kod

type: vertical-stack
cards:
  - type: markdown
    content: |
      ## ☕ Czajnik SETTI
  - type: grid
    columns: 3
    square: false
    cards:
      - type: custom:button-card
        name: 45 °C
        icon: mdi:thermometer
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_temperatura
            value: 45
        styles:
          card:
            - border-radius: 18px
            - padding: 12px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.15))
            - transition: all 0.2s ease
            - background: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 45 ? 'linear-gradient(180deg, var(--primary-color), var(--primary-color))'
                                      : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 45 ? 'white' : 'var(--primary-text-color)'; ]]]
          name:
            - font-weight: 700
            - font-size: 16px
          icon:
            - width: 26px
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 45 ? 'white' : 'var(--primary-color)'; ]]]
      - type: custom:button-card
        name: 70 °C
        icon: mdi:thermometer
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_temperatura
            value: 70
        styles:
          card:
            - border-radius: 18px
            - padding: 12px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.15))
            - transition: all 0.2s ease
            - background: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 70 ? 'linear-gradient(180deg, var(--primary-color), var(--primary-color))'
                                      : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 70 ? 'white' : 'var(--primary-text-color)'; ]]]
          name:
            - font-weight: 700
            - font-size: 16px
          icon:
            - width: 26px
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 70 ? 'white' : 'var(--primary-color)'; ]]]
      - type: custom:button-card
        name: 90 °C
        icon: mdi:thermometer
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_temperatura
            value: 90
        styles:
          card:
            - border-radius: 18px
            - padding: 12px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.15))
            - transition: all 0.2s ease
            - background: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 90 ? 'linear-gradient(180deg, var(--primary-color), var(--primary-color))'
                                      : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 90 ? 'white' : 'var(--primary-text-color)'; ]]]
          name:
            - font-weight: 700
            - font-size: 16px
          icon:
            - width: 26px
            - color: >
                [[[ const cur =
                Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state
                || 0);
                    return cur === 90 ? 'white' : 'var(--primary-color)'; ]]]
  - type: custom:button-card
    entity: switch.smart_kettle_setti_kt950w_start
    name: GOTUJ
    icon: mdi:kettle-steam
    tap_action:
      action: call-service
      service: switch.toggle
      data:
        entity_id: switch.smart_kettle_setti_kt950w_start
    label: >
      [[[ const cur =
      states['sensor.smart_kettle_setti_kt950w_current_temperature']?.state ??
      '—';
          const tgt = Math.round(Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0));
          const st  = states['sensor.smart_kettle_setti_kt950w_status']?.state ?? '';
          return `Cel: ${tgt}°C  •  Obecnie: ${cur}°C  •  ${st}`; ]]]
    styles:
      card:
        - border-radius: 22px
        - padding: 18px
        - box-shadow: 0 6px 18px rgba(0,0,0,0.18)
        - transition: all 0.2s ease
        - background: |
            [[[ const isOn = (entity && entity.state === 'on');
                return isOn ? 'linear-gradient(135deg, var(--error-color, #d32f2f), var(--error-color, #d32f2f))'
                            : 'linear-gradient(135deg, var(--primary-color), var(--primary-color))'; ]]]
        - color: white
      name:
        - font-size: 18px
        - font-weight: 800
        - letter-spacing: 0.5px
        - text-transform: uppercase
      icon:
        - width: 30px
        - color: white
      label:
        - margin-top: 6px
        - font-size: 14px
        - opacity: 0.9
    state:
      - value: "on"
        styles:
          card:
            - background: linear-gradient(135deg, var(--error-color,
            - color: white
          icon:
            - color: white
  - type: grid
    columns: 4
    square: false
    cards:
      - type: custom:button-card
        entity: switch.smart_kettle_setti_kt950w_heat_preservation
        name: Podtrzymuj
        icon: mdi:fire
        tap_action:
          action: toggle
        styles:
          card:
            - border-radius: 14px
            - padding: 10px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.12))
            - background: >
                [[[ return
                states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state
                === 'on'
                        ? 'linear-gradient(180deg, var(--accent-color), var(--accent-color))'
                        : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ return
                states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state
                === 'on'
                        ? 'white' : 'var(--primary-text-color)'; ]]]
          icon:
            - color: >
                [[[ return
                states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state
                === 'on'
                        ? 'white' : 'var(--accent-color)'; ]]]
      - type: custom:button-card
        name: 30 min
        icon: mdi:timer-outline
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_heat_preservation_time
            value: 30
        styles:
          card:
            - border-radius: 14px
            - padding: 10px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.12))
            - transition: all 0.2s ease
            - background: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===30 ? 'linear-gradient(180deg, var(--success-color, #43a047), var(--success-color, #43a047))'
                                  : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===30 ? 'white' : 'var(--primary-text-color)'; ]]]
          icon:
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===30 ? 'white' : 'var(--primary-color)'; ]]]
      - type: custom:button-card
        name: 60 min
        icon: mdi:timer-outline
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_heat_preservation_time
            value: 60
        styles:
          card:
            - border-radius: 14px
            - padding: 10px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.12))
            - transition: all 0.2s ease
            - background: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===60 ? 'linear-gradient(180deg, var(--success-color, #43a047), var(--success-color, #43a047))'
                                  : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===60 ? 'white' : 'var(--primary-text-color)'; ]]]
          icon:
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===60 ? 'white' : 'var(--primary-color)'; ]]]
      - type: custom:button-card
        name: 120 min
        icon: mdi:timer-outline
        tap_action:
          action: call-service
          service: number.set_value
          data:
            entity_id: number.smart_kettle_setti_kt950w_heat_preservation_time
            value: 120
        styles:
          card:
            - border-radius: 14px
            - padding: 10px
            - box-shadow: var(--ha-card-box-shadow, 0 2px 6px rgba(0,0,0,0.12))
            - transition: all 0.2s ease
            - background: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===120 ? 'linear-gradient(180deg, var(--success-color, #43a047), var(--success-color, #43a047))'
                                   : 'var(--ha-card-background, var(--card-background-color))'; ]]]
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===120 ? 'white' : 'var(--primary-text-color)'; ]]]
          icon:
            - color: >
                [[[ const t =
                Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state
                || 0);
                    return t===120 ? 'white' : 'var(--primary-color)'; ]]]


Karta składa się z trzech przycisków temperatur (np. 45°C, 70°C i 90°C) oraz przycisków do gotowania i podtrzymywania ciepła.

Najważniejsze jest to, by każda encja w kodzie odpowiadała Twojemu urządzeniu. W przykładzie wykorzystuję czajnik Setti Smart Kettle KT950W, który integruje się z Tuya.


🌡️ Dostosowanie temperatur

Jeśli chcesz ustawić własne wartości temperatur, wystarczy, że w kodzie zamienisz wszystkie wystąpienia liczb 45, 70 lub 90 na np. 60, 80 czy 100.
W ten sposób przyciski będą wysyłały do czajnika odpowiednie polecenie grzania do zadanej temperatury.


🔍 Jak znaleźć poprawne encje

Aby karta działała poprawnie, musisz wskazać właściwe encje, które Home Assistant przypisał do Twojego czajnika.
Zrobisz to wchodząc w Ustawienia → Urządzenia i usługi → TUYA → Twój czajnik → Encje, a następnie kopiując ich nazwy, np.:

    • number.smart_kettle_setti_kt950w_temperaturazadawanie temperatury docelowej czajnika (wartość, którą chcesz osiągnąć), zwykle zakres 40–100 °C.

    • switch.smart_kettle_setti_kt950w_startstart/stop grzania (włącznik gotowania). ON = grzej, OFF = stop.

    • sensor.smart_kettle_setti_kt950w_current_temperatureaktualna temperatura wody odczytana z czajnika (tylko do odczytu), w °C.

    • sensor.smart_kettle_setti_kt950w_statusstatus pracy czajnika (np. idle/heating/boiled/keep-warm itp., tylko do odczytu).

    • switch.smart_kettle_setti_kt950w_heat_preservationpodtrzymywanie ciepła (tryb „keep warm”). ON = utrzymuj temperaturę.

    • number.smart_kettle_setti_kt950w_heat_preservation_timeczas podtrzymywania (ile minut ma trwać tryb „keep warm”).

Następnie wklej te nazwy do kodu w odpowiednich miejscach.


⚙️ Jak to działa

Po zapisaniu karty zobaczysz trzy przyciski z temperaturami, które po kliknięciu ustawią wartość w encji czajnika.
Przycisk „Gotuj” uruchomi grzanie — jego kolor zmieni się na czerwony podczas działania.
Przycisk „Podtrzymuj” włączy funkcję utrzymania temperatury przez określony czas (np. 30 minut).

Całość działa w pełni interaktywnie i synchronizuje się ze stanem rzeczywistym czajnika — więc w panelu Home Assistant zawsze zobaczysz aktualną temperaturę oraz status pracy.


🎬 Dalsze możliwości

W tym wpisie pokazałem tylko część możliwości integracji Button Card.
Jeżeli chcesz, mogę przygotować osobny materiał, w którym szczegółowo omówię wszystkie dostępne funkcje — od animacji po dynamiczne kolory i warunki logiczne.

Zostaw komentarz lub ocenę pod filmem, jeśli chcesz zobaczyć więcej przykładów!