An-/Abwesenheitserkennung mit WLAN und Fritz!Box

Begonnen von borsti67, 25 Juli 2015, 21:21:04

Vorheriges Thema - Nächstes Thema

juergen012

Hallo, ich habe auch das Problem, dass nachdem ich einen Repeater (DVB-C) installiert habe, die Anwesenheit nicht mehr funktioniert. Wie von borsti67 beschrieben, "frieren" die readings auf dem Repeater ein. Meine bescheidenen Versuche, den Timestamp zu implementieren, sind gescheitert. Ich habe die Konfiguration wie von Otto123 beschrieben in der 99_myUtils.
######## Netzwerk Gerät über Fritzbox abfragen ############
sub
NetDevDa($)
{
    my $n = 0;
    my ($Reading) = @_;
    $Reading =~ tr/:/_/;
    my @fbs = devspec2array("TYPE=FRITZBOX");
       foreach( @fbs ) {
          my $Name = ReadingsVal($_,"mac_" . $Reading,"");
          if( ($Name ne "") && ($Name ne "inactive") ) {
              $n++;
          }
       }
    if( $n == 0) {
        return 0;
    } else {
        return 1;
    }
}

Wenn mir ein Wissender helfen könnte hier noch die Abfrage des Timestamp eizufügen, wäre ich dankbar.
Beste Grüße
Jürgen K.
Fhem unter Proxmox

yogiflop

So ähnlich ist es ja bei mir auch, würde mich freuen, wenn der Schreiber des Modules sich der Sache mal annehmen würde, da es nicht am Repeater liegt. Da im Repeater die Werte verschwunden sind.


Gesendet von irgendwo unterwegs
CubieTruck mit FHEM 5.7
433MHz, 868MHz HMLan
div. Baumarktsteckdosen, 3x HM
div. MiLight's

l2r

#62
ich hab meine Routine ein bisschen abgewandelt:



sub
NetDevDa($$)
{
    my $n = 0;
my $active = 0;
my ($Reading,$Client) = @_;
my $Cl_Status = ReadingsVal($Client,"state","absent");
    $Reading =~ tr/:/_/;
    my @fbs = devspec2array("TYPE=FRITZBOX");
       foreach( @fbs ) {
          my $Name = ReadingsVal($_,"mac_" . $Reading,"");
         if( ($Name ne "") && ($Name ne "inactive") && ((time() - time_str2num(ReadingsTimestamp($_,"mac_".$Reading,0))) < 600) ){
              $n++;
  $active = 1;
          }
  fhem("setreading $Client $_ $active");
  $active = 0;
       }
    if(( $n == 0)&&($Cl_Status ne "absent")) {
        fhem("set $Client absent");
Log 3, ("NetDevDa: $Client is set to ABSENT");
    } elsif (( $n > 0)&&($Cl_Status ne "present")) {
        fhem("set $Client present");
Log 3, ("NetDevDa: $Client is set to PRESENT");
    }
# Log 3, ("$Client $Cl_Status $n $Reading");
}


ich gebe zusätzlich noch den namen eines Dummies mit, der mein Gerät repräsentiert. und im Dummie wird dann ein Reading mit dem Namen der Fritzbox hinzugefügt, welches signalisiert an welcher Firtzbox das Device angemeldet ist (0 oder 1)

die Fitzbox-devices haben bei mir noch

attr <Fritzboxdevice-Name> event-on-update-reading mac_.*

im Firitzboxdevice ist ein Interval von 120 eingestellt.

und die Funktion lasse ich alle 2 Minuten durch ein at aufrufen:

deinfe test at +*00:02:00 {NetDevDa("XX:00:XX:00:XX:00","GalaxyS3")}

läuft gut bei mir.

vllt hilfts ja jemandem.

Gruß Michael
Wissen ist Macht.
Ich weiß nix.
Macht nix.

rhya

Habe etwas ähnliches gemacht, was für meine Zwecke auch funktioniert (habe die Probleme mit den Repeater-Einträgen nicht)

