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_temperatura– zadawanie temperatury docelowej czajnika (wartość, którą chcesz osiągnąć), zwykle zakres 40–100 °C. -
switch.smart_kettle_setti_kt950w_start– start/stop grzania (włącznik gotowania). ON = grzej, OFF = stop. -
sensor.smart_kettle_setti_kt950w_current_temperature– aktualna temperatura wody odczytana z czajnika (tylko do odczytu), w °C. -
sensor.smart_kettle_setti_kt950w_status– status pracy czajnika (np. idle/heating/boiled/keep-warm itp., tylko do odczytu). -
switch.smart_kettle_setti_kt950w_heat_preservation– podtrzymywanie ciepła (tryb „keep warm”). ON = utrzymuj temperaturę. -
number.smart_kettle_setti_kt950w_heat_preservation_time– czas 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!
Mniejsza karta:
type: vertical-stack
cards:
# Status i główny przycisk
- type: custom:button-card
entity: switch.smart_kettle_setti_kt950w_start
name: >
[[[
return (entity && entity.state === 'on') ? 'STOP' : 'GOTUJ';
]]]
icon: mdi:kettle
tap_action:
action: toggle
show_label: true
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: 52px
- padding: 1px
- background: >
[[[
return entity && entity.state === 'on'
? 'var(--error-color, #c62828)'
: 'var(--primary-color)';
]]]
- color: white
name:
- font-weight: 700
- font-size: 14px
icon:
- width: 22px
- color: white
label:
- margin-top: 2px
- font-size: 12px
- opacity: 0.9
# TEMPERATURY
- type: grid
columns: 3
square: false
cards:
- type: custom:button-card
name: '45°'
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: 50px
- padding: 2px
- border: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 45 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 45 ? 'var(--primary-color)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 45 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
icon:
- width: 20px
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 45 ? 'white' : 'var(--primary-text-color)';
]]]
- type: custom:button-card
name: '70°'
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: 50px
- padding: 2px
- border: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 70 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 70 ? 'var(--primary-color)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 70 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
icon:
- width: 20px
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 70 ? 'white' : 'var(--primary-text-color)';
]]]
- type: custom:button-card
name: '90°'
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: 50px
- padding: 2px
- border: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 90 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 90 ? 'var(--primary-color)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 90 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
icon:
- width: 20px
- color: >
[[[
const cur = Number(states['number.smart_kettle_setti_kt950w_temperatura']?.state || 0);
return cur === 90 ? 'white' : 'var(--primary-text-color)';
]]]
# PODTRZYMANIE: ikona ognia + czasy
- type: grid
columns: 4
square: false
cards:
# TYLKO IKONA OGNIA (toggle)
- type: custom:button-card
entity: switch.smart_kettle_setti_kt950w_heat_preservation
icon: mdi:fire
show_name: false
tap_action: { action: toggle }
hold_action: { action: more-info }
styles:
card:
- border-radius: 50px
- padding: 3px
- border: >
[[[
const on = states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state === 'on';
return on ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const on = states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state === 'on';
return on ? 'var(--accent-color)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const on = states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state === 'on';
return on ? 'white' : 'var(--primary-text-color)';
]]]
icon:
- width: 20px
- color: >
[[[
const on = states['switch.smart_kettle_setti_kt950w_heat_preservation']?.state === 'on';
return on ? 'white' : 'var(--primary-text-color)';
]]]
# CZASY PODTRZYMANIA
- type: custom:button-card
name: '30'
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: 50px
- padding: 6px
- border: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 30 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 30 ? 'var(--success-color, #2e7d32)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 30 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
- type: custom:button-card
name: '60'
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: 50px
- padding: 6px
- border: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 60 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 60 ? 'var(--success-color, #2e7d32)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 60 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
- type: custom:button-card
name: '120'
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: 50px
- padding: 6px
- border: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 120 ? '1px solid transparent' : '1px solid var(--divider-color)';
]]]
- background: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 120 ? 'var(--success-color, #2e7d32)' : 'var(--ha-card-background)';
]]]
- color: >
[[[
const t = Number(states['number.smart_kettle_setti_kt950w_heat_preservation_time']?.state || 0);
return t === 120 ? 'white' : 'var(--primary-text-color)';
]]]
name: [font-size: 13px]
