Einbindung des eigenen Google Kalender
In Zeiten des Smartphones nutzen auch sehr viele die integrierte Terminverwaltung. Hierzu gibt es mehrere Varianten, die Termine zu pflegen. Sobald man nicht nur das Smartphone zur Terminverwaltung nutzt, sondern noch ein Tablet oder einen PC, so macht es Sinn, die Termine zentral zu verwalten. Hierzu nutze ich den Google Kalender, da die Einbindung in beinahe alle Applikationen problemlos möglich ist.
In Verbindung mit der Haussteuerung FHEM ist es ein Leichtes, den Google Kalender einzubinden.
Was ist das Ziel?
Über die Einbindung des Google Kalender wollen wir in FHEM eine oder mehrere Dummyvariablen setzen. Beispielsweise wollen wir eine Variable für „Urlaub“ setzen. Aufgrund eines Termineintrags im Google Kalender geht die Variable Urlaub_dummy
von nein
auf ja
. Nun könnte man aufgrund der Änderung dieser Variable verschiedene Aktionen auslösen. Dementsprechend könnten wir im Winter die Heizkörper im Hobbyraum für diesen Tag einschalten oder die Medienzentrale im Wohnzimmer schon am Vormittag einschalten anstatt abends.
Hard-und Software-Voraussetzungen
Zuerst brauchen wir einen Raspberry Pi mit entsprechendem Netzteil. Hierzu habe ich auch entsprechende Empfehlungen gegeben.
Genauso sollte man sich über die Vernetzung Gedanken machen, ob man die Raspberry Pis per Netzkabel oder per WLAN anbinden möchte. Dafür habe ich hier in meinen Artikeln über die Grundkonfiguration Tipps gegeben:
- Checkliste für Raspberry Pi mit FHEM
- Raspberry Pi Grundkonfiguration
- FHEM Grundkonfiguration
- CUL Integration in FHEM
Einrichtung des Google Kalenders
Wir wollen unseren Google Kalender in FHEM integrieren. Oftmals ist es aber sinnvoll einen zweiten Google Kalender zu benutzen, um die Termine für die Haussteuerung von normalen Terminen zu unterscheiden. Das ist wirklich ganz einfach:
Man meldet sich bei Google über sein Profil an. Falls noch nicht vorhanden, erstellt man ein eigenes Profil. Anschließend ruft man den Online-Kalender auf. Dort erstellen wir einen eigenen Kalender namens „Haussteuerung„.
In vielen Beschreibungen der Einbindung wird empfohlen, den Kalender einfach öffentlich zu machen, damit die Haussteuerung auch darauf problemlos zugreifen kann. Das mag ja einfach sein, aber „öffentlich“ heißt nunmal, dass auch jeder diesen Kalender lesen könnte. Deswegen nie das Häkchen setzen bei „Diesen Kalender öffentlich machen„:
Nun drücken wir noch auf „Kalender erstellen“ und haben hiermit den Kalender angelegt. Wir müssen uns jetzt noch die Kalender-ID besorgen. Diese finden wir bei den Details unter „Privatadresse“.
Drücken wir auf den grünen „ICAL
„-Button, öffnet sich ein Fenster mit der URL, die wir uns in den Zwischenspeicher kopieren sollten.
Einbinden des Google Kalenders in FHEM
Im Folgenden müssen wir mit ein paar wenigen Einträgen in der Konfigurationsdatei fhem.cfg
den gerade erzeugen Kalender einbinden. Das funktioniert mit zwei Zeilen Code:
define Kalender_Haussteuerung Calendar ical url link-aus-zwischenspeicher 14400 attr Kalender_Haussteuerung room Kalender
In dem Beispiel müssen wir nur noch die https
-URL mit der eben kopierten für link-aus-zwischenspeicher
ersetzen und den Wert von 14400 stehen lassen. Dieser Wert sorgt dafür, dass der Kalender alle 4 h (= 14400 Sekunden) eingelesen wird.
Testen durch einen Google Kalender Eintrag
Als Erstes probieren wir die Integration unseres Haussteuerungs-Kalenders mit einem Test-Termin aus. Nun sollten wir den neuen Kalender schon in unserem Smartphone sehen.
Wir tragen entweder direkt auf der Google-Kalender-Seite oder am Smartphone einen Testtermin in unserem Haussteuerungskalender ein. Da wir die Prüfung nur alle 4h machen, zwingen wir FHEM zu einem erneuten Laden unseres Kalender. Dazu klicken wir auf der FHEM-Webseite auf unsere neue Rubrik Kalender und dann auf Kalender_Haussteuerung
.
Dort drücken wir für set Kalender_Haussteuerung reload auf den Set-Button. Anschließend sollte sich in den Readings unterhalb des Kalenders etwas tun:
Infolge des Kalendereintrags und des Neuladens des Kalenders sind vercodete Einträge in den Readings entstanden. Das zeigt uns, dass die Integration funktioniert.
Weiters löschen wir den Testeintrag wieder und erstellen nun einen Eintrag namens „Urlaub
„. Wichtig ist, dass der Termin nicht als Ganztageseintrag erstellt wir, sondern ein definiertes Beginn- und Endedatum haben muss. Also z.B. 07:00 Uhr bis 19:00 Uhr.
Dummyvariablen erzeugen
Damit wir hier auf die Kalendereinträge reagieren können, brauchen wir mindestens eine Dummyvariable. In unserem Beispiel wollen wir auf den Kalendertext „Urlaub“ checken. Dementsprechend legen wir eine Variable Urlaub_dummy
an:
define Urlaub_dummy dummy attr Urlaub_dummy alias Urlaubstag attr Urlaub_dummy devStateIcon ja:rc_dot@green nein:rc_dot@grey attr Urlaub_dummy icon weather_summer attr Urlaub_dummy room Kalender attr Urlaub_dummy setList ja nein attr Urlaub_dummy webCmd ja:nein
Durch diesen Eintrag können wir später entscheiden, ob ein Urlaubstag ist (=ja
) oder nicht (=nein
)
Hilfsfunktionen
Damit das Schalten der Dummyvariable nun über den Eintrag in den Online-Kalender funktioniert, brauchen wir zwei Hilfsfunktionen. Zum Einen müssen wir feststellen, ob das Ereignis aufgrund des Kalendertexts für unsere Dummyvariable relevant ist oder nicht. Zum Anderen gibt es prinzipiell drei Events, die in FHEM überwacht werden müssen: Der Start, das Ende und das Löschen eines Termins. Zunächst kümmern wir uns um die benötigten Funktionen.
Hierzu erstellen wir ein neues Include, das wir im Verzeichnis /opt/fhem/FHEM
erstellen. Dementsprechend kopieren wir uns den unten aufgelisteten Code in eine leere Datei namens 99_GoogleCalendarUtils.pm
. Hierfür können wir den kleinen Editor nano
benutzen und die neue Datei mit
cd /opt/fhem/FHEM nano 99_GoogleCalendarUtils.pm
erstellen. Weiters kopieren wir den unten stehenden Code in den geöffneten Editor und speichern ihn mit STRG
+O
ab. Schließlich beenden wir den Editor mit STRG
+X
.
Im Anschluß der Code:
############################################## # $Id: 99_GoogleCalendarUtils.pm 2691 2016-12-31 martin koch $ package main; use strict; use warnings; use Digest::MD5 "md5_hex"; use HttpUtils; sub GoogleCalendarUtils_Initialize($$) { my ($hash) = @_; } sub Kalenderstart ($) { my ($Ereignis) = @_; my @Ereignisarray = (); my $Ereignisteil1 = ""; my @uids = (); @Ereignisarray = split(/.*:\s/,$Ereignis); if($#Ereignisarray > 0) { $Ereignisteil1 = $Ereignisarray[1]; @uids=split(/;/,$Ereignisteil1); Log 3,"Termin fängt an"; foreach my $uid (@uids) { my $Kalendertext = fhem("get Kalender_Haussteuerung summary $uid"); Log 3,"uid = $uid, Text = $Kalendertext"; if ($Kalendertext =~ /Urlaub/) { fhem("set Urlaub_dummy ja"); Log 3,"Urlaub found"; } } } } sub Kalenderende ($) { my ($Ereignis) = @_; my @Ereignisarray = (); my $Ereignisteil1 = ""; my @uids = (); @Ereignisarray = split(/.*:\s/,$Ereignis); if($#Ereignisarray > 0) { $Ereignisteil1 = $Ereignisarray[1]; @uids=split(/;/,$Ereignisteil1); Log 3,"Termin wurde beendet oder gelöscht"; foreach my $uid (@uids) { my $Kalendertext = fhem("get Kalender_Haussteuerung summary $uid"); if ($Kalendertext =~ /Urlaub/) { fhem("set Urlaub_dummy nein"); } } } } 1;
Dummyvariablen schalten
Nun müssen wir nur noch in der Konfigurationsdatei fhem.cfg die Hilfsfunktionen bei Kalenderänderungen antriggern. Das geht ganz einfach mit folgenden drei Notify-Definitionen:
define Kalender_Haussteuerung_Start notify Kalender_Haussteuerung:modeStarted.* {\ Kalenderstart("$EVENT");;\ } define Kalender_Haussteuerung_Ende notify Kalender_Haussteuerung:modeEnded.* {\ Kalenderende("$EVENT");;\ } define Kalender_Haussteuerung_Loeschen notify Kalender_Haussteuerung:stateDeleted.* {\ Kalenderende("$EVENT");;\ }
Diese drei Definitionen sorgen nun dafür, dass zu Beginn, Ablauf und Löschen eines Termins in unserem Google-Kalender Haussteuerung
die gerade gezeigten Hilfsfunktionen aufgerufen werden. Passt dort der Kalendertext mit „Urlaub
“ überein, so wird die Dummyvariable Urlaub_dummy auf „ja
“ gesetzt. Sobald der Termin endet, wird die Variable auf „nein
“ gesetzt.
Kalenderintegration für Urlaub final testen
Nachdem wir uns nun einen neuen Eintrag in unserem Google-Kalender „Haussteuerung
“ unter dem Namen „Urlaub
“ erstellt haben, zwingen wir unser FHEM zu einem Neuladen des Kalenders wie oben beschrieben. (set Kalender_Haussteuerung reload
). Hierzu sollte der Termin in der Zukunft (für den Test reichen 5 Minuten) sein, da das Schalten sonst nicht ordnungsgemäß funktioniert.
Sobald nun der Termin beginnt, ruft FHEM die Hilfsmethoden auf und setzt die Variable „Urlaub_dummy
“ auf „ja
„.
Was sind die Grenzen?
Was nicht funktioniert ist, dass man beispielsweise einen Vorlauf vor einem solchen Termin einstellt. Da eine Heizung in der Regel einige Zeit braucht, um einen Raum aufzuwärmen, würden wir die Heizung gerne um eine Stunde früher einschalten als ein Termineintrag „Arbeit“ im Google Kalender aussagen würde. Leider triggert der Google Kalender exakt zum Beginn eines Termins „Arbeit“, so dass das mit diesem Modul nicht ohne weiteres möglich ist. Deswegen prüfe ich nicht nur nach einem Ereignis, sondern noch nach dem Termineintrag „Heizung“. Man benötigt zwar einen zusätzlichen Eintrag „Heizung“ im Kalender, diesen kann man aber immer wieder verschieben, auch aus der Vergangenheit. Man braucht ja den alten Termineintrag nicht mehr, also verschiebt man ihn dorthin, wo das Ereignis „Heizung“ den Dummy für die Heizung schalten soll.