Vielleicht kann's ja wer brauchen. Die MACs notiere ich so wie sie in der FB sind, ob ich das jetzt direkt im String mache oder hin und her knödle ... ist auch nicht besser lesbarer mit Doppelpunkten...
Wollte vorher über den Devicenamen gehen "Michael-*", aber mein Fritz-Repeater kann das wohl nicht. Also back to MAC...


sub
checkPresenceViaMacs()
{
  my @MACsMichael = (
    "mac_EC_59_E7_F4_D3_63", # Michael-Lumia830
    "mac_D4_3D_7E_05_16_33" # Michael-Desktop
  );
  my @MACsFreundin = (
    "mac_64_B8_53_55_63_33", #  Freundin-Handy
    "mac_30_52_CB_17_4F_C3" # Freundin-Laptop
  );
  checkMacs("Michael", @MACsMichael );
  checkMacs("Freundin", @MACsFreundin );
}

sub
checkMacs($@)
{
my ($dummydevice, @MACs) = @_;
my @Boxes = devspec2array("TYPE=FRITZBOX");

my $mac = "";
my $box = "";
my $dummystatus = ReadingsVal($dummydevice,"state","");

# Check presence
foreach $mac (@MACs) {
foreach $box (@Boxes) {
#Log3 undef, 3, "Checking $mac on $box ($dummydevice)";
my $devicename = ReadingsVal($box,$mac,"inactive");
if($devicename eq "inactive") {
next; # Device not found, try next box device
}

fhem("set ".$dummydevice.".lastseen ".strftime("%Y%m%d%H%M%S", localtime()));
if($dummystatus eq "Unterwegs") {
Log3 undef, 3, "Device $devicename found with $mac on $box ($dummydevice)";
fhem("set $dummydevice Zuhause");
}
return; # exit routine, person found. Absence check not necessary
}
}

if($dummystatus eq "Zuhause") {
# Check absence after 15 Minutes
my $minutes = 15;
my $now = strftime("%Y%m%d%H%M%S", localtime());
my $lastseen = ReadingsVal($dummydevice.".lastseen","state","0");

if($lastseen < ($now - ($minutes * 60))) {
Log3 undef, 3, "No devices from $dummydevice found in the last $minutes minutes - guess s/he is gone";
fhem("set $dummydevice Unterwegs");
}
}
}



Habe dafür zwei Dummys zum Speichern der letzten "Sichtung" Freundin.lastseen und Michael.lastseen, je einen dummy für den HomeStatus "Freundin" und "Michael" und ein at, was einfach alle 5 Minuten die checkPresenceViaMacs() aufruft. Die Funktion ist einfach nur zum wrappen, weil ich den Code lieber in der pm hatte als im at direkt (wer weiß wo ich das nochmal aufrufen will)

Otto123

Zitat von: l2r am 27 Januar 2016, 10:55:07
und die Funktion lasse ich alle 2 Minuten durch ein at aufrufen:
Da ich kein Freund von asynchronem Polling bin  8) habe ich meine Abfrage einfach an das FB Modul dran gehangen: Über den Event und das Reading
lastReadout.*
Triggere ich ein DOIF

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

l2r

@Otto: das ist auch das was mich stört und deinen Ansatz finde ich interessant. Leider versteh ich den gerade nicht. Kannst du da vllt noch ein bisschen mehr zu schreiben?

Gruß Michael
Wissen ist Macht.
Ich weiß nix.
Macht nix.

Otto123

Mein Fritzbox Device heisst FB7490, also steht in meiner DOIF DEF sowas in der Art. (Und do always ist gesetzt.)
Geht auch mit einem notify  8)
([FB7490:?lastReadout.*]) (starte die Abfrage)

Das heisst ich hänge mich an die zyklische Abfrage der Fritzbox dran.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

l2r

#67
jetzt ist es klar. Manchmal sieht man den Wald vor lauter Bäumen nicht mehr...

