FHEM Forum

FHEM => Codeschnipsel => Thema gestartet von: fhem86 am 23 Januar 2013, 17:54:38

Titel: Abwesenheit Script mit Verzögerung
Beitrag von: fhem86 am 23 Januar 2013, 17:54:38
$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");; \
        } \
} \
}

Titel: Aw: Abwesenheit Script mit Verzögerung
Beitrag von: ChrisW am 23 Januar 2013, 19:41:53
Vielen Dank.
Es Klappt wirklich auch mit Problem Handys wo öfters mal der Ping nicht klappt.

DANKE !!!
Titel: Aw: Abwesenheit Script mit Verzögerung
Beitrag von: henryk am 25 Januar 2013, 03:38:38
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
  • Titel: Aw: Abwesenheit Script mit Verzögerung
    Beitrag von: Reinerlein am 25 Januar 2013, 08:58:31
    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
    Titel: Aw: Abwesenheit Script mit Verzögerung
    Beitrag von: henryk am 25 Januar 2013, 09:16:19
    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
    Titel: Aw: Abwesenheit Script mit Verzögerung
    Beitrag von: ChrisW am 25 Januar 2013, 09:33:02
    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 ;)
    Titel: Antw:Abwesenheit Script mit Verzögerung
    Beitrag von: nocomment am 21 Januar 2014, 15:38:32
    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
    Titel: Antw:Abwesenheit Script mit Verzögerung
    Beitrag von: andrece am 07 Juli 2014, 13:20:37
    bei mir funzt es auch nicht >:(
    Titel: Antw:Abwesenheit Script mit Verzögerung
    Beitrag von: Towelie am 07 Juli 2014, 13:43:50
    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?