Hallo, wie sicher viele hier habe ich vor mein Haus mit Smart-Home auszurüsten. Mich hat es jedoch genervt 10 verschiedene Apps für die Steuerung zu verwenden und bin nun bei OpenHAB gelandet. Erschlagen von den ganzen Möglichkeiten habe ich mich einfach hingesetzt und drauf los geschrieben. Schnell habe ich gemerkt dass ich an meine Grenzen komme und habe hier nach Hilfe gefragt. Dank der unermüdlichen Hilfe von udo1toni habe ich es endlich geschafft eine Zeitschaltuhr mit Automatikmodus und Anwesenheitserkennung zu programmieren.
In diesem HowTo möchte ich den Leuten die, so wie ich, Startschwierigkeiten haben einen kleinen Anstoß geben.
Dieses Script habe ich jetzt selber eine Zeit am laufen und funktioniert einwandfrei!
Solltet ihr Fehler finden, dann sagt mir bescheid.
Derzeit funktioniert diese Methode nur mit Android, da Apple meines Wissens die benötigten App-Funktionen nicht hat.
Was ihr benötigt:
- OpenHAB
-OpenHAB - App
- Astro-Binding
- Map Transformation
- OpenHAB Cloud
- Etwas Zeit
Fangen wir an!
Astro-Binding konfigurieren:
Zuerst solltet ihr, sofern nicht schon geschehen, das Astro-Binding in der PaperUI installieren und konfigurieren. Hierzu sucht ihr das Binding bei den Add-Ons und installiert es. Nach der Installation solltet ihr bei Configuration > Things > Astronomische Sonnendaten eure Koordinaten eingeben. Diese könnt ihr über Maps oder andere Anbieter herausfinden. Danach einfach nur Speichern.
Als nächstes erstellt ihr mit einem Editor, in meinem Fall "Visual Studio Code" eine ".things-Datei". Diese nenne ich "astro.things".
Dort müsst ihr folgenden Code eingeben:
Code: Alles auswählen
Thing astro:sun:home [ geolocation="xxx,xxx", interval=60 ]{
Channels:
Type rangeEvent : set#event[
offset=-30
]
Type rangeEvent : rise#event[
offset=-30
]
}
Thing astro:moon:home [ geolocation="52.305400,8.604877", interval=60 ]
Das Thing "astro:sun:home: ist der "Main-Trigger". Darunter stehen die Channel. In meinem Fall ein "set#event" mit einer Verschiebung von 30 Minuten. Ebenfalls habe ich noch ein "rise#event" mit einer Verschiebung von 30 Minuten. Das sind Sonnenauf- und Sonnenuntergang.
openHAB Cloud
Als nächstes müsst ihr euch das Binding "openHAB Cloud" über PaperUI installieren. Nach der Installation findet ihr in dem Ordner "openHAB-userdata" eine Datei mit dem Namen "UUID". Diese öffnet ihr und speichert den Code in einem Text-Dokument.
Danach müsst ihr wieder in "openHAB-userdata > openhabcloud" da findet ihr eine "secret"-Datei. Diese öffnet ihr ebenfalls wieder und Speichert den Code in der Text-Datei.
Als nächstes müsst ihr euch bei https://myopenhab.org registrieren. Nach der Registrierung solltet ihr direkt aufgefordert werden, den Code der UUID und den Code vom Secret einzugeben. Nachdem ihr das gemacht und gespeichert habt, sollte kurze Zeit später oben links das Feld von "Offline" zu "Online" wechseln. Ist dies nicht der Fall müsst ihr euer OpenHAB einmal neustarten.
OpenHAB-App
Nun solltet ihr euch um die OpenHAB - App kümmern. Dazu müsst ihr in den Einstellungen der App auf den Reiter "Lokal" gehen. Dort müsst ihr die IP eures OpenHAB eingeben. Wichtig ist hierbei auch der Port "8080" am Ende.
Danach müsst ihr in den Reiter "Fernzugriff" wechseln. Dort gebt ihr unter "Server-URL für Fernzugriff" die IP-Adresse "https://myopenhab.org" ein. Bei Benutzername und Passwort gebt ihr die Daten von dem eben erstellten Account ein.
Map-Transformation
Dieses Binding soll später dafür sorgen, dass in unserer Sitemap nicht mehr "ON oder OFF" als Anwesenheitsstatus angezeigt wird, sondern im besten Fall "Anwesend oder Abwesend". Nachdem ihr dieses Binding installiert habt, müsst ihr über einen Editor in dem Ordner "openhab-config > transform" eine .map-Datei erstellen. Ich nenne sie "anwesenheit.map". Dort schreibt ihr folgendes rein:
Code: Alles auswählen
ON=Zuhause
OFF=Unterwegs
NULL=Undefiniert
Ab jetzt müssen wir schreiben:
Zunächst erstelle ich eine "anwesenheit.items" -Datei. Diese Datei sieht wie folgt aus:
Code: Alles auswählen
String WLAN_Handy1 "WLAN [%s]"
String WLAN_Handy2 "WLAN [%s]"
Switch Handy1 "Test1 ist [MAP(anwesenheit.map):%s]" <motion> ["Switchable"]
Switch Handy2 "Test2 ist [MAP(anwesenheit.map):%s]" <motion> ["Switchable"]
Switch Anwesend "[MAP(anwesenheit.map):%s]"
Die Schalter "Handy1 und Handy2" sind später unsere Anzeige in der Sitemap. Hier wird als Text der Schalter durch das "Map-Transformation" - Binding von "ON" zu "Anwedend" übersetzt.
Den Switch "Anwesend" benötigen wir, wenn wir mehr als ein Handy haben. So muss nicht ständig beide Handys für eine Rule abgefragt werden.
Als nächstes erstellen wir uns eine "anwesenheit.rules"-Datei. Diese ist in zwei Bereiche eingeteilt:
Bereich 1:
Code: Alles auswählen
var Timer timer1
var Timer timer2
rule "Abwesenheit Test1"
when
Item WLAN_Handy1 changed
then
logInfo("Anwesenheit", "Rule getriggert. WLAN_Handy1 Status: {}",WLAN_Handy1.state)
if(WLAN_Handy1.state.toString != "DEINE WLAN-SSID"){
timer1 = createTimer(now.plusSeconds(15), [|
if(WLAN_Handy1.state.toString != "DEINE WLAN-SSID"){
Handy1.postUpdate(OFF)
logInfo("Anwesneheit", "Test1 ist unterwegs!")
}
])
}else {
logInfo("Anwesenheit", "Test1 ist Zuhause!")
Handy1.postUpdate(ON)
}
end
rule "Anwesenheit Test2"
when
Item WLAN_Handy2 changed
then
if(WLAN_Handy2.state.toString != "DEINE WLAN-SSID"){
timer2 = createTimer(now.plusSeconds(15), [|
if(WLAN_Handy2.state.toString != "DEINE WLAN-SSID"){
Handy2.postUpdate(OFF)
logInfo("Anwesenheit", "Test2 ist unterwegs!")
}
])
}else {
logInfo("Anwesenheit", "Test2 ist zuhause!")
Handy2.postUpdate(OFF)
}
end
Wir prüfen zunächst ob sich das Item "WLAN_Handy1" geändert hat. (Zum Beispiel, weil die WLAN-SSID geändert wurde. Ist das passiert, wird geprüft, ob die SSID nun nicht mehr die SSID von dem Heimnetzwerk ist. Ist diese nun eine andere SSID, wird ein Timer gesetzt und 15 Sekunden gewartet. Nach Ablauf dieser 15 Sekunden wird nochmal geprüft ob das Handy immer noch aus dem WLAN ausgeloggt ist. Ist das der Fall, dann wird der Schalter "Handy1" ausgeschaltet, also "Abwesend".
Den Timer habe ich eingebaut, da sich mein Handy ab und zu auf meinem WLAN ausloggt. Das ist abhängig davon, wo ich mich im Haus befinde. Da ich aber nicht möchte dass ich im dunkeln stehe, nur weil mein Handy sich kurz ausgeloggt hat, soll zur Sicherheit nochmal 15 Sekunden gewartet werden.
Wenn wir nun nach Hause kommen und die SSID von unserem Handy die selbe SSID wir in der Rule hat, dann wird der Schalter "Handy1" auf "ON" gesetzt, also "Anwesend".
WICHTIG: In der Rule müsst ihr bei "DEINE WLAN-SSID" den Namen von eurem WLAN eingeben!
Der nächste Schritt ist wichtig, wenn man mehr als ein Handy hat
Code: Alles auswählen
rule "Anwesenheit umschalten"
when
Item Handy1 changed or
Item Handy2 changed
then
if(Handy1.state == OFF && Handy2.state == OFF){
Anwesend.postUpdate(OFF)
} else {
Anwesend.postUpdate(ON)
}
end
Als nächsten Schritt erstellen wir eine "beleuchtung.items"-Datei. In diese Datei müssen folgende Items
Code: Alles auswählen
Number Light1_Timer_On "Einschaltzeit Licht 1"
Number Light1_Timer_Off "Ausschaltzeiten Licht 1"
Number Light2_Timer_On "Einschaltzeiten Licht 2"
Number Light2_Timer_Off "Ausschaltzeiten Licht 2"
Switch Sunset "Sonnenuntergang"
Der Switch "Sunset" wird gebraucht damit die nachfolgende Rule erkennt, wenn Sonnenuntergang ist/war.
Info: Um die Übersicht in eurem Script nicht zu verlieren, solltet ihr die Namen der Items nach eurem belieben ändern.
Danach erstellen wir eine "beleuchtung.rules"-Datei. Diese bauen wir in verschiedenen Abschnitten auf, damit es nicht zu unübersichtlich wird.
Erster Abschnitt
Code: Alles auswählen
rule "Sonnenuntergang"
when
Channel 'astro:sun:home:set#event' triggered START
then
Sunset.postUpdate(ON)
end
rule "Sonnenaufgang"
when
Channel 'astro:sun:home:rise#event' triggered START
then
Sunset.postUpdate(OFF)
end
Selbes machen wir auch für den Sonnenaufgang. Hier wird der Schalter "Sunset" wieder ausgeschaltet.
Zweiter Abschnitt
Code: Alles auswählen
rule "Zeitschaltuhr"
when
Time cron "0 00 17-20 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
Time cron "0 00 21-23 * * ?" or //täglich um 21, 22 und 23 Uhr
Item Sunset changed to ON or
Item Light1_Timer_On changed or
Item Light1_Timer_Off changed or
Item Light2_Timer_On changed or
Item Light2_Timer_Off changed or
Item Anwesend changed
then
val Sl1_OnSel = if(Light1_Timer_On.state instanceof Number) (Light1_Timer_On.state as Number) else 0
val Sl1_OffSel = if(Light1_Timer_Off.state instanceof Number) (Light1_Timer_Off.state as Number) else 0
val Lc_OnSel = if(Light2_Timer_On.state instanceof Number) (Light2_Timer_On.state as Number) else 0
val Lc_OffSel = if(Light2_Timer_Off.state instanceof Number) (Light2_Timer_Off.state as Number) else 0
var Sl = OFF
var Lc = OFF
if(Anwesend.state == ON){
if(Sl1_OnSel == 0)
if(Sunset.state == ON) Sl = ON
else if(now.getHourOfDay > (15 + Sl1_OnSel)) Sl = ON
if(now.getHourOfDay > (19 + Sl1_OffSel) || now.getHourOfDay < 15) Sl = OFF
if(Lc_OnSel == 0)
if(Sunset.state == ON) Lc = ON
else if(now.getHourOfDay > (15 + Lc_OnSel)) Lc = ON
if(now.getHourOfDay > (19 + Lc_OffSel) || now.getHourOfDay < 15) Lc = OFF
} else {
Lc = OFF
Sl = OFF
}
if(Sl != "Eure Lampe".getStateAs(OnOffType)) "Eure Lampe".sendCommand(Sl)
if(Lc != "Eure Lampe".getStateAs(OnOffType)) "Eure Lampe".sendCommand(Lc)
end
Ich erkläre es Abschnitt für Abschnitt.
Code: Alles auswählen
when
Time cron "0 00 17-20 * * ?" or //täglich um 17, 18, 19 und 20 Uhr
Time cron "0 00 21-23 * * ?" or //täglich um 21, 22 und 23 Uhr
Item Sunset changed to ON or
Item Light1_Timer_On changed or
Item Light1_Timer_Off changed or
Item Light2_Timer_On changed or
Item Light2_Timer_Off changed or
Item Anwesend changed
Dann soll noch getriggert werden, wenn sich einer der Items verändert.
Code: Alles auswählen
val Sl1_OnSel = if(Light1_Timer_On.state instanceof Number) (Light1_Timer_On.state as Number) else 0
val Sl1_OffSel = if(Light1_Timer_Off.state instanceof Number) (Light1_Timer_Off.state as Number) else 0
val Lc_OnSel = if(Light2_Timer_On.state instanceof Number) (Light2_Timer_On.state as Number) else 0
val Lc_OffSel = if(Light2_Timer_Off.state instanceof Number) (Light2_Timer_Off.state as Number) else 0
var Sl = OFF
var Lc = OFF
Code: Alles auswählen
if(Anwesend.state == ON){
if(Sl1_OnSel == 0)
if(Sunset.state == ON) Sl = ON
end
Code: Alles auswählen
else if(now.getHourOfDay > (15 + Sl1_OnSel)) Sl = ON
if(now.getHourOfDay > (19 + Sl1_OffSel) || now.getHourOfDay < 15) Sl = OFF
Hier wird die Stunde des Tages + den Schalterzustand der Zeitschaltuhr genommen. Steht der Schalter z.B. auf ein, dann ergibt das 16 Uhr. Da wir aber auf das überschreiten von 16 Uhr triggern, ergibt das 17 Uhr. Also wird um 17 Uhr das Licht eingeschaltet.
Selbes gilt für das Ausschalten!
Das wiederholt sich nochmal, für die zweite Lampe. Das kann auf mehrere Lampen ausgeweitet werden.
WICHTIG: Bei "Eure Lampe" muss der Name der Lampe die ihr einschalten wollt gesetzt werden.
Die Sitemap
Damit ihr später auch eine Uhrzeit auswählen könnt, müsst ihr noch die Items in die Sitemap einbinden.
Ich habe dafür ein Untermenü bei meinen Lampen angelegt. Darin werden dann meine Items erscheinen.
Code: Alles auswählen
Selection item=Light1_Timer_On label="Einschaltzeiten Licht 1" mappings=[-1="Aus",0="Sonnenuntergang",1="17:00 Uhr",2="18:00 Uhr",3="19:00 Uhr",4="20:00 Uhr"]
Selection item=Light1_Timer_Off label="Ausschaltzeiten Licht 1" mappings=[-1="Aus",1="21:00 Uhr",2="22:00 Uhr",3="23:00 Uhr",4="24:00 Uhr"]
Selection item=Light2_Timer_On label="Einschaltzeiten Licht 2" mappings=[-1="Aus",0="Sonnenuntergang",1="17:00 Uhr",2="18:00 Uhr",3="19:00 Uhr",4="20:00 Uhr"]
Selection item=Light2_Timer_Off label="Ausschaltzeiten Licht 2" mappings=[-1="Aus",1="21:00 Uhr",2="22:00 Uhr",3="23:00 Uhr",4="24:00 Uhr"]
Der letzte Schritt
Damit das alles nun funktioniert, müsst ihr nochmal in eure OpenHAB-App. Dort müsst ihr in den Einstellungen zu "Geräteinformationen an Server senden" gehen. Dort müsst ihr die "Ereignisüberwachung" aktivieren. Danach müsst ihr bei "WLAN-Name" das Item "WLAN_Handy1" oder "WLAN_Handy2" eingeben.
WICHTIG: Damit das alles funktioniert müsst ihr den Standort aktivieren und diesen auch für die App-Freigeben.
Danach alles speichern und im OpenHAB-Log auf Fehler prüfen.
Jetzt sollte alles funktionieren!
Viel Spaß mit der neuen Funktion!