GEOFANCY

Aus FHEMWiki
Version vom 31. Januar 2018, 11:29 Uhr von Baumbuwe (Diskussion | Beiträge) (Vorlage Link2CmdRef)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
GEOFANCY
Zweck / Funktion
Anwesenheitserkennung
Allgemein
Typ Hilfsmodul
Details
Dokumentation EN / DE
Modulname 98_GEOFANCY.pm
Ersteller Loredo
Wichtig: sofern vorhanden, gilt im Zweifel immer die (englische) Beschreibung in der commandref!


Modul in FHEM einrichten

Das Modul ist mit einer einfachen Definition sofort betriebsbereit:

define geofancy GEOFANCY geo

Damit nimmt FHEM unter http://192.168.178.1:8083/fhem/geo entsprechende Meldungen des iPhones entgegen. Damit das nicht nur über das lokale WLAN funktioniert, bedarf es allerdings noch einiger zusätzlicher Maßnahmen. FHEM muss vom Internet erreichbar gemacht werden, dabei sollte unbedingt an die Absicherung des Zugriffs gedacht werden.

Zunächst einmal habe ich bei mir eine eigene FHEMWEB Instanz dafür angelegt:

define WEBhook FHEMWEB 8088 global
attr WEBhook column Alarms: Apartment: Living: Bedroom: Kitchen: Sonos: Residents: Weather: Bathroom: Logs: Statistics: DashboardRoom: System: hidden: all:
attr WEBhook hiddenroom input,detail,save,Unsorted,Everything,CUL_HM,FS20,Commandref,style,Edit files,Select style,Logfile,Floorplans,Remote doc,FileLogs,Apartment,Bathroom,Bedroom,Kitchen,Living,Residents,System,Weather,Event monitor,NEW
attr WEBhook room hidden
attr WEBhook webname webhook

Damit ist unter der URL http://192.168.178.1:8088/webhook/geo das GEOFANCY Modul erreichbar. Ich verstecke in dieser Ansicht noch alle Räume, die ich so habe. Wer die Raumnamen allerdings kennt, kann sie trotzdem aufrufen. Die Anzeige in den Räumen kann man mit dem Attribut column und entsprechend leeren Definitionen verstecken. Nun muss man explizit den Devicenamen kennen, um noch etwas über die Konfiguration in Erfahrung bringen zu können. Auch wenn das Security-by-Obscurity ist - ich fühle mich wohler damit.

Webhook weiter absichern

Mit Hilfe eines allowed-Devices lässt sich die FHEMWEB Instanz noch weiter absichern indem nur die tatsächlich benötigten Kommandos erlaubt werden (in diesem Fall keine) und damit alle anderen nicht erlaubten (attr,define,get,set,...) automatisch nicht mehr zur Verfügung stehen:

define allowedWEBhook allowed
attr allowedWEBhook allowedCommands ,
attr allowedWEBhook allowedDevices ,
attr allowedWEBhook validFor WEBhook

Außerdem ist dringend zu empfehlen, den Zugriff über TLS/SSL und HTTP Basic-Authentication weiter abzusichern. Läuft FHEM auf einem Raspberry Pi, dann empfehle ich dazu die Konfiguration eines ReverseProxy (vorzugsweise HAproxy, Pound oder Varnish, notfalls auch Nginx oder Apache); damit ist man am flexibelsten und kann auch alle FHEMWEB Instanzen direkt über einen einzigen Port (meist 443, der HTTPS Standard Port) zusammenfassen. Ich möchte hier allerdings beschreiben, wie weit man mit FHEM Bordmitteln kommt und nehme das Beispiel einer Installation auf einer Fritzbox.

Wie TLS aktiviert wird, steht in der Commandref für FHEMWEB. Um die Kommandos auf der Fritzbox ausführen zu können, muss zuerst Telnet aktiviert werden (bitte Google benutzen). Anschließend wechselt man auf der Fritzbox ins Verzeichnis /var/media/ftp/fhem und kann dann den Hinweisen aus der commandref/FHEMWEB unter dem Punkt HTTPS folgen. Letztlich fehlt noch das entsprechende Attribut:

attr WEBhook HTTPS

Als nächstes aktivieren wir Benutzername+Passwort für den Zugriff. Die commandref für allowed gibt auch hier unter dem Punkt basicAuth entsprechende Hinweise. Wir fügen hier einfach mal einen Benutzer "webhook" mit dem Passwort "Geofancy" hinzu, das sieht dann so aus:

attr allowedWEBhook basicAuth { "$user:$password" eq "webhook:Geofancy" }

Weitere Infos zur Absicherung gibt auch FritzBox Webzugriff absichern.

Um zu testen, ob unsere Absicherung erfolgreich war, kann man die URL https://192.168.178.1:8088/webhook/geo aufrufen (wichtig ist, dass man jetzt https und nicht mehr http eingibt; ansonsten bekommt man keine Antwort). Eine Zertifikatswarnung kann getrost ignoriert werden, verschlüsselt wird trotzdem. Es sollte auch eine Passwort Abfrage kommen und die Eingabe der entsprechenden Daten sollte dann zu einer entsprechenden Meldung vom GEOFANCY Modul führen:

