sunrise-or8

FHEM – Ein paar nützliche Features implementieren

Nachdem FHEM nun installiert ist und es auch ein paar Funksteckdosen gibt, die man schalten kann, soll es in diesem Beitrag darum gehen, ein paar Dinge anzulegen, die das Smart Home nun tatsächlich etwas „smart“ machen werden.

Wie bereits auf meinem Blog unter Smart Home – ein Begriff – viele Themen erwähnt, hat Smart Home bei mir nichts damit zu tun, dass ich aus der Ferne irgendwelche Dinge schalten kann. Das fällt bei mir eher unter „Fernbedienung“. Smart heißt „schlau“ und das bedeutet, das Haus oder die Wohnung weiß selbst, wann etwas ausgelöst werden muss.

Ein Zeitpunkt, an den man relativ viele Aktionen koppeln kann, ist der tägliche Sonnenauf- und -untergang. Dieser ändert sich von Tag zu Tag ein wenig. Mit einer Zeitschaltuhr kann man nur einstellen, dass etwas zu einer bestimmten Uhrzeit – z.B. abends um 20:00 Uhr – schalten soll. Im Hochsommer wäre 20:00 Uhr aber viel zu früh, im Winter wäre 20:00 Uhr viel zu spät. Zum Glück kann unser Raspi selbst ausrechnen, wann täglich für den lokalen Ort der Zeitpunkt für den Sonnenauf- und -untergang ist. Dafür benötigen wir als erstes den geografischen Ort, denn schließlich macht es einen zeitlichen Unterschied, ob der Sonnenaufgang heute in List auf Sylt, am Haldenwanger Eck, in der Gemeinde Neißeaue (bei Görlitz) oder in Isenbruch gemeint ist.

Geografischen Standort definieren

Die notwendigen Koordinaten kann man entweder mit einem GPS-System erfassen oder man benutzt einen Internet-Dienst wie beispielsweise OpenStreetMap. Falls jemand zufällig auf dem Berliner Alexanderplatz im Fernsehturm wohnt und seinem dortigen Raspi die korrekten Daten zuweisen will, dann ruft dieser die Mapnik-Karte von OpenStreetMap auf und liest aus der Adresszeile die Koordinaten ab. Wer woanders wohnt, muss natürlich vorher den Kartenausschnitt entsprechend woanders zentrieren.

OpenStreetMap-GPS

Dann definieren wir die beiden globalen Attribute Latitude und Longitude indem wir in die FHEM-Befehlszeile eingeben:

Sonnenaufgang / Sonnenuntergang berechnen

Als nächstes definieren wir einen Dummy du_Sonnenaufgang durch folgende Eingabe in der FHEM-Befehlszeile:

Und wo wir schon dabei sind auch noch einen Dummy für Sonnenuntergang:

Damit haben wir jetzt die Platzhalter (Variablen) definiert, in denen die Uhrzeit gespeichert werden wird. Da sich die Uhrzeit täglich ändert, ist es notwendig, diese Variablen auch täglich zu aktualisieren. Das erledigen wir mit einem AT-Befehl, den wir möglichst vor dem ersten möglichen Sonnenaufgang auslösen, damit auch im Hochsommer die Variable schon mit dem für den Tag aktuellen Wert gefüllt ist. Ich denke, dass es kaum den Fall geben wird, dass der Sonnenaufgang vor 00:05 Uhr eintritt (wir wohnen ja schließlich nicht nördlich des Polarkreises – da sollen sich die Norweger selbst Gedanken machen). Also legen wir den Zeitpunkt für den AT-Befehl auf genau diese Uhrzeit:

Das Sternchen vor der Uhrzeit teilt FHEM mit, dass es diesen Programmteil nicht nur einmalig um 00:05 Uhr durchlaufen soll, sondern täglich immer wieder. Die FHEM-Funktion sunrise_abs() gibt die absolute Uhrzeit des Sonnenaufgangs für den aktuellen Tag zurück. Weitere Informationen zum FHEM-Hilfsmodul Sunrise_EL findet man im Wiki von FHEM.

Nun kann man warten, bis es 5 Minuten nach Mitternacht wird, und anschließend wird in den beiden Variablen du_Sonnenaufgang und du_Sonnenuntergang unter state jeweils eine Uhrzeit stehen. Mit diesen Zeiten kann jetzt gearbeitet werden.

