$zeit sind die Minuten, bevor Anwesenheit_Name auf off geht
define Anwesenheit_Name dummy
attr Anwesenheit_Name room Anwesenheit
set Anwesenheit_Name off
define count_Name dummy
set count_Name 0
define Job_AnwesendName at +*00:01:00 { \
my $zeit = 5;; \
use Net::Ping;; \
my $ip = "IP-Adresse";; \
my $p = Net::Ping->new("icmp", 9, 64);; \
my $pingtest = $p->ping($ip);; \
my $cn = Value("count_Name");; \
my $n = $zeit-1;; \
if ($pingtest && $cn != 0) { \
fhem("set count_Name 0");; \
} \
if ($pingtest && ($value{Anwesenheit_Name} eq "off")) { \
fhem("set Anwesenheit_Name on");; \
fhem("set count_Name 0");; \
} \
elsif (!($pingtest) && $value{Anwesenheit_Name} eq "on") { \
if ($cn == 0) { \
fhem("set count_Name 1");; \
} \
elsif ($cn != 0 && $cn < $n){ \
$cn=$cn+1;; \
fhem("set count_Name ".$cn);; \
} \
elsif ($cn == $n){ \
fhem("set count_Name 0");; \
fhem("set Anwesenheit_Name off");; \
} \
} \
}
Vielen Dank.
Es Klappt wirklich auch mit Problem Handys wo öfters mal der Ping nicht klappt.
DANKE !!!
Moin,
danke für deinen Code! Problem hier ist, dass für
Net::Ping->new("icmp") root-Rechte nötig sind. Es gibt noch Net::Ping::External (was sich in Net::Ping über "external" statt "icmp" aufrufen lässt). Das funktioniert leider nicht aus dem Stand in fhem, da in fhem.pl der Signalhandler für SIGCHLD auf IGNORE gesetzt wird (das hat mich grade anderthalb Stunden gekostet das zu debuggen :)). Und wenn wir eh schon dabei sind, ein externes Programm aufzurufen, können wir auch gleich arping nehmen, das spart dann einen Layer (für jegliche Kommunikation in einem Ethernet braucht man eh ARP, und wenn's nur um das Vorhandensein des Hosts geht reicht nur ARP ja auch). Hier also mein Vorschlag für den Job:
(Das arping-Tool muss installiert und suid root sein. Ausserdem probiere ich standardmäßig pro Durchlauf 3 Versuche, da nicht jeder klappt. Ich vermute da eine Art rate limiting in meinem Handy als Ursache.)
define Job_AnwesendName at +*00:01:00 { \
my $zeit = 5;; \
my $ip = "IP-Adresse";; \
my $pingtest = 1;; \
my $repeat = 3;; \
while($pingtest == 1 && $repeat-- > 0) { \
local $SIG{CHLD}='';; \
system("arping -c 1 $ip > /dev/null 2> /dev/null");; \
$pingtest = $? >> 8;; \
} \
$pingtest = ! $pingtest ;; \
my $cn = Value("count_Name");; \
my $n = $zeit-1;; \
if ($pingtest && $cn != 0) { \
fhem("set count_Name 0");; \
} \
if ($pingtest && ($value{Anwesenheit_Name} eq "off")) { \
fhem("set Anwesenheit_Name on");; \
fhem("set count_Name 0");; \
} \
elsif (!($pingtest) && $value{Anwesenheit_Name} eq "on") { \
if ($cn == 0) { \
fhem("set count_Name 1");; \
} \
elsif ($cn != 0 && $cn < $n){ \
$cn=$cn+1;; \
fhem("set count_Name ".$cn);; \
} \
elsif ($cn == $n){ \
fhem("set count_Name 0");; \
fhem("set Anwesenheit_Name off");; \
} \
} \
}
Anmerkungen:
local $SIG{CHLD}='';; ist nötig, damit der Exit-Wert des Kindes von wait (was intern von system aufgerufen wird) geholt werden kann.
$pingtest = $? >> 8;; holt den Exit-Wert des Kindes. Der Statuswert von wait enthält den nämlich mit noch anderen Dingen zusammengemixt. $pingtest = ! $pingtest ;; macht dass der Exit-Wert den Erwartungen des Restcodes entspricht. Konterintuitiv ist nämlich 0 gleich "Host hat sich gemeldet" und 1 gleich "Host hat sich nicht gemeldet".[/list]
--
Henryk Plötz
Grüße aus Berlin
Moin Henryk,
du kannst auch einfach bei Net::Ping mit einem anderen Verfahren arbeiten.
Bei mir hat sich
Net::Ping->new('syn');
bewährt.
Das funktioniert zügig, sicher und mit wenig Ressourcenaufwand...
Aber unter http://search.cpan.org/~smpeters/Net-Ping-2.36/lib/Net/Ping.pm#Functions (//search.cpan.org/~smpeters/Net-Ping-2.36/lib/Net/Ping.pm#Functions) sind auch noch andere Verfahren beschrieben, die dieses Ping durchführen kann...
Grüße Reinerlein
Moin,
Zitat von: Reinerlein schrieb am Fr, 25 Januar 2013 08:58du kannst auch einfach bei Net::Ping mit einem anderen Verfahren arbeiten.
Radio Eriwan antwortet: Im Prinzip ja, aber nicht mit tcp (mein Handy bietet keine Dienste an), udp (mein Handy bietet keine Dienste an), icmp (braucht Root-Rechte), stream (ist auch nur tcp) oder syn (ist auch nur tcp). :-)
--
Henryk Plötz
Grüße aus Berlin
hm ich habe nun auch ein Handy was sich nach einer Stunde per icmp nicht mehr erreichen lässt wäre mal ne idee andere Pings zu versuchen ;)
Ich habe die Überarbeitete Variante von henryk genommen und die Variable $ip geändert:
define Anwesenheit_Name dummy
attr Anwesenheit_Name room Anwesenheit
define count_Name dummy
define Job_AnwesendName at +*00:05:00 { \
my $zeit = 5;; \
my $ip = "192.168.1.3";; \
my $pingtest = 1;; \
my $repeat = 3;; \
while($pingtest == 1 && $repeat-- > 0) { \
local $SIG{CHLD}='';; \
system("arping -c 1 $ip > /dev/null 2> /dev/null");; \
$pingtest = $? >> 8;; \
} \
$pingtest = ! $pingtest ;; \
my $cn = Value("count_Name");; \
my $n = $zeit-1;; \
if ($pingtest && $cn != 0) { \
fhem("set count_Name 0");; \
} \
if ($pingtest && ($value{Anwesenheit_Name} eq "off")) { \
fhem("set Anwesenheit_Name on");; \
fhem("set count_Name 0");; \
} \
elsif (!($pingtest) && $value{Anwesenheit_Name} eq "on") { \
if ($cn == 0) { \
fhem("set count_Name 1");; \
} \
elsif ($cn != 0 && $cn < $n){ \
$cn=$cn+1;; \
fhem("set count_Name ".$cn);; \
} \
elsif ($cn == $n){ \
fhem("set count_Name 0");; \
fhem("set Anwesenheit_Name off");; \
} \
} \
}
Außerdem habe ich auf meiner Raspberry Pi arping installiert.
Leider ändern sich der Status nicht.
Ist die Version veraltet ?
Was heißt suid muss root sein ?
Liebe Grüße aus Berlin
bei mir funzt es auch nicht >:(
Ich habe meine Anwesenheitserkennung mit einem PRESENCE Modul kombiniert mit einem Watchdog aufgebaut. Wird 5 Minuten keines der Handys gefunden sind wir abwesend. Könnte das euer Problem lösen?