Hauptmenü

Presence

Begonnen von Talkabout, 28 Mai 2015, 20:06:53

Vorheriges Thema - Nächstes Thema

Jorge3711

Habe das eben auf meiner FHEM Testinstallation eingebaut, und bisher (10 Minuten) bleibt der Status der jeweiligen Handys stabil.

Danke für die Umsetzung. Einen Hinweis oder Anregung habe ich aber noch. Ich mag nicht minütlich mein gesamtes Netzwerk per Broadcast scannen, weshalb ich den Suchbereich über die Netzwerkmaske eingegrenzt habe:


sub
PresenceByMacAddress($)
{
my ($macAddress) = @_;
        my $command      = "sudo /usr/bin/arp-scan 192.168.0/29 | grep -i \"" . $macAddress . "\"";
my $result       = qx/$command/;
        if ($result ne "") {
        return 1;
        }
        return 0;
}


Per DHCP habe ich in meinem Router den Handys in einem engen IP-Bereich fest IPs zugewiesen. Die "/29" sorgt dafür, dass 6 Adressen (192.168.0.1 -192.168.0.6) per Broadcast gescannt werden. Das behelligt das Netzwerk deutlich weniger, als wenn man alle 60 Sekunden 254 mögliche Adressen scannt. Und schneller geht es auch noch.

Grüße Carsten

P.A.Trick

Zitat von: JoWiemann am 28 Mai 2015, 22:19:56
Schöne Idee. Leider findet arp-scan bei Handys die an einem Repeater angemeldet sind immer nur die MAC des Repeaters.

Grüße Jörg

Könnte man nicht noch optional die IP Adresse mitgeben und versuchen diese dann zu finden?
Cubietruck,RPI,QNAP Ts-419p+, FS20, FRITZ!DECT200, 7 MAX! Thermostate, 3 MAX! Fensterkontakte, Kodi, CUL V3.3, EM1000S, LW12, LD382, HUE, HM-CFG-USB-2, 1x HM-LC-SW1-FM, 2x HM-LC-SW2-FM, 2x HM-LC-Sw1PBU-FM, 3xHM-LC-Bl1PBU-FM,HM-SEC-RHS, 2xHM-SEC-SD,HM-WDS30-T-O, 3x HM-LC-Dim1TPBU-FM, RPI+AddOn

Jorge3711

Zitat von: Jorge3711 am 14 Juni 2015, 14:56:12
Habe das eben auf meiner FHEM Testinstallation eingebaut, und bisher (10 Minuten) bleibt der Status der jeweiligen Handys stabil.

Muss mich etwas korrigieren, das iPhone wird nicht mehr gefunden, nachdem es in den Sleep Mode gegangen ist. Sobald ich das iPhone in die Hand nehme und entsperre ist es wieder "present". Das WP bleibt hingegen scanbar.

Grüße Carsten

knxhm

Hallo,

hab hier noch eine andere Methode anzubieten die bei mir mit Moto G2 (Android 5.0), Alcatel Idol2 (Android 4.3), Nokia620 (WP8.1)  gut funktionieren.
Man fragt ab ob ein WLAN Endgerät am AP "associated" ist.

Erfordert einen WLAN Router oder Access Point der unter Linux läuft bzw das tool iw unterstützt und awk sollte er auch installiert haben,
z.B. ein OPENWRT Router.
Am FHEM brauch man zusätzlich noch sshpass, kann man einfach wie üblich mit "apt-get install sshpass" installieren.

Es werden bei der Abfrage vom WLAN Router keine Pakete an das WLAN Gerät geschickt, sollte also 0 Auswirkung auf die Batterielebensdauer haben. Mit sshpass kann man ein shell Kommando auf einem entfernten host (also dem AP) ausführen. Ich nutze sshpass um das tool iw am entfernten WLAN Router auszuführen.

Dazu schreibt man folgende Funktion in 99_myUtils, daspasswort, deruser, dierouterip sind entsprechend anzupassen.