Man kann sich damit jetzt eine Licht-Automatik programmieren, die täglich früh das Licht zu einem festen Zeitpunkt einschaltet (da wo man aus dem Bett muss) und es zum Sonnenaufgang automatisch ausschaltet, denn dann ist es ja hell genug. Bevor man das tut, noch mal kurz nachdenken. Eventuell will man nicht immer durch das Licht geweckt werden, also ist es ganz sinnvoll, vorher noch einen Hauptschalter anzulegen, mit dem man sämtliche Lichtautomatik ein- oder ausschalten kann.

Licht-Automatik-Hauptschalter definieren

Also ein neuer Dummy namens du_Licht_Master:

Dem geben wir jetzt noch ein paar Zusatzeigenschaften.

Als erstes platzieren wir den Schalter im Raum Licht:

Als nächstes geben wir der DropDown-Liste die beiden möglichen Werte an und aus.

Dann erlauben wir nur die unter state definierten Befehle zum schalten:

Und damit es auch ein wenig schick aussieht, geben wir dem Schalter noch ein schönes Icon:

Damit sollte jetzt ein Hauptschalter im Raum Licht existieren, der so aussieht:

du_Licht_Master

Damit der auch einen schöneren Namen in der Anzeige hat, kann man mit dem Alias-Attribut auch noch einen vernünftigen Namen vergeben:

Das Ergebnis ist dann das hier:

Licht-Automatik

Gut – der Hauptschalter ist da, nun kann es an die Programmierung der Licht-Automatik selbst gehen.

Licht zu einem festen Zeitpunkt einschalten und zum Sonnenaufgang ausschalten

Damit der feste Zeitpunkt nicht gar so fest in FHEM verdrahtet ist, definieren wir auch diesen in einem Dummy, damit wir später direkt in der FHEM-Oberfläche den (festen) Zeitpunkt leicht ändern können. Das erhöht den WAF ungemein 😉 und außerdem braucht man den Wert dann nur an einer Stelle ändern und nicht möglicherweise an vielen Programmierungen.

Wir benötigen einen weiteren Dummy, der die „feste“ Uhrzeit speichert:

Jetzt sieht unser Dummy so aus:

du_Licht_an

Durch Klick auf den (rot markierten) Plus-Button öffnen sich zwei Scroll-Balken zum Einstellen der Stunden und Minuten. Will man bei Minuten etwas anderes als in 5 Minuten-Schritten einstellen, dann kann man die Uhrzeit auch direkt in das Feld eintragen.

du_Licht_an-Zeit einstellen

Durch einen weiteren Klick auf den (rot markierten) Minus-Button schließen sich die Scroll-Balken wieder und die eingestellte Uhrzeit ist übernommen.

du_Licht_an-fertig

Und nun kommt es zur Programmlogik. Ich habe mich da sehr an das FHEM-Modul DOIF gewöhnt. Man könnte es allerdings auch mit AT-Befehlen machen. Es wird nur beim Auswerten von Bedingungen schwieriger.

DOIF

Es soll zunächst erst einmal das Licht zu einem festen Zeitpunkt (04:30 Uhr) eingeschaltet, und zum Sonnenaufgang wieder ausgeschaltet werden. Also definieren wir das DOIF:

Damit wird das DOIF erst mal als leere Hülle (mit der sinnlosen Bedingung (A) ) angelegt. Das Definieren der wirklichen Bedingung macht sich wesentlich einfacher in der FHEM-Oberfläche, die jetzt so aussieht:

di_Licht_schalten

Klickt man jetzt auf den Eintrag DEF, dann öffnet sich das Editor-Fenster und man kann hier bequem seine Schaltbedingungen definieren. Das sinnlose (A) muss dabei gelöscht werden. In unserem Fall wäre die Schaltbedingung folgende:

di_Licht_schalten-Definition

Die erste Einschaltbedingung ist unser Automatik-Hauptschalter, der auf „an“ stehen muss. Die zweite Bedingung ist der „feste“ Zeitpunkt, zu dem die Lampen einschalten sollen. In der hinteren Klammer steht dann, was erfolgen soll, wenn die vorderen Bedingungen alle erfüllt sind – Lampe1 und 2 einschalten und dazwischen 5 Sekunden warten. Dann gibt es in unserem DOIF einen zweiten Zweig, der durch DOELSEIF eingeleitet wird. Hier ist wieder die erste Bedingung, das unser Automatik-Hauptschalter auf „an“ steht, die zweite Bedingung ist, dass der Zeitpunkt des Sonnenaufgangs erreicht wird. In der Klammer dahinter steht dann, das dann die Lampe1 ausgeschaltet werden soll, dann 5 Sekunden gewartet wird und dann die Lampe2 ausgeschaltet wird.