Danke

EDIT: und mit aktueller Syntax dann so: ([FB7490:"lastReadout"]) (starte die Abfrage)
Wissen ist Macht.
Ich weiß nix.
Macht nix.

xMichiix

Hallo,

hab mir jetzt mal so durchgelesen aber leider nichts mit einem speedport gefunden funktioniert das genauso oder nur mit einer fb?

Otto123

Mit Speedport bist Du ziemlich arm dran ...

Ich habe allerdings in den letzten Tagen eine mögliche Alternative entdeckt, die ziemlich unabhängig vom Router ist.
IFTTT (App auf dem Smartphone) kann auch WLAN connnect und disconnect erkennen und dann etwas tun, z.B. Mail schicken. Mit dem mailcheck Modul kann man Mails checken.
Die Kombination von beiden führt zu einem besseren Zeitverhalten zumindest beim WLAN abmelden, der Fritzbox braucht immer ewig bis sie erkannt hat, dass ein Gerät  nicht mehr da ist, das Gerät selbst merkt es logischerweise sofort.

Also mit IFTTT und mailcheck geht einiges, auch geofencing - und das alles ohne dass man irgendwas von FHEM im Internet freigeben muss.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

xMichiix

Guten Abend,

geht das auch wen man das FHEM auf einen raspi hat und ne Fritzbox ?

l2r

Wissen ist Macht.
Ich weiß nix.
Macht nix.

der_da

Da ich auch einen Repeater im Einsatz habe, der die Readings nicht vergisst sondern mit veralteten Zeitstempeln beibehält, wollte ich das aus dem Wiki übernommene sub für die Abfrage der Fritzbox(en) dahingehend modifizieren, dass eben auch das Alter des Zeitstempels herangezogen wird. Leider komme ich nicht weiter. Folgendes habe ich probiert:
sub checkAllFritzMACpresent($) {
  # Benötigt: nur die zu suchende MAC ($MAC),
  # Es werden alle Instanzen vom Type FRITZBOX abgefragt
  #
  # Rückgabe: 1 = Gerät gefunden
  #           0 = Gerät nicht gefunden
  my ($MAC) = @_;
  # Wird in keiner Instanz die MAC Adresse gefunden bleibt der Status 0
  my $Status = 0;
  $MAC =~ tr/:/_/;
  $MAC = "mac_".uc($MAC);
  my @FBS = devspec2array("TYPE=FRITZBOX");
    foreach( @FBS ) {
my $StatusFritz = ReadingsVal($_, $MAC, "weg");
if ($StatusFritz eq "weg")
} elsif ($StatusFritz eq "inactive") {
} elsif ((time() - time_str2num(ReadingsTimestamp($_,$MAC,0))) <600) {
} else {
  # Reading existiert, Rückgabewert ist nicht "inactive", also ist das Gerät am Netzwerk angemeldet.
  $Status = 1;
}
    }
  return $Status
}


Die Zeile
} elsif ((time() - time_str2num(ReadingsTimestamp($_,$MAC,0))) <600) {
habe ich eingefügt, in der Hoffnung, dass das die notwendige Eingrenzung macht. Allerdings ist FHEM damit nicht zufrieden. Kann mir einer helfen?
Danke!

l2r

Wissen ist Macht.
Ich weiß nix.
Macht nix.

juergen012

#74
Hallo, da ich auch einen Repeater mit dem gleichen Problem habe und die Modulentwickler wohl wenig Interesse haben hier Abhilfe zu schaffen, lösche ich alle 10 Min. die Readings aus dem Repeater:
+*00:10:00 deletereading RepeaterHome2 mac.*
Sie werden dann spätestens nach weiteren 60 Sekunden wieder neu eingelesen. Damit das Presence-Modul nicht falsche Werte anzeigt, habe ich im DOIF ein Wait von 45 eingetragen.
Gruß
Jürgen K.
Fhem unter Proxmox