openHAB :: Präsenzerkennung via Bluetooth und Ping
In vielen denkbaren Szenarien macht es Sinn, dass unsere openHAB-Instanz weiß, dass jemand zuhause ist und vielleicht auch wer im Einzelnen. Denkbar wäre das Einschalten von bestimmten Geräten nach einer Heimkehr eines Bewohners. Zudem können nicht benötigte Geräte ausgeschaltet werden, wenn niemand anwesend ist und diese somit nicht unnötig Strom verbrauchen. In diesem Artikel zeigen wir, wie wir die Präsenz eines Bewohners mittels WLAN und Bluetooth ermitteln und situationsabhängig Schaltungen durchführen können.
Verfügbare Artikel zu openHAB
Präsenzerkennung mittels Bluetooth
Einrichtung auf dem Raspberry Pi
Auf unserem Raspberry Pi, welcher mit der IP-Adresse „192.168.23.235“ konfiguriert wurde, haben wir zunächst alle Schritte aus dieser Anleitung ausgeführt und sind in der Lage, lokal vom Raspberry Pi aus Bluetooth Endgeräte mittels L2-Ping zu erreichen. Alternativ kann der Bluetooth-Stick auch am openHAB-Server selbst betrieben werden, wenn bei diesem ein Anschließen von USB-Geräten möglich ist.
Ist der Betrieb des Bluetooth-Adapters sichergestellt, erstellen wir nun auf dem Raspberry ein Bash-Script mit folgendem Inhalt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/bash #1=Daniel, 2=Tina case $1 in 1) MAC="33:44:55:66:77:88" ;; 2) MAC="11:22:33:44:55:66" ;; esac if /usr/bin/l2ping -c 1 $MAC &> /dev/null then echo "ON" else echo "OFF" fi |
Das Script könnte nun bereits auf dem Raspberry per Hand gestartet werden. Dazu müssen lediglich zuvor alle notwendigen Bluetooth-MAC-Adressen im Script hinterlegt und die zu prüfende Nummer als Parameter beim Starten des Scripts übergeben werden. Als Beispiel möchte ich die Präsenz von Tinas Mobilfunktelefon feststellen:
1 |
/scripts/bt.sh 2 |
Hier scheint wohl entweder:
- Tina nicht zuhause zu sein
- Auf Tinas Mobilfunktelefon ist Bluetooth nicht aktiviert
- Beim Einrichten gemäß dieser Anleitung ist etwas schief gelaufen
Einrichtung auf dem openHAB-Server
Wie auch bei vielen anderen hier zu findenden openHAB-Anleitungen benötigen wir hierbei jeweils ein Script auf dem Raspberry sowie auch auf dem openHAB-Server. Das erstere wurde an diesem Punkt der Anleitung bereits umgesetzt, widmen wir uns also dem Bash-Script auf dem Server. Dies gestaltet sich etwas weniger umfangreich mit folgenden Zeilen des neuen Scripts „/scripts/bt.sh„:
1 2 |
#!/bin/bash /usr/bin/ssh -i /scripts/.ssh/id_rsa root@192.168.23.235 "/scripts/bt.sh $1" |
Wir erlauben die Ausführung des Scripts durch
1 |
chmod +x /scripts/bt.sh |
und übertragen den Besitz an „openhab“ durch
1 |
chown openhab: /scripts/bt.sh |
Dieses Script bewirkt nur, dass das Script auf der Himbeere remote via SSH ausgeführt wird. Ein Test vom openHAB-Server aus sollte das gleiche Ergebnis wie auf dem Raspberry selbst liefern:
1 |
/scripts/bt.sh 2 |
Das Item definieren
Nun erstellen wir für die beiden Smartphones unseres Beispielszenarios zwei entsprechende Item-Definitionen in der passenden Konfigurationsdatei von openHAB:
1 2 3 |
//Mobilfunktelefone Switch MOB188_BT "Handy Daniel" (grp_PRAESENZ) { exec="<[/scripts/bt.sh 1:60000:REGEX((.*?))]" } Switch MOB137_BT "Handy Tina" (grp_PRAESENZ) { exec="<[/scripts/bt.sh 2:60000:REGEX((.*?))]" } |
Auch in diesem Fall nutzen wir erneut das Addon „exec„, welches wir mittels
1 |
apt-get install openhab-addon-binding-exec |
installieren.
Integration in die Sitemap
Anschließend können diese Items bereits in die Sitemap eingefügt werden:
1 2 3 4 |
Frame label="Mobilfunktelefone" icon="network" { Text item=MOB188_BT label="Handy Daniel [MAP(praesenz.map):%s]" icon="present" Text item=MOB137_BT label="Handy Tina [MAP(praesenz.map):%s]" icon="present" } |
Das hier konfigurierten Symbole „present“ und „network“ müssen ebenfalls zuvor bereitgestellt werden, indem sie in den Ordner „/usr/share/openhab/webapps/images/“ kopiert werden. Die Einbindung an dieser Stelle macht jedoch noch wenig Sinn, am Ende des Artikels wird die Einbindung einer Präsenzerkennung gezeigt, die jedes Gerät auf mehrfache Arten auf eine Anwesenheit prüft.
Ausgabe übersetzen
Die dazugehörige Übersetzungsdatei „praesenz.map“ umfasst folgenden Inhalt:
1 2 3 4 |
ON=Anwesend OFF=Abwesend undefined=unbekannt -=unbekannt |
Präsenzerkennung mittels WLAN
Die Network-Health Items definieren
Leider gibt es zur Zeit Probleme bei der Art und Weise, wie Java als nicht priviligierter Benutzer die Erreichbarkeit via TCP/IP prüft.
Daher nutzen wir in dieser Anleitung nicht das Addon „network-health„, was naheliegend wäre, sondern erstellen ein eigenes Script.
Für die Prüfung der Erreichbarkeit eines Netzwerkteilnehmers erstellen wir uns ein neues, kleines Bash-Script: „/scripts/ping.sh“
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/bin/bash if [ -z "$1" ] ;then echo "So geht das nicht" exit 1; fi ping -c1 $1 > /dev/null if [ $? -ne 0 ]; then echo "OFF" else echo "ON" fi |
Wir erlauben die Ausführung des Scripts durch
1 |
chmod +x /scripts/ping.sh |
und übertragen den Besitz an „openhab“ durch
1 |
chown openhab: /scripts/ping.sh |
Nun definieren wir die entsprechenden Items wie folgt:
1 2 |
Switch MOB188_WLAN "Handy Daniel" (grpAW_PRAESENZ) { exec="<[/scripts/ping.sh 192.168.1.188:60000:REGEX((.*?))]" } Switch MOB137_WLAN "Handy Tina" (grpAW_PRAESENZ) { exec="<[/scripts/ping.sh 192.168.1.137:60000:REGEX((.*?))]" } |
Kombinierte Präsenzerkennung
Nun sind wir an einem Punkt angelangt, an dem wir feststellen können, ob ein Smartphone via Bluetooth oder WLAN erreichbar ist. Jetzt wäre es aber sinnvoll, diese beiden Informationen für jedes Gerät zu kombinieren, um mit zwei Methoden die Präsenz eines Geräts festzustellen. Dazu führen wir die beiden Werte in ein neues Item zusammen.
Dummy-Item definieren
Dazu benötigen wir zunächst ein sogenanntes Dummy-Item, das nur innerhalb von openHAB existiert und von außen weder geschaltet noch dessen Wert verändert wird:
1 2 3 |
//Mobilfunktelefone Switch MOB188 "Handy Daniel" Switch MOB137 "Handy Tina" |
Doch wenn nicht durch eine Änderung eines externen Zustandes, wie kann dieses Item nun „geschaltet“ werden?
Zusammenführende Regeln erstellen
Dazu erstellen wir uns Regeln, die beispielsweise das Item „MOB188“ auf „ON“ setzen, wenn entweder das Item „MOB188_WLAN“ oder „MOB188_BT“ aktiv ist. Anders ausgedrückt reicht es, wenn das Smartphone entweder per WLAN oder Bluetooth erreichbar ist. Dann wird das Dummy-Item „MOB188“ ebenfalls auf „ON“ gesetzt. Andersherum wird das Item „MOB188“ auf „OFF“ gesetzt wenn das Smartphone weder per WLAN noch via Bluetooth erreicht werden konnte.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
rule "Daniel ist Zuhause" when Item MOB188_WLAN changed to ON or Item MOB188_BT changed to ON then postUpdate(MOB188, ON) end rule "Daniel ist nicht mehr Zuhause" when Item MOB188_WLAN changed to OFF or Item MOB188_BT changed to OFF then if(MOB188_WLAN.state == OFF && MOB188_BT.state == OFF) { postUpdate(MOB188, OFF) } end |
Noch mehr kombinieren
Dieser Schritt lässt sich natürlich wiederholen und es sind Verschachtelungen in unendlicher Tiefe möglich, zumindest so tief, wie man es selbst noch überblicken kann:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
rule "Irgendjemand ist zuhause" when Item MOB188 changed to ON or Item MOB137 changed to ON then postUpdate(PRAESENZ, ON) sendCommand(SPRINGBRUNNEN, ON) end rule "Niemand ist mehr zuhause" when Item MOB188 changed to OFF or Item MOB137 changed to OFF then if(MOB188.state == OFF && MOB137.state == OFF) { postUpdate(PRAESENZ, OFF) sendCommand(SPRINGBRUNNEN, OFF) } end |
In diesem Beispiel wurde zuvor ein weiteres Dummy-Item definiert:
1 |
Switch PRAESENZ |
Diese beiden Regeln aktualisieren das Item „PRAESENZ“ je nach dem, ob eins der beiden vorhandenen Mobilfunktelefone anwesend ist oder nicht. Zudem wird bei einer festgestellten Präsenz einer der beiden beispielhaften Personen der Springbrunnen ein- und bei Abwesenheit aller Personen wieder ausgeschaltet.
Darstellung in der Sitemap
Die beiden Mobilfunktelefone dieser Anleitung binden wir nun in Form der kombinierten Präsenzermittlung wie folgt in die Sitemap ein:
1 2 3 4 |
Frame label="Mobilfunktelefone" icon="network" { Text item=MOB188 label="Handy Daniel [MAP(praesenz.map):%s]" icon="present" Text item=MOB137 label="Handy Tina [MAP(praesenz.map):%s]" icon="present" } |
Dies wird nun so oder so ähnlich dargestellt:
OpenHAB and Bluetooth Presence Detection | BigTrak Arduino Radio Controlled (BARC)
15.02.2019 @ 12:34
[…] install the Bluetooth presence detection shell script using l2ping as described here https://klenzel.de/3328#Praesenzerkennung_mittels_Bluetooth […]
Jürgen Baginski
17.02.2016 @ 16:48
Kann da jemand Gedanken lesen?
Den Rest des letzten Abends habe ich vergeblich versucht mich per SonosBox zu begrüßen.
Danke für den Tipp
Daniel Wenzel
16.02.2016 @ 20:42
Vielleicht liegt es daran, dass dein Script anstatt „ON“ und „OFF“, „On“ und „Off“ zurückgibt. Möglicherweise erkennt OpenHAB das nicht als Switch. In einen String kannst du an Werten schmeißen, was du möchtest ;)
Für eine weitere Verwendung in Regeln würde ich aber schauen, dass ich das Item als Switch zum Laufen bekomme.
Jürgen Baginski
16.02.2016 @ 20:20
Problem gelöst!
Mit String geht es!
String MeinPhoneSwitch „Handy Juergen“ (MeineGruppe) { exec=“<[configurations/scripts/ping.sh 192.168.178.25:60000:REGEX((.*?))]" }
Jürgen Baginski
16.02.2016 @ 19:00
Moin,
erstmal Danke für die sehr hilfreichen openHAB-Artikel.
Ich versuche mich an der Präsenzerkennung per WLAN. Zum einen funktionert der EXEC-Aufruf bei mir nur wenn ich das erstellte Script mit dem Pfad „configurations/scripts/ping.sh“ aufrufe.
Rufe ich das Script direkt auf, liefert es „On“ oder „Off“. Aufgerufen aus openHAB steht im Log „MeinPhoneSwitch state updated to ON“ bzw. „…OFF“. Ergo scheint das Script richtig zu laufen.
Leider bekomme ich auf dem GUI keine richtige Rückmeldung.
Mein Item sieht so aus
Switch MeinPhoneSwitch „Handy Juergen“ (MeineGruppe) { exec=“<[configurations/scripts/ping.sh 192.168.178.25:60000:REGEX((.*?))]" }
Der Switch belibt immer in OFF.
Auf der Sitemap versuche ich es so:
Frame label=“Handys“ icon=“network“ {
Text item=MeinPhoneSwitch label=“Juergen Handy [MAP(praesenz.map):%s]“ icon=“present“
}
Hier kommt immer nur „unbekannt“.
Langsam bin ich ratlos.
Warum kommt da nix an?
Daniel Wenzel
20.01.2016 @ 05:05
Wie sieht denn deine Item-Definition aus? Als welches Systemnutzer läuft OpenHAB bei dir? Vielleicht darf OpenHAB dieses Script nicht ausführen.
Matthias
19.01.2016 @ 10:26
Hallo Daniel,
ich habe auch die Anwesenheitserkennung mit Bluetooth nachgebaut.
Wenn ich auf dem PI das scipt ausführe bekommen ich passend ON und OFF.
Wenn ich auf dem Openhab Server das Script ausführe, dass über ssh auf den PI connectet bekomm ich auch On und OFF.
Nun zu meinem Problem: Wenn ich die items und sitemap definiere aktuallisiert oben hab die items aber im Logstream kommt immer nur
Jan_Handy_BT state updated to
Also kein ON oder OFF.
Weiß du woran das liegen könnte?
Viele Grüße
Matthias
Daniel Wenzel
23.12.2015 @ 05:48
Das werde ich mal ausprobieren und ggf. die Anleitung damit erweitern. Danke für den Tipp.
Thomas
22.12.2015 @ 12:33
Halo Daniel,
danke für die Anleitung. Ein kleiner Optimierungsvorschlag: Ich habe anstatt den Regeln für „Daniel ist Zuhause“ und „Daniel ist nicht mehr Zuhause“ einfach eine Group:Switch:OR(ON, OFF) MOB188 „Handy Daniel“ angelegt und diese den beiden Items WLAN und BT hinzugefügt. Dann kann man sich das Script sparen.
Ich hoffe ich habe mich nicht vertippt. Bei mir heißen die Items logischerweise anders.
Switch MOB188_BT „Handy Daniel“ (MOB188, grp_PRAESENZ) { exec=“<[/scripts/bt.sh 1:60000:REGEX((.*?))]" }
Switch MOB188_WLAN "Handy Daniel" (MOB188, grp_PRAESENZ) { nh="192.168.23.188" }
Group:Switch:OR(ON, OFF) MOB188 "Handy Daniel"
Patrick
22.12.2015 @ 12:03
Nun geht es wieder. War ein Syntaxfehler.
Patrick
22.12.2015 @ 10:54
Hallo erstmal an alle hier und Danke für das tolle Script.
Ein Problem habe ich nun aber ein Problem ich mache das ganze ur auf der WLAN Basis und in einer VM.
Das komische ist erst lief es und dann nach dem Neustart der VM plötzlich nicht mehr ich bekomme nun im LOG einen Fehler
[ERROR] [o.u.i.items.ItemUIRegistryImpl:438 ] – Cannot retrieve item MOB104 for widget org.openhab.model.sitemap.Text ich habe die Mobs an allen stellen meiner Dateien geändert.
MFG Patrick
Daniel Wenzel
22.11.2015 @ 21:35
Oh, ist mir gar nicht aufgefallen. Freut mich, dass es nun endlich funktioniert.
NCO
22.11.2015 @ 20:44
Hi Daniel,
ich habs geschafft.
Es hing mit dem sudoers file zusammen.
Ich hatte blind deinen Tippfehler oben per copy & paste übernommen ;-)
/usb/bin/l2ping (statt /usr/bin/l2ping).
Vielen Dank für deine Hilfe und Geduld.
Gruß
Enzio
Daniel Wenzel
21.11.2015 @ 16:02
Hmm, bisher hatte weder ich Probleme deiner Art noch habe ich von Ähnlichen gehört. Es steht dir natürlich frei, alles zu testen. Aber wenn du eh schon am testen bist, kannst du es ja auch mit einer frischen Installation von Raspbian probieren ;)
NCO
21.11.2015 @ 13:17
Hmm, schade. Vielen Dank aber für deine Geduld mit mir ;-)
Vielleicht sollte ich Ubuntu in Betracht ziehen und kein Raspbian!?
Es scheint als wäre das ausgereifter. Zugriffsrechtprobleme gibts da in den Foren deutlich weniger.
Viele Grüße,
Enzio
Daniel Wenzel
20.11.2015 @ 07:12
Tja, dann stehe ich ehrlich gesagt erstmal aufm Schlauch. Möglicherweise ist es nur eine Kleinigkeit, die man übersieht, vielleicht ist aber auch irgendwas am System vermurkst. Das könnte man herausfinden, indem man mit einer zweiten SD-Karte die Schritte der Anleitung mit einer frischen Installation testet.
NCO
19.11.2015 @ 13:55
In meinem /etc/sudoers ist kein requiretty erwähnt.
Daniel Wenzel
18.11.2015 @ 15:24
Ich habe grade das Internet befragt und folgendes gefunden:
https://stackoverflow.com/questions/27697348/sudoers-nopasswd-sudo-no-tty-present-and-no-askpass-program-specified
Schau doch mal bitte, ob das Problem mit „requiretty“ auf dich zutrifft.
NCO
18.11.2015 @ 12:39
Hallo Daniel,
ich habe deinen sudo hinweis befolgt und bekomme nun im log folgenden Eintrag
(ich habe auch hier “&> /dev/null” weggelassen)
no tty present and no askpass program specified
Kannst du damit etwas anfangen?
Daniel Wenzel
18.11.2015 @ 11:40
Nun ja, ich konnte antworten, weil ich gestern einen Bluteooth-Stick gefunden habe, mit dem ich das testen konnte. Grundsätzlich hatte der Nutzer „pi“ nicht das Recht, /usr/bin/l2ping auszuführen.
NCO
18.11.2015 @ 09:57
danke, werde ich mal testen.
NCO
18.11.2015 @ 09:56
Hallo Daniel,
da habe ich mich wohl vertan – sorry.
l2ping als sudo geht, als pi aber nicht und liefert:
Can’t create socket: Operation not permitted
Nach Entfernen von “&> /dev/null” kommt das auch beim Aufruf von bt.sh 1.
Dann hakts wohl doch bei den Rechten!?
/usr/bin/l2ping hat auch für nicht-root execution Rechte.
Daniel Wenzel
17.11.2015 @ 21:31
Hallo Enzio,
versuch mal bitte folgendes:
ändere die Zeile im Script, die l2ping aufruft wie folgt:
if /usr/bin/sudo /usr/bin/l2ping -c 1 $MAC &> /dev/null
Dann änderst du die sudoers mit
nano /etc/sudoers
und trägst ganz unten (unter pi ALL….) ein:
openhab ALL = NOPASSWD: /usb/bin/l2ping
Datei speichern und das Script nochmals testen.
Daniel Wenzel
14.11.2015 @ 08:41
Hallo Enzio,
leider kann ich das Problem grad nicht nachstellen, weil mein Bluetooth-Stick an einem anderen Gerät hängt. Da du aber als Nutzer Pi „l2ping“ ausführen kannst, denke ich nicht mehr, dass es sich um ein Rechteproblem handelt. Viel mehr wird in dem Script ja nicht ausgeführt. Versuch mal testweise in dem Script das „&> /dev/null“ zu entfernen, dann werden dir eventuelle Fehler auf der Shell angezeigt. Meld dich einfach mit deinen Ergebnissen.
NCO
14.11.2015 @ 08:25
Hallo Daniel,
vielen Dank für die Anleitung – die ist sehr hilfreich.
Dennoch habe ich Probleme:
Wenn ich dein bt.sh in der Konsole als pi aufrufe, bekomme ich immer „OFF“.
Führe ich ein l2ping auf meine iPhone bt-MAC Adresse aus bekomme ich eine Antwort und als sudo liefert auch dein bt ein „ON“.
Bei openHAB ist mein user „openhab“, der auch in der Gruppe „dialout“ ist.
Die Rechte habe ich bei dem bt.sh auf 755 gesetzt.
Hast du eine Idee, was ich falsch gemacht haben könnte?
Vielen Dank im Voraus.
Viele Grüße,
Enzio
Christian
16.03.2015 @ 22:43
Hallo Sebastian,
das ist die „Kunst“, also zu ermitteln, ob jemand zu Hause ist, oder nicht.
Man müsste da ein paar Dinge mehr in Kombination überwachen, z.B.
– Aktueller Stromverbrauch
– Raum Temperatur / Zustand Heizung
– Offene/Geschlossene Fenster (in Abhängigkeit von der Jahreszeit)
– Feste „Präsenz“-Zeiten (z.B. bei einem regelmäßigem Tagesablauf)
– PIR Bewegungsmelder
– Eingeschaltete Geräte (z.B. Fernseher, Sat-Reciver, A/V-Reciver – fast jedes neuere Gerät hat ja einen LAN-Schnittstelle)
All diese „Sensoren“ in kombination mit einem vernünftigen Regel-Werk ergeben bestimmt eine zuverläsige „Präsenz-Meldung“!
Viele Grüße,
Christian
Sebatian
23.02.2015 @ 11:32
Servus,
schöner Artikel. Vor allem die Idee BT & WLAN zu verknüpfen. Ich hatte vor einiger Zeit mal ausschließlich mit BT eine Presence detaection aufgebaut und hatte einige Probleme.
Zum einen blieb mein l2ping leer, da das Smartphone meiner Frau nur geantwortet hat, wenn es gepaired war. Doof beim Stromverbrauch und Fragen meiner Frau, warum da jetzt immer ein BT Icon als aktiv auftaucht. Zum andern war die Reichweite nicht groß genug um das ganze Haus abzudecken. Wenn man ins OG gegangen ist, war die Presence weg ;-(
Ich hatte mir damals auch ein Shell Script geschrieben, das direkt per Curl einen POST absetzt und das OH item via rest API auf ON bzw: OFF setzete. Dann spart man sich den exec call in OH. Das ganze lief in einer while/true Schleife alle 30 Sekunden.
Wie läuft die Präsenz Ermittlung so im täglichen Leben? Zuverlässig? Mit den ganzen Handy Stromspar Mechanismen könnte ich mir vorstellen, dass wenn das Handy schlafen geht, BT und auch WLAN aus gehen. Dann wäre die „Präsenz“ OFF aber ihr seid noch zu Hause.
Gruß