NOK No data received, see API information on http://wiki.geofancy.com

Das ist ok, schließlich sind wir keine App, sondern der Mensch, der nur mal eben prüfen will :-)

Zugriff vom Internet ermöglichen

Das ist je nach Fritzbox und Software Version unterschiedlich. Grundsätzlich gilt: Eine Weiterleitung des ports 8088 vom Internet auf das laufende FHEM auf Port 8088 intern ist von AVM so nicht vorgesehen. Bei mir führte folgendes zum Erfolg:

  • Einloggen per Telnet auf der Fritzbox (ich habe FritzOS 6 installiert)
  • Konfiguration editieren mittels "nvi /var/flash/ar7.cfg"
  • Suchen nach richtiger Zeile durch Eingabe von "/internet_forwardrules" und Enter
  • Hinzufügen einer weiteren Zeile (Vorsicht, die bestehende Zeile endet mit ; und das muss in , umgeändert werden, so dass das ; schließlich am Ende der Zeile steht.

So sieht es bei mir vorher aus:

internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0";

Hinterher:

internet_forwardrules = "tcp 0.0.0.0:488 0.0.0.0:488 0", "tcp 0.0.0.0:8088 0.0.0.0:8088 0";

Danach mittels ":x" abspeichern und sofort per "reboot" die Box neu starten, um diese Änderungen zu aktivieren. Das ist wichtig; ansonsten zeigt die Erfahrung, dass die Änderung nicht dauerhaft erhalten bleibt und die gerade gemachten Änderungen verloren gehen.

Wer die Einstellungen zu "internet_forwardrules" bei sich nicht finden kann, hat womöglich eine andere Version als ich oder ein leicht anderes Gerät und bemüht am besten Google, was er tun kann, um das Gleiche zu erreichen. Möglicherweise tauchen die Einträge auch erst auf, wenn man mal über das Webinterface ein Forwarding eingerichtet hatte.

Hat man einen DynDNS Dienst oder myFritz auf der Fritzbox aktiviert, so kann man jetzt auch von draußen auf den Webhook zugreifen. Das kann man prüfen, indem man das iPhone aus dem WLAN ausbucht und einmal die externe Adresse eingibt, also z.B. https://meindyndns.org:8088/webhook/geo.

Weitere Alternativen für den Zugriff aus dem Internet

Als Alternative zum Port Forwarding kann man sich auch per VPN in das lokale Netzwerk einwählen. iOS bietet dazu auch eine automatische Aktivierung des VPN (VPN on Demand), wie z.B. hier beschrieben wird.

Auch eine Alternative ist, das Portforwarding nicht direkt an FHEM einzurichten, sondern an einem im Netzwerk laufenden Reverse-Proxy, der dann seinerseits die Anfragen an FHEM weiterleitet. Dies kann z.B. Apache, Nginx oder am besten HAproxy sein. Letzterer ist dabei sehr flexibel, allerdings nicht unbedingt einfach zu konfigurieren. Ein paar Inspirationen diesbezüglich gibt es z.B. hier und hier. Wer pfSense nutzt, findet diesen Artikel womöglich auch interessant. Er zeigt auch, dass mit HAproxy noch weit mehr möglich ist. Der Reverse-Proxy sollte dabei auch unbedingt der TLS Termination Point sein (TLS Offloading). Nicht nur spart man sich dann die Aktivierung von TLS in FHEM, sondern man hat auch mehr Einfluss darauf, wie TLS arbeitet (z.B. Deaktivierung von SSLv3, forcieren von TLSv1.2, nur als sicher eingestufte Cipher Suite... siehe auch Infos auf der Mozilla Website).

Einrichten in der Geof[e|a]ncy.app

Hat das alles soweit geklappt, können endlich in der Geofency.app bzw. Geofancy.app am iPhone die gewünschten Bereiche definiert werden. Am Besten zuvor in den Global Settings die folgenden Einstellungen hinterlegen:

Anfänglich ist es empfehlenswert noch "Notification on success" und "Notification on Failure" einzuschalten. Ersteres kann man ausmachen wenn man weiß, dass es soweit funktioniert. Über "Send Test-Request" kann man einmal einen Test schicken und erhält das Ergebnis entsprechend dargestellt. Es sollte sowas kommen wie

POST Success: test OK. In Geofancy.app gibt es keine Rückmeldung über den Erfolg des Testrequests. In FHEM sollten sich durch den Testrequest jedoch die Readings sofort aktualisieren (Ggf. ist ein Reload der FHEMWEB-Seite nötig da zusätzliche Tabellenzeilen nicht via Longpoll ergänzt werden).

Funktioniert das soweit, kann man eine neue Lokation als sein Zuhause anlegen. Es empfiehlt sich einen ID-Namen zu setzen; dieser ist dann in FHEM als Name für die Lokation sichtbar. Für die eigene Wohnung empfiehlt sich hier "home" (da dies auch direkt vom RESIDENTS Modul so verwendet werden kann). Man kann auch Trigger für andere Standorte anlegen. FHEM weiß dann sogar, wenn ihr im Büro seid und könnte sich dabei auch unterschiedlich verhalten, als wenn ihr "auf Achse" seid. Bei letzterem ist der Status im GEOFANCY Modul "underway", was so viel heißt wie "unbekannter Aufenthaltsort".

Hinweis: Zumindest für Geofancy.app liefert ein Testrequest wohl zufällige Locations zurück. Die eigenen Location-IDs werden also nicht übergeben, selbst wenn man sich in einem Geofence befindet. Um zu testen muss man sich wohl oder übel selbst bewegen ;-).