Wenn die Änderungen mit dem Button „modify di_Licht_schalten“ gespeichert wurden, brauchen wir nur noch warten, bis es 04:30 Uhr wird, und dann sollte erst die Lampe, die am Dummy du_Lampe1 hängt schalten und nach 5 Sekunden dann die, die am Dummy du_lampe2 hängt. Da hier Funkbefehle durch die Gegend geschickt werden, muss da mittels sleep 5 eine gewisse Pause (5 Sekunden) zwischen den beiden Schaltvorgängen liegen, da sonst FHEM die Schaltbefehle zwar gleichzeitig aussenden würde, die Empfänger-Steckdosen bei dem „Gebrüll“ aber beide nichts verstehen würden und daher nichts schalten würde.

Noch ein wenig Feintuning

Natürlich ist das noch etwas ausbaufähig:

  • Was passiert, wenn der Sonnenaufgang schon vorbei ist, wenn das Licht eingeschaltet werden soll?

In der jetzigen Lösung würde unser DOIF das Licht um 04:30 Uhr einschalten und es nicht mehr ausschalten, da der Sonnenaufgang bereits früher stattgefunden hat.

Um das abzufangen, kann man einen weiteren Dummy du_Tageslicht definieren, der täglich zum Sonnenaufgang mit „hell“ und zum Sonnenuntergang mit „dunkel“ gefüllt wird. Da wir den Dummy nicht selbst per Klick schalten wollen, benötigen wir hier nicht das Attribut webCmd.

Nun noch die beiden AT-Befehle, die den Dummy zum Sonnenauf- und -untergang umschalten:

Anschließend fügen wir in unser DOIF di_Licht_schalten folgendes als weitere Bedingung zum Einschalten hinzu:

so dass dann da steht:

Damit werden die Lampen nur noch angeschaltet, wenn es zum Einschaltzeitpunkt noch dunkel ist – der Sonnenaufgang also nicht schon vorbei ist.

Nur von Montags bis Freitags schalten:
  • Soll das Licht wirklich jeden Tag zu dieser Uhrzeit eingeschaltet werden (oder will man am Wochenende eventuell länger schlafen und das Licht soll aus bleiben)?

Für diese Fragestellung habe ich definiert, dass das Licht nur von Montag bis Freitag eingeschaltet werden soll. Am Samstag und Sonntag bleibt es aus. Das geht sehr elegant indem man die Definition des DOIF dahingehend ändert, dass hinter den Dummy mit der „festen“ Uhrzeit noch ein |8 gehängt wird (und um den Dummy und unser |8 noch eine eckige Klammer hinzugefügt wird). Ändert man also das DOIF so ab:

dann wir nur noch von Montag bis Freitag die Bedingung zum Einschalten erfüllt. Wer aufgepasst hat, wird bemerkt haben, dass die Ausschaltbedingung immer noch jeden Tag erfüllt ist und demnach auch am Wochenende zum Sonnenaufgang der Ausschaltbefehl durch den Äther geistert. Aber da die Steckdosen noch/schon aus sind, passiert nichts. Ja, auch hier könnte man zur Vermeidung von sinnlosem Funkverkehr noch etwas „schrauben“. Aber das kann jeder mal für sich selbst ausdenken. 😉

Hinweis: In Perl werden die Wochentage von Sonntag und 0 beginned gezählt. Daraus ergibt sich folgende Übersicht:

  • Sonntag = 0
  • Montag = 1
  • Dienstag = 2
  • Mittwoch = 3
  • Donnerstag = 4
  • Freitag = 5
  • Samstag = 6
  • Wochenende = 7
  • Wochentags = 8

Wollte man also das Licht nur am Wochenende schalten, müsste man stattdessen |7 hinter den Platzhalter der Einschaltzeit schreiben. Was dort stehen müsste, wenn es nur mittwochs schalten soll, erkennt jeder selbst!

So, das soll es erst mal gewesen sein. Bestimmt könnt ihr daraus eine Menge eigener Schaltbedingungen ableiten. Viel Erfolg!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.