Skripte gehören zu den am meisten unterschätzten Werkzeugen in Home Assistant. Richtig eingesetzt, schreibst du eine Logik nur ein einziges Mal und rufst sie danach überall mit unterschiedlichen Werten auf. In diesem Beitrag zeige ich dir Schritt für Schritt, wie du das mit Feldern und Variablen umsetzt – inklusive aller Code-Beispiele aus dem Video zum Rauskopieren.
In der Praxis heißt das: Statt denselben Block in zehn Automationen zu pflegen, hast du am Ende ein einziges, sauberes Skript, das du überall aufrufst. Wir bauen das gemeinsam von Grund auf – erst ein einfaches Skript mit Feldern, dann optionale Eingaben über Default-Werte, komfortable Auswahl per Selektoren und schließlich dynamische Werte mit Variablen. Egal ob du gerade erst mit Skripten startest oder schon länger dabei bist: Am Ende hast du eine Vorlage, die du direkt auf dein eigenes Smart Home überträgst.
Das Problem: derselbe Code in zwanzig Automationen
Kennst du das? Dieselbe Push-Benachrichtigung steht bei dir in zehn oder zwanzig Automationen. Mal meldet sie die fertige Waschmaschine, mal ein offenes Fenster – aber das Gerüst aus notify, Titel und Nachricht ist jedes Mal dasselbe, nur mit anderem Text. Bei zwei Automationen ist das egal. Bei zwanzig wird es zum echten Problem: Sobald du dein Handy wechselst oder dein Notify-Dienst anders heißt, darfst du die Änderung an zwanzig Stellen nachziehen.
Du magst Home Assistant? Dann abonniere kostenlos meine Beiträge mit Tipps, Tricks und Anleitungen rund um Home Assistant:
Follow Home Assistant
Garantiert kein Spam, keine Werbung und immer mit Abmelde-Link, solltest du es dir anders überlegen!
Genau dafür gibt es Skripte mit Feldern. Du baust den Block einmal, lässt die variablen Teile offen und füllst sie bei jedem Aufruf neu.
Vorab: Android, iOS und wie du den Code übernimmst
Ich zeige alles am Beispiel von Android. Auf iOS funktioniert es technisch genauso, einzelne Bezeichnungen bei den Benachrichtigungen heißen aber anders – ich weise an den entsprechenden Stellen darauf hin.
Alle Skripte hier sind im Format des UI-Skript-Editors geschrieben, beginnen also direkt bei alias. Du legst dafür unter Einstellungen → Automationen & Szenen → Skripte ein neues Skript an, schaltest oben rechts auf „In YAML bearbeiten“ und fügst den Code ein. Wenn du lieber klickst als tippst: Das meiste lässt sich genauso über die normalen Pflegedialoge zusammenbauen – nur bei Aktionen mit Templates solltest du im YAML-Modus bleiben (warum, dazu unten mehr).
Und hier gibt es das Ganze auch im Bewegtbild als Video von mir:
Schritt 1: Ein Skript mit Feldern bauen
Die Idee ist simpel: Wir bauen den Benachrichtigungs-Block genau einmal als eigenes Skript. Die Teile, die sich von Fall zu Fall unterscheiden – Titel und Nachricht – lassen wir offen. Diese offenen Stellen nennt Home Assistant Felder (fields).
alias: "Benachrichtigung aufs Handy"
fields:
titel:
description: "Überschrift der Nachricht"
example: "Waschmaschine"
selector:
text:
nachricht:
description: "Inhalt der Nachricht"
example: "ist fertig!"
selector:
text:
sequence:
# Dienstnamen ggf. anpassen (Entwicklerwerkzeuge -> Aktionen, "notify.").
# WICHTIG: nur hier im YAML aendern! Im visuellen Dialog gehen title/message verloren.
- action: notify.mobile_app_pixel_10_pro
data:
title: "{{ titel | default('Hinweis') }}"
message: "{{ nachricht | default('(keine Nachricht übergeben)') }}"
Oben definierst du zwei Felder, titel und nachricht. Das sind die Platzhalter, die du beim Aufruf von außen befüllst. Unten in der Sequenz greifst du über die geschweiften Klammern darauf zu. Wer schon mal programmiert hat, erkennt das Prinzip: Das ist im Grunde eine Funktion – einmal definiert, beliebig oft mit anderen Werten aufgerufen.
Die default()-Filter sind ein kleines Sicherheitsnetz: Falls beim Aufruf doch mal kein Wert ankommt, sendet das Skript einen Ersatztext statt zu scheitern.
Wo kommt das script: hin?
Ein häufiger Stolperstein: Weil du das Skript über das Skript-Menü anlegst, fängst du direkt bei alias an. Ein script: davor brauchst du hier nicht – den Namen vergibt Home Assistant über das Menü. Schreibst du das script: trotzdem in den UI-Editor, bekommst du den Fehler extra keys not allowed @ data['script']. Nur wenn du deine Skripte stattdessen direkt in der configuration.yaml pflegst, kommt der ganze Block noch unter ein script: plus einen frei gewählten Namen.
Den richtigen Notify-Dienst eintragen
In meinem Beispiel heißt der Dienst notify.mobile_app_pixel_10_pro. Bei dir heißt er fast sicher anders – nämlich notify.mobile_app_ plus dem Namen, den dein Handy in der Companion-App bekommen hat. Den genauen Namen findest du unter Entwicklerwerkzeuge → Aktionen, wenn du notify. eintippst. Ändere den Dienstnamen nur im YAML-Modus, indem du den Text direkt überschreibst – nicht über den visuellen Dialog (Begründung weiter unten bei den Stolperfallen).
Das Skript aus einer Automation aufrufen
Statt des kompletten Notify-Blocks steht in deiner Automation jetzt nur noch das hier:
- action: script.benachrichtigung
data:
titel: "Waschmaschine"
nachricht: "ist fertig!"
Änderst du später dein Notify-Ziel, machst du das genau einmal – im Skript – und alle Automationen ziehen automatisch mit.
Schritt 2: Felder optional machen mit Default-Werten
Manchmal soll eine Benachrichtigung einfach nur normal aufs Handy. Manchmal ist sie aber wichtig – Wasser im Keller zum Beispiel – und soll auch durchkommen, wenn das Handy stumm ist. Dafür ergänzen wir ein drittes Feld mit einem Default-Wert:
alias: "Benachrichtigung aufs Handy"
fields:
titel:
description: "Überschrift der Nachricht"
selector:
text:
nachricht:
description: "Inhalt der Nachricht"
selector:
text:
wichtig:
description: "Als kritische Nachricht senden?"
default: false
selector:
boolean:
sequence:
# Dienstnamen ggf. anpassen (Entwicklerwerkzeuge -> Aktionen, "notify.").
# WICHTIG: nur hier im YAML aendern! Im visuellen Dialog gehen title/message verloren.
- action: notify.mobile_app_pixel_10_pro
data:
title: "{{ titel | default('Hinweis') }}"
message: "{{ nachricht | default('(keine Nachricht übergeben)') }}"
# Android-Syntax fuer "dringend". iOS waere: {'push': {'interruption-level': 'critical'}}
data: "{{ {'ttl': 0, 'priority': 'high'} if wichtig | default(false) else {} }}"
Sobald ein Feld ein default: hat, ist es optional. Lässt du wichtig beim Aufruf weg, greift der Standardwert false und es bleibt eine normale Nachricht. Setzt du wichtig: true, hängt das Skript die Zusatz-Info an, die die Benachrichtigung dringend macht.
Diese Zusatz-Info zeige ich in der Android-Schreibweise mit ttl und priority. Auf iOS arbeitest du stattdessen mit interruption-level: critical – das Prinzip ist identisch, nur die Schlüssel unterscheiden sich. Die iOS-Variante steht als Kommentar direkt im Code.
Schritt 3: Selektoren für komfortable Eingaben
Wenn du ein Skript manuell ausführst, baut Home Assistant dir ein kleines Eingabeformular. Wie dieses Formular aussieht, bestimmst du über den Selektor (selector). Bisher waren unsere Felder einfache Textfelder. Du kannst aber auch sagen: Dieses Feld ist eine Lampe.
lampe:
description: "Welche Lampe?"
selector:
entity:
domain: light
Damit bekommst du beim Ausführen kein leeres Textfeld mehr, sondern ein Dropdown mit all deinen Lampen. Genauso geht es für Zahlenwerte – hier als Schieberegler:
minuten:
description: "Wie lange? (in Minuten)"
default: 5
selector:
number:
min: 1
max: 60
step: 1
mode: slider
unit_of_measurement: "min"
Das ist nicht nur hübscher, es verhindert auch Tippfehler und ungültige Werte. Du baust dir damit quasi deine eigene kleine Bedienoberfläche fürs Skript.
Praxisbeispiel: Ein Skript für beliebig viele Lampen
Damit das nicht zu abstrakt bleibt, hier ein zweites Skript, das ich selbst täglich nutze: Licht für eine bestimmte Zeit einschalten und dann automatisch wieder aus – ideal für Keller, Garage oder Abstellraum.
alias: "Licht temporär einschalten"
fields:
lampe:
description: "Welche Lampe?"
selector:
entity:
domain: light
minuten:
description: "Wie lange?"
default: 5
selector:
number:
min: 1
max: 60
mode: slider
unit_of_measurement: "min"
sequence:
# Felder (lampe/minuten) bleiben templatisiert -> Aktionen nur im YAML-Modus bearbeiten.
- action: light.turn_on
target:
entity_id: "{{ lampe }}"
- delay:
minutes: "{{ minuten }}"
- action: light.turn_off
target:
entity_id: "{{ lampe }}"
Die Sequenz macht genau drei Dinge: Lampe an, warten, Lampe aus. Welche Lampe und wie lange, steht nicht fest im Skript, sondern kommt aus den Feldern. Damit brauchst du nicht ein Skript fürs Kellerlicht und ein zweites fürs Garagenlicht – du hast ein einziges Skript und rufst es überall mit anderen Werten auf.
Schritt 4: Variablen – Werte im Skript selbst berechnen
Der zweite große Baustein sind Variablen. Der Unterschied ist schnell erklärt: Felder kommen von außen rein, Variablen baust du innen im Skript selbst. Praktisch ist das, wenn du denselben berechneten Wert an mehreren Stellen brauchst.
alias: "Benachrichtigung aufs Handy"
fields:
titel:
description: "Überschrift der Nachricht"
selector:
text:
nachricht:
description: "Inhalt der Nachricht"
selector:
text:
geraet:
description: "An welches Handy?"
default: "pixel_10_pro"
selector:
select:
options:
- "pixel_10_pro"
- "partner_handy" # Platzhalter: an echten Geraetenamen anpassen
wichtig:
description: "Als kritische Nachricht senden?"
default: false
selector:
boolean:
sequence:
- variables:
voller_text: "{{ titel | default('Hinweis') }}: {{ nachricht | default('(keine Nachricht übergeben)') }}"
# Handy-Name ggf. anpassen: muss dem Teil nach "mobile_app_" entsprechen.
# Vorteil: Ziel als Variable -> nie wieder im visuellen Dialog auswaehlen (sonst Templates weg).
ziel: "notify.mobile_app_{{ geraet | default('pixel_10_pro') }}"
- action: "{{ ziel }}"
data:
message: "{{ voller_text }}"
# Android-Syntax fuer "dringend". iOS waere: {'push': {'interruption-level': 'critical'}}
data: "{{ {'ttl': 0, 'priority': 'high'} if wichtig | default(false) else {} }}"
- action: persistent_notification.create
data:
message: "{{ voller_text }}"
Hier passieren zwei Dinge. Erstens baue ich die Variable voller_text einmal aus Titel und Nachricht zusammen und nutze sie danach mehrfach – einmal für die Push-Nachricht aufs Handy, einmal für den Eintrag ins Home-Assistant-Log. Ohne Variable müsste ich denselben Ausdruck zweimal hinschreiben.
Zweitens baue ich über die Variable ziel sogar den Notify-Dienst dynamisch zusammen. Du gibst als Feld nur den Gerätenamen mit (hier als Auswahl-Dropdown), und das Skript setzt daraus den vollständigen Dienst zusammen. Damit verschickt ein und dasselbe Skript an verschiedene Handys – praktisch für die ganze Familie. Als angenehmer Nebeneffekt umgehst du so die weiter unten beschriebene Template-Falle, weil du den Notify-Dienst nie wieder direkt in einer Aktion auswählst.
Bonus: Das Skript direkt aufs Dashboard legen
Ein Skript lebt nicht nur versteckt in Automationen – du kannst es auch direkt auf dein Dashboard legen:
type: button
name: "Kellerlicht 5 Min"
tap_action:
action: perform-action
perform_action: script.licht_temporaer
data:
lampe: light.keller
minuten: 5
Ein Fingertipp, und dieselbe Logik läuft wie über eine Automation. Damit schließt sich der Kreis: Ein Skript, einmal gebaut, läuft in deinen Automationen und auf deiner Bedienoberfläche.
Häufige Stolperfallen (und wie du sie vermeidest)
Beim Nachbauen lauern ein paar typische Fehler. Hier die wichtigsten:
extra keys not allowed @ data['script'] – Du hast das script: mit in den UI-Editor geschrieben. Im Skript-Menü beginnst du direkt bei alias. Das script: brauchst du nur in der configuration.yaml.
required key not provided @ data['message'] – Bei notify ist message ein Pflichtfeld und muss eine Ebene unter data: stehen. Tritt der Fehler auf, ist meist beim Abtippen die Einrückung verrutscht, oder beim Aufruf wurde kein nachricht übergeben. Die default()-Filter im Skript fangen den leeren Fall zusätzlich ab.
Der visuelle Pflegedialog frisst deine Templates – Das ist die fieseste Falle. Wenn du eine Aktion mit Templates über den visuellen Dialog bearbeitest (zum Beispiel um dein Handy aus der Liste auszuwählen), baut Home Assistant die Aktion neu auf und wirft dabei die templatisierten Werte für title und message raus. Ergebnis: wieder der „message fehlt“-Fehler. Goldene Regel: Sobald in einer Aktion Templates stehen, bearbeitest du sie nur noch im YAML-Modus.
Feld-defaults greifen nicht beim Aufruf aus einer Automation – Ein default: unter einem Feld gilt nur für das UI-Formular. Wird ein Feld aus einer Automation nicht übergeben, ist es im Skript undefined – nicht der Default. Deshalb sichere ich echte Standardwerte zusätzlich im Template ab, zum Beispiel mit {{ geraet | default('pixel_10_pro') }}.
Fazit
Das ist im Grunde das ganze Geheimnis: Felder für das, was von außen kommt, Variablen für das, was du innen berechnest – und ein Skript, das du nur ein einziges Mal anfasst, wenn sich etwas ändert. Damit räumst du nicht nur deine Automationen auf, sondern sparst dir auf Dauer eine Menge Pflegearbeit.
Welches deiner Skripte schreit am lautesten danach, mit Feldern aufgeräumt zu werden? Schreib es gern in die Kommentare.
Produktempfehlungen



