Du hast einen Wecker in Home Assistant. Du gehst in den Urlaub. Du schaltest den Wecker manuell aus. Du vergisst, ihn wieder einzuschalten. Oder du schaltest ihn zu früh ein und wirst am letzten Urlaubstag geweckt.
Die Lösung: Der Kalender ist die einzige Quelle der Wahrheit. Wenn dort “Urlaub” steht, schweigt der Wecker. Wenn das Event endet, feuert er wieder. Ohne Schalter, ohne Extra-Automation.
TL;DR
- Shell-Script auf dem HA-Server fragt per CalDAV, ob heute ein “urlaub”-Event aktiv ist
command_lineBinary Sensor in HA:on= Urlaub,off= kein Urlaub- Wecker-Automations prüfen
condition: notauf diesen Sensor — fail-open - Drei Pitfalls, die euch Zeit sparen: CalDAV Config Flow, deprecated YAML-Platform, BusyBox-
date
Die Architektur
Kalender-Server (CalDAV)
|
v (curl REPORT, alle 15 Min)
HA: check_urlaub.sh
|
v
binary_sensor.urlaub_kalender [on/off]
|
v (condition: not → state: on)
Set_Weekday_Alarm / Set_Weekend_Alarm
Der Binary Sensor pollt alle 15 Minuten den CalDAV-Server. Für mehrtägige Urlaubs-Events ist das mehr als ausreichend.
Das Script: CalDAV-Abfrage
Das Script läuft direkt im HA-Container und fragt per CalDAV REPORT (RFC 4791) die heutigen Events ab. Wenn ein Event mit “urlaub” im Titel gefunden wird: ON. Sonst: OFF.
#!/bin/bash
# /config/check_urlaub.sh
CALDAV_URL="https://mail.deathstar.lan/dav/calendars/luke.skywalker@rebellion.local/Kalender/"
CALDAV_USER="c3po@rebellion.local"
CALDAV_PASS="<DEIN-CALDAV-PASSWORT>"
START=$(date -u +%Y%m%dT000000Z)
# BusyBox-kompatibel (siehe Pitfall 3)
END=$(date -u -D %s -d $(($(date +%s) + 86400)) +%Y%m%dT000000Z)
RESULT=$(curl -s --max-time 10 -u "$CALDAV_USER:$CALDAV_PASS" \
-X REPORT -H "Depth: 1" -H "Content-Type: application/xml" \
"$CALDAV_URL" \
-d "<?xml version=\"1.0\"?>\
<c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\
<d:prop><c:calendar-data/></d:prop>\
<c:filter><c:comp-filter name=\"VCALENDAR\">\
<c:comp-filter name=\"VEVENT\">\
<c:time-range start=\"$START\" end=\"$END\"/>\
</c:comp-filter></c:comp-filter></c:filter>\
</c:calendar-query>")
if echo "$RESULT" | grep -qi "urlaub"; then
echo "ON"
else
echo "OFF"
fi
Wichtig: Der CalDAV-User braucht Leserechte auf den Kalender des Ziel-Users. Bei Grommunio:
grommunio-admin exmdb luke.skywalker@rebellion.local folder grant 0x9 \
c3po@rebellion.local foldervisible readany
0x9 ist der Store Root — ohne foldervisible dort sieht SabreDAV die Kalender-Kollektionen im PROPFIND nicht.
HA-Konfiguration
Binary Sensor (configuration.yaml)
command_line:
- binary_sensor:
name: "Urlaub Kalender"
unique_id: urlaub_kalender_caldav
command: "bash /config/check_urlaub.sh"
device_class: occupancy
payload_on: "ON"
payload_off: "OFF"
scan_interval: 900
Automation-Condition (automations.yaml)
Die Urlaubs-Prüfung kommt als erste Condition in den bestehenden Wecker:
- id: 'weekday_alarm'
alias: Set_Weekday_Alarm
triggers:
- at: input_datetime.alarm
trigger: time
conditions: []
actions:
- choose:
- conditions:
# Urlaub? → Wecker aus
- condition: not
conditions:
- condition: state
entity_id: binary_sensor.urlaub_kalender
state: 'on'
# Normaler Wochentag?
- condition: time
weekday: [mon, tue, wed, thu, fri]
# Wecker eingeschaltet?
- condition: state
entity_id: input_boolean.alarm_on_off
state: 'on'
sequence:
# ... Licht, Musik, Kaffeemaschine
Warum condition: not statt state: 'off'?
Fail-open. Wenn der CalDAV-Server nicht erreichbar ist, wird die Entity unavailable:
| Sensor-State | condition: not → on | state: 'off' |
|---|---|---|
on (Urlaub) | Wecker aus | Wecker aus |
off (kein Urlaub) | Wecker an | Wecker an |
unavailable | Wecker an | Wecker aus |
Mit state: 'off' würde ein CalDAV-Ausfall den Wecker dauerhaft stumm schalten. condition: not kehrt die Logik um: nur ein explizites on unterdrückt den Wecker. Alles andere — inklusive Fehler — lässt ihn feuern.
Faustregel: Wenn der Fehlerfall “Wecker klingelt obwohl Urlaub” vs. “Wecker schweigt obwohl Arbeitstag” ist — wähle ersteres.
Die drei Pitfalls
Pitfall 1: CalDAV Config Flow geht nicht für Cross-Account
HA hat eine CalDAV-Integration in der UI (Einstellungen → Integrationen → CalDAV). Die funktioniert — aber nur für den Kalender des authentifizierten Users.
Wenn User A den Kalender von User B lesen soll (z. B. ein Service-Account liest den Chef-Kalender), folgt die Config Flow trotzdem dem Principal von User A. Die Entity zeigt dann einen leeren Kalender.
Kein Fehler, kein Log-Eintrag. Die Entity existiert, hat 0 Events, und man sucht den Fehler woanders.
Workaround: command_line Binary Sensor mit direktem curl-CalDAV-REPORT auf die URL des Ziel-Kalenders. Umgeht die Discovery komplett.
Pitfall 2: YAML CalDAV-Platform ist deprecated (silent fail)
Die alte YAML-Variante:
calendar:
- platform: caldav
url: https://...
username: ...
password: ...
custom_calendars:
- name: "Urlaub"
calendar: "Kalender"
search: "(?i)urlaub"
wird in aktuellen HA-Versionen ohne Fehlermeldung ignoriert. config/core/check_config meldet valid. Kein Log-Eintrag. Die Entity wird nie erstellt.
Das ist besonders tückisch, weil die YAML-Platform früher Features hatte, die der Config Flow nicht bietet (custom_calendars mit search-Filter). Man konfiguriert es, startet HA neu, alles sieht OK aus — nur die Entity fehlt.
Pitfall 3: BusyBox-date im HA-Container
Home Assistant OS läuft auf Alpine Linux. Der Container hat BusyBox statt GNU coreutils. Das betrifft date:
# GNU date (funktioniert auf Debian/Ubuntu):
date -d "+1 day" +%Y%m%dT000000Z
# BusyBox date (HA Container):
date: invalid date '+1 day'
BusyBox-kompatible Alternative:
date -u -D %s -d $(($(date +%s) + 86400)) +%Y%m%dT000000Z
Betrifft alle shell_command und command_line Sensoren in HA OS.
Der Workflow
- Urlaubs-Event im Kalender eintragen (beliebiger Client — Outlook, Thunderbird, Handy)
- Warten bis der nächste 15-Minuten-Poll läuft
binary_sensor.urlaub_kalenderwechselt aufon- Wecker-Automations prüfen die Condition und schweigen
- Event endet → Sensor geht auf
off→ Wecker feuert wieder
Kein manueller Eingriff. Eine Quelle der Wahrheit.
Lessons Learned
- Fail-open schlägt fail-closed bei Weckern. Lieber einmal zu viel geweckt als verschlafen.
- CalDAV Config Flow in HA ist nicht CalDAV — sie ist eine opinionated Abstraktion. Für Cross-Account-Zugriff braucht man den Rohweg über curl.
- Silent deprecation ist schlimmer als ein Breaking Change. Fehlermeldungen helfen. Stilles Ignorieren kostet Stunden.
- Alpine/BusyBox-Kompatibilität ist ein Evergreen-Problem. Jedes Shell-Script, das im HA-Container läuft, braucht einen Test im Container, nicht auf dem Entwickler-Rechner.
Checkliste
- CalDAV-User hat Leserechte auf den Ziel-Kalender
-
check_urlaub.shim HA-Container getestet (docker exec homeassistant bash /config/check_urlaub.sh) - Binary Sensor in Developer Tools → States sichtbar und mit korrektem State
- Wecker-Automation nutzt
condition: not(fail-open) - Kalender-Event angelegt und Sensor reagiert