FHEM

Anwesenheitserkennung

Die Anwesenheitserkennung liefert die Information, die fast alle anderen Automatisierungen brauchen: Ist eine Person zu Hause? In diesem Aufbau wird Anwesenheit anhand der Smartphones der Bewohner im Netzwerk erkannt und anschließend über structure-Gruppen zu raum- und gruppenbezogenen Status zusammengefasst. So weiß die Heizungssteuerung, ob ein Raum beheizt werden muss, und die Benachrichtigungen wissen, ob eine Meldung relevant ist. Alle Namen und MAC-Adressen sind generische Platzhalter.

Funktionsprinzip

Jedes Smartphone besitzt eine eindeutige MAC-Adresse. Solange ein Gerät im WLAN aktiv ist, ist es dem Router bekannt. FHEM fragt daher zyklisch ab, ob die MAC einer Person aktuell im Netzwerk registriert ist. Verschwindet sie über einen definierten Zeitraum, gilt die Person als abwesend; taucht sie wieder auf, als anwesend.

Voraussetzung: Router-Gerät in FHEM

Damit FHEM weiß, welche Geräte gerade im Netzwerk aktiv sind, wird der Router selbst als Gerät eingebunden – bei einer FRITZ!Box etwa über das FRITZBOX-Modul. Dieses Gerät stellt für jedes bekannte Endgerät ein Reading der Form mac_AA_BB_CC_DD_EE_FF bereit. Dessen Wert ist der Hostname (Gerät aktiv) oder inactive (Gerät nicht erreichbar).

bashKlick markiert alles · Strg + C
define WLANRouter FRITZBOX
attr  WLANRouter room Anwesenheit

Hilfsfunktion zur Netzwerkabfrage

Die eigentliche Prüfung übernimmt eine kleine, selbst geschriebene Perl-Funktion in der 99_myUtils.pm. Sie wandelt die übergebene MAC-Adresse in die Reading-Schreibweise (Doppelpunkte werden zu Unterstrichen), durchsucht alle als Router definierten Geräte und gibt 1 für anwesend bzw. 0 für abwesend zurück.

bashKlick markiert alles · Strg + C
sub NetDevDa($) {
  my ($mac) = @_;
  my $n = 0;
  # Doppelpunkte der MAC in Unterstriche wandeln (Reading-Schreibweise)
  $mac =~ tr/:/_/;
  # Alle als Router definierten Geraete durchgehen
  my @router = devspec2array("NAME=WLANRouter");
  foreach (@router) {
    my $host = ReadingsVal($_, "mac_" . $mac, "");
    $n++ if ($host ne "" && $host ne "inactive");
  }
  return ($n == 0) ? 0 : 1;
}

Sind mehrere Router im Einsatz (z. B. ein getrenntes WLAN für Gäste oder ein zweiter Standort), lässt sich die Funktion mit weiteren Gerätenamen erweitern oder als zweite Variante kopieren. Nach dem Anlegen muss FHEM die Datei neu einlesen:

bashKlick markiert alles · Strg + C
reload 99_myUtils

Einzelne Person erkennen

Pro Bewohner wird ein PRESENCE-Gerät im function-Modus angelegt. Es ruft die Hilfsfunktion alle 30 Sekunden auf (im Abwesenheitsfall alle 300 Sekunden) und liefert die Zustände present bzw. absent.

bashKlick markiert alles · Strg + C
define Person1Anwesend PRESENCE function {NetDevDa("AA:BB:CC:DD:EE:FF")} 30 300
attr  Person1Anwesend event-on-change-reading .*
attr  Person1Anwesend room Anwesenheit

Das Attribut event-on-change-reading .* sorgt dafür, dass nur echte Statuswechsel Ereignisse auslösen – das hält die Logs sauber und vermeidet unnötige Schaltvorgänge.

Status zu Gruppen zusammenfassen

Selten interessiert eine einzelne Person; meist zählt, ob überhaupt jemand einer bestimmten Gruppe anwesend ist. Das Modul structure aggregiert dazu mehrere PRESENCE-Geräte zu einem gemeinsamen Status. Über clientstate_priority wird festgelegt, dass present Vorrang vor absent hat – sobald also eine Person der Gruppe da ist, gilt die ganze Gruppe als anwesend.

bashKlick markiert alles · Strg + C
define WohnzimmerStructureAnwesend structure Anwesenheit Person1Anwesend Person2Anwesend Person3Anwesend
attr  WohnzimmerStructureAnwesend clientstate_behavior relative
attr  WohnzimmerStructureAnwesend clientstate_priority present absent
attr  WohnzimmerStructureAnwesend room Anwesenheit

So lassen sich beliebige Gruppen bilden – etwa eine Gruppe „Kinder", die nur die Geräte der Kinder enthält, oder eine raumbezogene Gruppe für die Heizungslogik. Genau diese Gruppen-Stati (WohnzimmerStructureAnwesend, KinderStructureAnwesend …) werden in den DOIF-Regeln der Heizung abgefragt.

Lange Abwesenheit erkennen

Für eine besonders sparsame Absenkung ist es sinnvoll, zwischen „kurz weg" und „schon lange weg" zu unterscheiden. Ein Dummy-Flag hält diesen Zustand, ein DOIF setzt es: Ist die Gruppe länger als eine Stunde abwesend, wird das Flag auf true gesetzt; bei Rückkehr sofort wieder auf false.

bashKlick markiert alles · Strg + C
define WohnzimmerStructureLangeAbwesend dummy
attr  WohnzimmerStructureLangeAbwesend setList true false
attr  WohnzimmerStructureLangeAbwesend room Anwesenheit

define di_LangeAbwesend DOIF ([WohnzimmerStructureAnwesend:state] eq "absent")
  (set WohnzimmerStructureLangeAbwesend true)
DOELSE
  (set WohnzimmerStructureLangeAbwesend false)
attr  di_LangeAbwesend wait 3600:0
attr  di_LangeAbwesend room Anwesenheit

Das wait 3600:0 verzögert nur den ersten Zweig um 3600 Sekunden (eine Stunde). Erst wenn die Abwesenheit so lange anhält, schaltet das Flag – die Heizung kann dann zusätzlich von Eco auf eine noch tiefere Sparstufe gehen.

Test und Speichern

  1. Mit dem Smartphone das WLAN verlassen und prüfen, ob Person1Anwesend nach Ablauf des Intervalls auf absent wechselt.
  2. Über list WohnzimmerStructureAnwesend kontrollieren, ob der Gruppenstatus korrekt aus den Mitgliedern berechnet wird.
  3. Konfiguration sichern:
bashKlick markiert alles · Strg + C
save

Damit steht eine zuverlässige, gestaffelte Anwesenheitserkennung bereit: einzelne Personen werden erkannt, zu sinnvollen Gruppen zusammengefasst und um eine Erkennung langer Abwesenheit ergänzt.