GEOFANCY Modul individualisieren

Die im GEOFANCY Modul dargestellten Readings sind nun in etwa so, wenn ihr euch bewegt:

Readings:
     2014-01-18 14:37:42   lastDevice      -
     2014-01-18 14:37:42   lastDeviceUUID      51F23894-AAAA-BBBB-CCCC-0123456789AB
     2014-01-18 14:37:42   state           dev:51F23894-AAAA-BBBB-CCCC-0123456789AB trig:test id:home lat:48.9999 long:11.9999

Wer genauer hinschaut sieht: Mein iPhone heißt wohl 51F23894-AAAA-BBBB-CCCC-0123456789AB. Damit nun die Readings für mein iPhone richtig angelegt werden, muss ein Device Alias gesetzt werden. Sinnvoll erscheint mir der Vorname des Besitzers:

attr geofancy devAlias 51F23894-AAAA-BBBB-CCCC-0123456789AB:Julian

Weitere Alias-Namen können mit Leerzeichen einfach angehängt werden. Jetzt werden weitere Readings angelegt, sobald GEOFANCY entsprechende Daten vom Mobilgerät empfängt:

Readings:
     2014-01-18 14:37:42   Julian          arrived home
     2014-01-18 14:37:42   currLocLat_Julian 48.9999
     2014-01-18 14:37:42   currLocLong_Julian 11.9999
     2014-01-18 14:37:42   currLocTime_Julian 2014-01-18 14:37:42
     2014-01-18 14:37:42   currLoc_Julian  home
     2014-01-17 19:18:23   lastArr         Julian home
     2014-01-17 18:41:46   lastDep         Julian Office
     2014-01-18 14:37:42   lastDevice      Julian
     2014-01-18 14:37:42   lastDeviceUUID      51F23894-AAAA-BBBB-CCCC-0123456789AB
     2014-01-17 18:41:46   lastLocArr_Julian 2014-01-17 08:58:37
     2014-01-17 18:41:46   lastLocDep_Julian 2014-01-17 18:41:46
     2014-01-17 18:41:46   lastLocLat_Julian 48.1111
     2014-01-17 18:41:46   lastLocLong_Julian 11.1111
     2014-01-17 18:41:46   lastLoc_Julian  Office
     2014-01-18 14:37:42   state           dev:Julian trig:test id:home lat:48.9999 long:11.9999

Möchte man nun etwas bestimmtes tun, wenn man nach Hause kommt oder das Heim verlässt, kann man am Besten ein entsprechendes Notify auf das Reading currLoc_Name setzen. Ich aktualisiere lediglich zwei Dummies, durch die dann alle weiteren Notifies ausgelöst werden:

define n_Julian.Presence notify geofancy:currLoc_Julian:.home set Julian.homestatus:FILTER=STATE!=home home
attr n_Julian.Presence room Residents
define n_Julian.absence notify geofancy:currLoc_Julian:.underway {\
if (Value("Julian.homestatus") ne "gone") {\
  fhem("set Julian.homestatus:FILTER=STATE!=absent absent");;\
}\
}
define n_Julian.whereabout notify geofancy:currLoc_Julian:.* set Julian.whereabout:FILTER=STATE!=$EVTPART1 $EVTPART1

Wer es noch einfacher möchte (bzw. auch noch mehr Features) schaut sich einmal die neue Modulfamilie aus RESIDENTS, ROOMMATE und GUEST an. Diese sind direkt auf GEOFANCY abgestimmt. Dabei kann das devAlias Attribut entfallen und man hinterlegt die UUID stattdessen direkt im ROOMMATE oder GUEST Device (Attribut r*_geofenceUUIDs). Das erspart es für jeden Bewohner und jedes Device zig unterschiedliche Devices der Typen Notify, DOIF oder Watchdog anlegen und pflegen zu müssen.

Wer mehr Kontrolle möchte kann natürlich bei notify, DOIF und Co. bleiben: define n_rr_Julian.location notify geofancy:currLoc_Julian:.* set rr_Julian:FILTER=location!=$EVTPART1 location $EVTPART1. Wobei "Julian" dabei als devAlias in GEOFANCY eingtragen wurde, rr_Julian der Name des ROOMMATE aus RESIDENTS ist. Außerdem wurden die Location-IDs in der Geofency.app bzw. Geofancy.app so gewählt, dass diese direkt einem ROOMMATE-Status entsprechen (also z.B. home, wayhome...).