Abwesenheit Script mit Verzögerung

Begonnen von fhem86, 23 Januar 2013, 17:54:38

Vorheriges Thema - Nächstes Thema

fhem86

$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");; \
        } \
} \
}


ChrisW

Vielen Dank.
Es Klappt wirklich auch mit Problem Handys wo öfters mal der Ping nicht klappt.

DANKE !!!
Raspberry PI3 mit allem möglichen.

henryk

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

    Reinerlein

    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 sind auch noch andere Verfahren beschrieben, die dieses Ping durchführen kann...

    Grüße Reinerlein

    henryk

    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

    ChrisW

    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 ;)
    Raspberry PI3 mit allem möglichen.

    nocomment

    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

    andrece


    Towelie

    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?