Hallo zusammen,
ich habe schon seid längerem nach einer Lösung gesucht, wie ich mein Handy (Windows Phone) für das Presence-Modul verwenden kann. Bluetooth kam nicht in Frage, zu geringe Reichweite. Abfrage über Ping funktionierte nicht, da, wenn das Handy in Standby ging, es auch auf einen Ping nicht reagierte. Nach etwas Suchen kam ich dann aber doch auf eine funktionierende Lösung: ARP SCAN
http://de.wikipedia.org/wiki/Address_Resolution_Protocol
Über dieses Protokoll war es mir möglich, auch von "schlafenden" Devices eine Antwort zu erhalten. Damit das Ganze funktioniert, bedarf es unter Unix (Debian) des Programms "arp-scan". Dieses kann über "apt-get" installiert werden. Da der Befehl per "sudo" ausgeführt werden muss, bedarf es noch eines Eintrags in /etc/sudoers.
Anschliessend noch eine kleine Funktion in der myUtils:
sub
PresenceByMacAddress($)
{
my ($macAddress) = @_;
my $command = "sudo /usr/bin/arp-scan 192.168.20.0/24 | grep -i \"" . $macAddress . "\"";
my $result = qx/$command/;
if ($result ne "") {
return 1;
}
return 0;
}
Die IP-Range (192.168.20.0) müsst Ihr durch Eure IP-Range ersetzen. In den meisten Fällen 192.168.1.0 oder 192.168.254.0. Um rauszufinden, welche IP-Range Ihr habt, einfach mal nachschauen, welche IP-Adresse Eure Geräte zugewiesen bekommen haben, und die letzte Nummer durch 0 ersetzen.
Und die entsprechenden "PRESENCE"-Definitionen in der fhem.cfg:
define Handy1 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
define Handy2 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
Die Zeilen mit "xx" jeweils mit der Hardware-Adresse (MAC-Adresse) des jeweiligen Gerätes ersetzen.
Damit funktioniert nun auch die Anwesenheitserkennung bei mir. Vielleicht kann damit ja jemand auch was anfangen.
Gruss
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
Kann ich das ganze irgendwie manuell testen? Aktuell funktioniert es mit der Mac Adresse meines PCs nicht.
Eingebunden habe ich es wie folgt:
sub
PresenceByMacAddress($)
{
my ($macAddress) = @_;
my $command = "sudo /usr/bin/arp-scan 192.168.1.0/24 | grep -i \"" . $macAddress . "\"";
my $result = qx/$command/;
if ($result ne "") {
return 1;
}
return 0;
}
Das ist die Ausgabe im FHEM Log:
2015.05.29 11:51:54 5: PRESENCE (Handy1) - starting local scan
2015.05.29 11:51:54 5: PRESENCE (Handy1) - starting blocking call for mode function
2015.05.29 11:51:54 5: PRESENCE (Handy1) - execute perl function: Handy1|{PresenceByMacAddress("aa:bb:cc:dd:ee:ff")}|1
2015.05.29 11:51:54 5: PRESENCE (Handy1) - function returned with: 0
2015.05.29 11:51:54 5: PRESENCE (Handy1) - blocking scan result: Handy1|1|absent
Lasse ich das ganze im Terminal auf dem Pi laufen bekomme ich folgendes:
pi@raspberrypi ~ $ sudo /usr/bin/arp-scan 192.168.1.0/24 | grep -i aa:bb:cc:dd:ee:ff
192.168.1.99 aa:bb:cc:dd:ee:ff (Unknown)
Ich habe es vorhin erfolgreich getestet..
Aber ich habe den Code abgeändert..
Alt:
define Handy1 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:01")} 60 60
define Handy2 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:01")} 60 60
Neu:
define Handy1 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
define Handy2 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
..spich bei der MAC die "01" ersetzt
reload 99_myUtils gemacht ?
Gruß Kai
Hallo Jungs,
sorry für die "01" bei der MAC-Adresse, die muss natürlich raus. Der gesamte String muss durch Eure Mac-Adresse ersetzt werden.
@gloob: ist die MAC-Adresse im Fhem-Log genau die MAC-Adresse Deines Gerätes? Hast Du vielleicht die "01" noch hinten dran gelassen?
Gruss
als Tipp für die die nur WLAN benutzen, bei mir war eth0 als Standard eingestellt, musste somit den Befehl nur ein wenig abändern.
sub
PresenceByMacAddress($)
{
my ($macAddress) = @_;
my $command = "sudo /usr/bin/arp-scan 192.168.178.0/24 --interface=wlan0 | grep -i \"" . $macAddress . "\"";
my $result = qx/$command/;
if ($result ne "") {
return 1;
}
return 0;
}
Hello,
ich habe folgendes Problem.
Ich habe die funktion wie beschrieben in 99_myUtils.pm eingebaut und auch den define für den ARP Request auf das Windows Phone Handy gemacht.
Das ganze wird nun auch alle 60 Sekunden aufgerufen. Nur leider bleibt das Handy immer "absent"
Im Log bekomm ich immer die Meldung
/usr/bin/sudo: 1: /usr/bin/sudo: ��������
Im Sudoer habe ich folgende Einträge
fhem ALL = NOPASSWD:ALL
fhem ALL = NOPASSWD:/usr/bin/arp-scan
Woran könnte es noch liegen, dass es beim Aufruf der Funktion doch Zugriffsberechtigungsprobleme gibt ?
Zitat von: Charity am 07 Juni 2015, 12:23:42
Hello,
ich habe folgendes Problem.
Ich habe die funktion wie beschrieben in 99_myUtils.pm eingebaut und auch den define für den ARP Request auf das Windows Phone Handy gemacht.
Das ganze wird nun auch alle 60 Sekunden aufgerufen. Nur leider bleibt das Handy immer "absent"
Im Log bekomm ich immer die Meldung
/usr/bin/sudo: 1: /usr/bin/sudo: ��������
Im Sudoer habe ich folgende Einträge
fhem ALL = NOPASSWD:ALL
fhem ALL = NOPASSWD:/usr/bin/arp-scan
Woran könnte es noch liegen, dass es beim Aufruf der Funktion doch Zugriffsberechtigungsprobleme gibt ?
Hallo,
Du hast den Eintrag in der sudoer Datei nicht ganz richtig.
Müsste so funkonieren:
fhem ALL = (root) NOPASSWD:/usr/bin/arp-scan
Oder
fhem ALL = (ALL) NOPASSWD:/usr/bin/arp-scan
Worin genau der Unterschied liegt kann ich dir jetzt nicht sagen. Aufjedenfall muss nach dem ALL= noch all oder root in klammern stehen. Dann dürfte es klappen.
Gruß
Miggi
Gesendet von meinem OnePlus One mit Tapatalk.
Hi,
erstmal danke, aber der Eintrag
fhem ALL = (root) NOPASSWD:/usr/bin/arp-scan
hat auch nichts gebracht. Muss die Kiste ev. dafür durchgestartet werden ?
Zitat von: Charity am 07 Juni 2015, 13:43:20
Hi,
erstmal danke, aber der Eintrag
fhem ALL = (root) NOPASSWD:/usr/bin/arp-scan
hat auch nichts gebracht. Muss die Kiste ev. dafür durchgestartet werden ?
Also ein Neustart ist nicht nötig. Ist aber komisch, dass es nicht funktioniert.
Habe es genauso und bei mir funktioniert es.
Vlt braucht es ein klein wenig Zeit bis es funktioniert. Aber das müsste so passen.
Gesendet von meinem OnePlus One mit Tapatalk.
Kann es sein, dass der Eintrag in der sudoers
fhem ALL = NOPASSWD:ALL
fhem ALL = (root) NOPASSWD:/usr/bin/arp-scan
so nicht passt ?
Zitat von: Charity am 07 Juni 2015, 13:55:17
Kann es sein, dass der Eintrag in der sudoers
fhem ALL = NOPASSWD:ALL
fhem ALL = (root) NOPASSWD:/usr/bin/arp-scan
so nicht passt ?
Den ersten Eintrag brauchst du nicht.
(fhem ALL = NOPASSWD:All)
Gesendet von meinem OnePlus One mit Tapatalk.
@Charity
Mich irritieren die schwarzen Vierecke etwas. Sind diese exakt so im Log drin?
@talkabout: ja, nur füllen diese die ganze Zeile. Ich hab nicht alle eingefügt.
@miggi: Leider hat das entfernen der ersten Zeile auch nichts gebracht
@Charity
Das sieht mir irgendwie nach einem Encoding-Problem aus. Kannst Du die Code Zeilen mal über einen Texteditor in der Datei speichern, der in ASCII schreibt?
@Talkabout : welche Codezeilen? Jene die in der 99_myUtil die Funktion beinhalten ?
@Charity
Jep, genau die. Ich könnte mir vorstellen, dass da was beim Copy&Paste schief gelaufen ist.
Gruss
@Talkabout : Danke. Das war jetzt gar nicht so einfach :-)
Ascii ist UTF-8 als UTF-8 hab ich das File nun gespeichert und mit WinSCP wieder hochgeladen. Doch auch da hat WinSCP ein wenig reingespuckt.
Und das File in Binary hochgeladen. Nachdem ich nun den Mode auf Text umgestellt habe kommt die Meldung nicht mehr im Log.
Leider bleibt das Handy aber immer noch offline.
Kann ich das irgendwie testen ? den in der Linux Command kommt ein ergebnis retour
@Charity
Kannst DU mal bitte in Deinen Utils den Aufruf wegloggen:
Log3 "command", 3, $command;
vor die Zeile mit "my $result..." einfügen, dann sollte beim Aufruf ein Log-Eintrag entstehen, der den abgeschickten Befehl anzeigt.
Gruss
Zitat von: Charity am 07 Juni 2015, 20:35:40
@talkabout: ja, nur füllen diese die ganze Zeile. Ich hab nicht alle eingefügt.
@miggi: Leider hat das entfernen der ersten Zeile auch nichts gebracht
Schreib mal anstatt dem root ein ALL rein. Schau ob das dann so klappt.
Gesendet von meinem OnePlus One mit Tapatalk.
Erstmal ein großes Danke für eure Unterstützung !
@Talkabout : der Log sieht nun so aus
2015.06.07 22:01:04 3: sudo /usr/bin/arp-scan 192.168.0.0/24 | grep -i "74:E2:8C:4D:0E:66"
@miggi : der Eintrag in der sudoers sieht nun so aus
fhem ALL = (ALL) NOPASSWD:/usr/bin/arp-scan
Mit dem gleichen Ergebnis -> immer noch offline
Zitat von: Charity am 07 Juni 2015, 22:03:30
Erstmal ein großes Danke für eure Unterstützung !
@Talkabout : der Log sieht nun so aus
2015.06.07 22:01:04 3: sudo /usr/bin/arp-scan 192.168.0.0/24 | grep -i "74:E2:8C:4D:0E:66"
@miggi : der Eintrag in der sudoers sieht nun so aus
fhem ALL = (ALL) NOPASSWD:/usr/bin/arp-scan
Mit dem gleichen Ergebnis -> immer noch offline
Komisch hab das genauso drin.
Hast du die Datei mit Hilfe von dem Befehl visudo geändert?
Gesendet von meinem OnePlus One mit Tapatalk.
@miggi : Nein, im Texteditor von WinSCP.
Aber ich werde es gleich mal mit visudo nochmal machen
@Charity:
Eigentlich sollte das "-i" die Groß-/Kleinschreibung ignorieren, aber probiere mal die MAC-Adresse mit Kleinbuchstaben an die Funktion zu übergeben.
Gruss
Zitat von: Talkabout am 28 Mai 2015, 20:06:53
Hallo zusammen,
ich habe schon seid längerem nach einer Lösung gesucht, wie ich mein Handy (Windows Phone) für das Presence-Modul verwenden kann. Bluetooth kam nicht in Frage, zu geringe Reichweite. Abfrage über Ping funktionierte nicht, da, wenn das Handy in Standby ging, es auch auf einen Ping nicht reagierte. Nach etwas Suchen kam ich dann aber doch auf eine funktionierende Lösung: ARP SCAN
http://de.wikipedia.org/wiki/Address_Resolution_Protocol
Über dieses Protokoll war es mir möglich, auch von "schlafenden" Devices eine Antwort zu erhalten. Damit das Ganze funktioniert, bedarf es unter Unix (Debian) des Programms "arp-scan". Dieses kann über "apt-get" installiert werden. Da der Befehl per "sudo" ausgeführt werden muss, bedarf es noch eines Eintrags in /etc/sudoers.
Anschliessend noch eine kleine Funktion in der myUtils:
sub
PresenceByMacAddress($)
{
my ($macAddress) = @_;
my $command = "sudo /usr/bin/arp-scan 192.168.20.0/24 | grep -i \"" . $macAddress . "\"";
my $result = qx/$command/;
if ($result ne "") {
return 1;
}
return 0;
}
Die IP-Range (192.168.20.0) müsst Ihr durch Eure IP-Range ersetzen. In den meisten Fällen 192.168.1.0 oder 192.168.254.0. Um rauszufinden, welche IP-Range Ihr habt, einfach mal nachschauen, welche IP-Adresse Eure Geräte zugewiesen bekommen haben, und die letzte Nummer durch 0 ersetzen.
Und die entsprechenden "PRESENCE"-Definitionen in der fhem.cfg:
define Handy1 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
define Handy2 PRESENCE function {PresenceByMacAddress("xx:xx:xx:xx:xx:xx")} 60 60
Die Zeilen mit "xx" jeweils mit der Hardware-Adresse (MAC-Adresse) des jeweiligen Gerätes ersetzen.
Damit funktioniert nun auch die Anwesenheitserkennung bei mir. Vielleicht kann damit ja jemand auch was anfangen.
Gruss
Hallo,
Kurze Frage ist es bei dir auch so, dass die Geräte immer im regelmäßigem Abstand anwesend und abwesend ist, obwohl das Handy immer im wlan ist?
Im Screenshot sieht man es auch.
Gesendet von meinem OnePlus One mit Tapatalk.
@miggi
Ja, es kommt vor, dass das Handy als absent angezeigt wird. Woran es genau liegt weiss ich nicht, aber es könnte sein, dass die ARP-Listen zu dem Zeitpunkt aktualisiert werden.
Man kann das umgehen, indem man beim Presence-Modul den zweiten Zahlenwert erhöht, damit erst beim 2. oder 3. Check als abwesend gekennzeichnet wird.
Gruss
Zitat von: Talkabout am 07 Juni 2015, 22:23:18
@miggi
Ja, es kommt vor, dass das Handy als absent angezeigt wird. Woran es genau liegt weiss ich nicht, aber es könnte sein, dass die ARP-Listen zu dem Zeitpunkt aktualisiert werden.
Man kann das umgehen, indem man beim Presence-Modul den zweiten Zahlenwert erhöht, damit erst beim 2. oder 3. Check als abwesend gekennzeichnet wird.
Gruss
Okey alles klar.
Der erste wert ist die Zeit in Sekunden in der nachgeschaut wird richtig?
Somit ist 60 60
Das jede Minute nachgesehen wird und jede Minute der Wert sich ändert oder?
Gesendet von meinem OnePlus One mit Tapatalk.
@miggi
richtig, der 2 Wert gibt an nach wie viel Zeit sich der Status dann ändert, wenn das Device nicht gefunden wird.
Gruss
@Talkabout : Ich hab den Fehler gefunden.
In der Linux Shell hat sudo auch nicht funktioniert. Hab nun sudo erneut installiert und jetzt funktioniert es !
Danke euch
Servus zusammen,
funktioniert das bei euch? Bei mir wechselt der Zustand permanent zwischen absent und present. 20 Sekunden Absent und dann mal 20 - 30 Present.
Eigentlich eine gute Idee aber funktioniert nicht so richtig bei mir.
Wie ist das bei euch?
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
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?
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
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
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;
}
}