#http://forum.fhem.de/index.php/topic,37598.0.html
sub
PresenceByAssociatedMac($)
{
        my ($macAddress) = @_;
        my $command = "sshpass -p".chr(34)."daspasswort".chr(34)." ssh -o StrictHostKeyChecking=no deruser\@dierouterip ".chr(34)."iw dev wlan0 station get ".$macAddress.chr(34)." 2>/dev/null | awk \'NR==10   { print \$1 }\'";
        my $result       = qx/$command/;
        if ($result eq "signal\n") {
            return 1;
        }
        return 0;
}


In der fhem config dann aufrufen mit

define handy1 PRESENCE function {PresenceByAssociatedMac('xx:xx:xx:xx:xx:xx')} 30 30

statt xx:xx:xx:xx:xx:xx die MAC Adresse der zu überwachenden Geräte angeben, man braucht für jedes Gerät ein ""define".

Eine Bemerkung am Rande, ich habe zuerst vesucht nur den Return code von iw auszuwerten (=0 wenn mac gefunden, -254 wenn nicht) aber ich habs nicht geschafft das in der if Abfrage auszuwerten. Dann hätte man sich die awk Geschichte sparen können.

Nun viel Spass bei der erweiterten Qual der Wahl welche PRESENCE Methode denn nun zur Anwendung kommen soll.

Und danke an Talkabout der mir eine gute Ausgangsbasis für diese Variation der Presence Detection geliefert hat.

lg
KNX, HM, HMLAN, RPi 2 mit Raspbian Jessie, knxd und FHEM, 1w Temperaturmessung mit gpio4, Dämmerungssensor, autom. Rolladensteuerung

Retar

knxhm die Idee mit dem AP nach Clients abfragen hatte ich auch und solange FHEM auf der selben Box (OpenWRT) lief, wars auch einfach. Alle 30 Sekunden ein SSH machen geht zwar, aber ist schon einiges an Overhead und das Syslog des OpenWRT wird danach nicht mehr lesbar sein.

Hier eine ebenso passive Alternative mit dem OpenWRT-Integrierten Webserver - FHEM fragt per http beim AP nach, ob der Client da ist (benötigt bash auf dem AP) ( /www/cgi-bin/wifi-client ):
#!/bin/bash

# Decodes an URL-string
# an URL encoding has "+" instead of spaces
# and no special characters but "%HEX"
function urlDec() {
  local value=${*//+/%20}                   # replace +-spaces by %20 (hex)
  for part in ${value//%/ \\x}; do          # split at % prepend \x for printf
    printf "%b%s" "${part:0:4}" "${part:4}" # output decoded char
  done
}

# For all given query strings
# parse them an set shell variables
function setQueryVars() {
  local vars=${*//\*/%2A}                      # escape * as %2A
  for var in ${vars//&/ }; do                  # split at &
    local value=$(urlDec "${var#*=}")          # decode value after =
    value=${value//\\/\\\\}                    # change \ to \\ for later
    eval "CGI_${var%=*}=\"${value//\"/\\\"}\"" # evaluate assignment
  done
}

# Execute the evaluation
# set all variables for both, POST and GET data
setQueryVars $QUERY_STRING $(</dev/stdin)

echo Content-type: text/plain
echo

case $CGI_dev in
        *[!0-9a-f:]*|"") echo "NOK MAC"; exit 0;;
esac

# Pfade anpassen je nach AP-Config!!
if [ -d "/sys/kernel/debug/ieee80211/phy1/netdev:wlan1/stations/$CGI_dev" ] || [ -d "/sys/kernel/debug/ieee80211/phy0/netdev:wlan0-1/stations/$CGI_dev" ]; then
        echo "connected"
else
        echo "no device"
fi


Perl Funktion (MAC nur in Kleinbuchstaben)
sub wlan_det($) {
        my ($client)= @_;

        my $ua = new LWP::UserAgent;

        my $response = $ua->get('http://<IP des APs>/cgi-bin/wifi-client?dev='.$client);

        unless ($response->is_success) {
                return 99;
        }

        my $content = $response->decoded_content();

        if ($content =~ m/connected/) {
                return 1;
        } else {
                return 0;
        }
}