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).
define WLANRouter FRITZBOX
attr WLANRouter room AnwesenheitHilfsfunktion 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.
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:
reload 99_myUtilsEinzelne 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.
define Person1Anwesend PRESENCE function {NetDevDa("AA:BB:CC:DD:EE:FF")} 30 300
attr Person1Anwesend event-on-change-reading .*
attr Person1Anwesend room AnwesenheitDas 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.
define WohnzimmerStructureAnwesend structure Anwesenheit Person1Anwesend Person2Anwesend Person3Anwesend
attr WohnzimmerStructureAnwesend clientstate_behavior relative
attr WohnzimmerStructureAnwesend clientstate_priority present absent
attr WohnzimmerStructureAnwesend room AnwesenheitSo 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.
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 AnwesenheitDas 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
- Mit dem Smartphone das WLAN verlassen und prüfen, ob
Person1Anwesendnach Ablauf des Intervalls aufabsentwechselt. - Über
list WohnzimmerStructureAnwesendkontrollieren, ob der Gruppenstatus korrekt aus den Mitgliedern berechnet wird. - Konfiguration sichern:
saveDamit steht eine zuverlässige, gestaffelte Anwesenheitserkennung bereit: einzelne Personen werden erkannt, zu sinnvollen Gruppen zusammengefasst und um eine Erkennung langer Abwesenheit ergänzt.
