Hallo Markus,
zunächst mal herzlichen Dank für Dein PRESENCE-Modul! Das spart mir viel Arbeit, denn sonst hätte ich mir selbst eine ping-Abfrage zimmern müssen.
Allerdings geht es in meinem Fall gar nicht um An-/Abwesenheitserkennung. Vielmehr möchte ich in FHEM den Schlaf-/Wach-Status diverser Geräte in meinem lokalen Netzwerk erfassen (hauptsächlich Computer, aber auch anderer Geräte wie z.B. ein Projektor).
Das zeigt, dass PRESENCE viel universeller verwendbar ist, als Du vielleicht zunächst im Sinn hattest. Aber für diese erweiterte Anwendung wären ein paar Ergänzungen optimal.
Konkret hätte ich zwei Vorschläge/Wünsche:
1. Ein einstellbarer Ping-Count. Du hast den Count im Moment fest auf 4 gesetzt. Für den Anwendungsfall, den Du im Kopf hattest, ist das sicher sinnvoll. Für meinen Anwendungsfall wäre 1 oder 2 viel besser, da sich dann einerseits eine zeitnahere Statusanzeige verwirklichen lässt, während andererseits die Zuverlässigkeit bei verkabelten Netzwerkgeräten hoch genug ist, dass 1 oder 2 ausreicht.
Mein Vorschlag für den Aufruf wäre:
define <name> PRESENCE lan-ping <ip-address> [ <check-interval> [ <present-check-interval> [<ping-count>] ] ]
(Man muss dann zwar immer auch present-check-interval angeben, wenn man ping-count spezifizieren will, aber das ist ja kein großes Problem.)
2. Ein zusätzlicher Modus "shellscript". Es kann Spezialfälle geben, wo eine zyklische Ping- (oder auch Bluetooth-)Abfrage nicht funktioniert, aber andere zyklische Abfragen möglich wären. Mein Projektor ist so ein Fall: Der antwortet auch im Ruhezustand auf Pings, aber über ein spezielles TCP-Kommando lässt sich der Ruhe-/Wachzustand abfragen. Solche Spezialfälle ließen sich prima integrieren, wenn PRESENCE alternativ die Spezifikation eines individuellen Shellscripts erlauben würde, das als Exit-Wert 0 bei Anwesenheit/Wachzustand und 1 bei Abwesenheit/Schlafzustand zurückliefern muss.
Mein Vorschlag für den Aufruf wäre:
define <name> PRESENCE shellscript </path/to/script> [ <check-interval> [ <present-check-interval>] ]
Beides müsste sich ja ziemlich einfach in PRESENCE ergänzen lassen (ich dachte aber, es ist besser, wenn Du das machst, statt dass ich in Deinem Modul herumfummle) und würde den Einsatzbereich erweitern.
Hallo Uli,
Ja, das währe möglich. Kann ich aber erst in einer Woche machen, wenn ich wieder aus dem Urlaub zurück bin.
Viele Grüße
Markus
Zitat von: Markus Bloch schrieb am Sa, 30 März 2013 09:06Ja, das währe möglich.
Klasse, vielen Dank! :)
ZitatKann ich aber erst in einer Woche machen, wenn ich wieder aus dem Urlaub zurück bin.
Logo, null Problem!
Dir einen schönen Osterurlaub!
Uli
es wäre schön statt dem shellscript auch eine perl funktion aufrufen zu können. rückgabe wert auch 0 oder 1. etwa so wie an anderen stellen in fhem auch:define <name> PRESENCE {...} [ <check-interval> [ <present-check-interval>] ]
dann hätte ich endlich meine snmp wlan erkennung :)
gruss
andre
Zitat von: justme1968 schrieb am Sa, 30 März 2013 17:30es wäre schön statt dem shellscript auch eine perl funktion aufrufen zu können. rückgabe wert auch 0 oder 1. etwa so wie an anderen stellen in fhem auch:
Wie ist das eigentlich generell bei Perl-Funktionen, die auf diese Art in FHEM (
fhem.cfg) konfiguriert werden? Werden die
einmal kompiliert beim Einlesen von
fhem.cfg, oder bei jedem einzelnen Aufruf der Funktion
erneut?
Denn wenn letzteres, ergäbe eine Perl-Funktion hier von der CPU-Belastung her nicht so viel Sinn, da sie alle paar Sekunden neu kompiliert werden müsste.
zum einen wäre selbst das resourcen schonender als ein shellscript aufzurufen zum anderen musst du ja nicht ein ganzes programm in der perlfunc unterbringen sondern z.b. nur den aufruf einer funktion in 99_myUtils.
gruss
andre
Zitat von: justme1968 schrieb am Mo, 01 April 2013 15:58zum einen wäre selbst das resourcen schonender als ein shellscript aufzurufen
"shellscript" ist vielleicht ein unglücklicher Ausdruck dafür, etwas über die Shell (in Kontrast zu FHEM's direktem Perl-Zugriff) aufzurufen, was ja durchaus auch ein kompiliertes C-Programm sein kann.
Ich hatte das Problem mit einem kleinen Progrämmchen, das nur eine ganz kurze TCP-Kommunikation mit einem Gerät im Netzwerk durchführt: Zuerst schnell in Perl geschrieben, hat es bei jeder Ausführung kurzzeitig eine CPU-Last von ca. 70% erzeugt und eine user time von ca. 0,7s beansprucht. Deswegen habe ich es dann in C reimplementiert, da braucht es 0,02s user time; die CPU-Last konnte ich aufgrund der Kürze der Zeit gar nicht erfassen. Ist also schon ein Riesenunterschied.
Zitatzum anderen musst du ja nicht ein ganzes programm in der perlfunc unterbringen sondern z.b. nur den aufruf einer funktion in 99_myUtils.
Da hast Du natürlich recht. :) Auf diese naheliegende Idee bin ich nicht gekommen - gut, es ist auch noch nicht klar, ob Perl-Aufrufe in PRESENCE gehen werden, aber das allein ist natürlich bereits ein starkes Argument dafür.
Zitat von: justme1968 schrieb am Sa, 30 März 2013 17:30es wäre schön statt dem shellscript auch eine perl funktion aufrufen zu können. rückgabe wert auch 0 oder 1. etwa so wie an anderen stellen in fhem auch:define <name> PRESENCE {...} [ <check-interval> [ <present-check-interval>] ]
dann hätte ich endlich meine snmp wlan erkennung :)
gruss
andre
Kannst du mir mal fix ein Beispiel zeigen, damit ich mal Guttenbergen kann? ;-)
schau mal hier: Link (http://forum.fhem.de/index.php?topic=11768.msg71364#msg71364)
gruss
andre
Da werden die Kommandos aber nur ausgeführt und nicht das Ergebnis evaluiert. Das Ausführen generell ist kein Problem, das Problem ist aber aus so einer Befehlskette einen Rückgabewert zu erhalten.
Viele Grüße
Markus
schau dir devState icon in fhem.pl an. da kann man icon und kommando zurueck geben.
gruss
andre
alles klar :-)
Vielen Dank
Mach ich. Ich denke mal am Wochenende kann ich das machen. Dann wahrscheinlich aber erstmal nur als Patch wegen 5.4 Release, da das ja ein neues Feature währe ;-)
Viele Grüße
Markus
Hallo zusammen,
ab morgen gibts via update eine neue PRESENCE Version:
folgende Neuerungen:
Neuere Mode: shellscript:
define <name> PRESENCE shellscript </path/to/script> [ <check-interval> [ <present-check-interval> ] ]
Bsp:
define Handy PRESENCE shellscript "/opt/test_bluetooth_ping.sh 7C:61:93:6D:5F:0B" 30 60
Neuere Mode: function:
define <name> PRESENCE function {...} [ <check-interval> [ <present-check-interval> ] ]
Bsp:
define Test PRESENCE function {snmpCheck()} 30 60
Beide Modis sind aktuell noch nicht in der Doku, da ich mal so langsam zu Bett gehen müsste ;-)
Bitte probiert mal beide Sachen aus und gebt Feedback. Die Doku werde ich noch nachreichen.
Viele Grüße
Markus
Toll, danke! Probiere ich gleich morgen aus. :)
Kleine Infos zu den Rückgabewerten (hatte ich ganz vergessen).
shellscript: Das Skript muss eine 0 (abwesend) oder 1 (anwesend) auf der Konsole ausgeben. Der exit-Code wird nicht ausgewertet.
function: Die Funktion muss als return-Wert 0 oder 1 zurückgeben.
Viele Grüße
Markus
hallo markus,
das schaut klasse aus. mein anwesenheitscheck per smnp auf meine airport basestation funktioniert wunderbar. code unten falls es noch jemand brauchen kann. anlegen mit ip der basis station und mac des telefons als hex zahl:define iPhoneAndre PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")} 30 30
nur zwei dinge sind mit aufgefallen:
- wenn ich das check intervall weg lasse bekomme ich den fehler: check-interval must be a number
- es wird bei jedem check noch was ins log geschrieben. ich vermute mal das ist noch absicht.
gruss
andre
sub
snmpCheck($$)
{
my ($airport,$client)= @_;
my $community = "public";
my $host = $airport;
my $oid = ".1.3.6.1.2.1.3.1.1.2";
#my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";
my ( $session, $error ) = Net::SNMP->session(
-hostname => $host,
-community => $community,
-port => 161,
-version => 1
);
if( !defined($session) ) {
return 0;
return "Can't connect to host $host.";
}
my @snmpoids = ();
my $response = $session->get_next_request($oid);
my @nextid = keys %$response;
while ( $nextid[0] =~ m/^$oid/ ) {
push( @snmpoids, $nextid[0] );
$response = $session->get_next_request( $nextid[0] );
@nextid = keys %$response;
}
if( !defined($response = $session->get_request( @snmpoids ) ) ) {
return 0;
}
foreach my $value (values %$response) {
return 1 if( $value eq $client )
}
return 0;
}
Zitat von: justme1968 schrieb am Sa, 13 April 2013 11:14nur zwei dinge sind mit aufgefallen:
- wenn ich das check intervall weg lasse bekomme ich den fehler: check-interval must be a number
- es wird bei jedem check noch was ins log geschrieben. ich vermute mal das ist noch absicht.
Ist im SVN gefixet.
Viele Grüße
Markus
Hallo Markus,
Zitat von: Markus Bloch schrieb am Sa, 13 April 2013 10:20shellscript: Das Skript muss eine 0 (abwesend) oder 1 (anwesend) auf der Konsole ausgeben. Der exit-Code wird nicht ausgewertet.
Gibt es einen besonderen Grund, warum Du das so gemacht hast (also
qx() statt
system() genommen hast)? Die Konsole-Ausgaben verschiedener Programme sind doch sehr unterschiedlich, aber exit-Code 0 = Erfolg und !0 = Misserfolg ist in der Shell universell gültig. (D.h. es müsste stringenter Weise dann natürlich auch 0 = present und alles !0 = absent sein.)
Z.B. würde meine Bitte, den Ping-Count einstellbar zu machen, dann eigentlich überflüssig werden, da man auch einfach
ping in Zusammenhang mit
shellscript verwenden könnte (gibt auch 0 bei Erfolg zurück, sonst etwas anderes).
Theoretisch ließen sich Befehle, bei denen der exit-Code entscheidend ist, natürlich recht einfach an Deine jetzige
PRESENCE-Version anpassen mit
befehl > dev/null; echo $?
das auch keinen allzu großen Overhead hat (obwohl bei sich ggf. schnell wiederholenden Kommandos natürlich jeder Overhead unschön ist, und im übrigen die "verlängerte" Skriptzeile natürlich unnötig kompliziert/fehlerträchtig ist).
Nur dummerweise habe ich FHEM partout nicht dazu bekommen, solch ein Shellscript zu akzeptieren; ";;", "\" etc. alles versucht; es gibt immer irgendwelche Fehlermeldungen.
Daher konnte ich leider bislang
PRESENCE mit "meinem" Befehl (der auch Exitwerte benutzt für Erfolg/Misserfolg) noch nicht ausprobieren.
Zitat von: Uli Zappe schrieb am So, 14 April 2013 23:56Gibt es einen besonderen Grund, warum Du das so gemacht hast (also qx() statt system() genommen hast)? Die Konsole-Ausgaben verschiedener Programme sind doch sehr unterschiedlich, aber exit-Code 0 = Erfolg und !0 = Misserfolg ist in der Shell universell gültig. (D.h. es müsste stringenter Weise dann natürlich auch 0 = present und alles !0 = absent sein.)
Das hat folgenden Hintergrund: Die Perl-Funktion system(), sobald sie aufgerufen wird, führt einen fork() durch, startet den Shell-Befehl und wartet mit wait() bis das Ergebnis vorliegt.
Nun ist aber das Problem, dass PRESENCE diesen Shell-Befehl bereits in einem Fork abarbeitet. Ein Fork kann nicht nochmal erneut forken um den system-call durchzuführen.
Die Funktion exec() gibt kein exit-code zurück und wartet auch nicht auf den Output. Daher hab ich keine andere Möglichkeit als qx() zu verwenden.
Wenn ich system() bei mir nutze, kommt bei jedem Befehl, egal welchem -1 zurück. Damit kann ich natürlich nichts auswerten
Tut mir leid.
Viele Grüße
Markus
Zitat von: Uli Zappe schrieb am So, 14 April 2013 23:56Theoretisch ließen sich Befehle, bei denen der exit-Code entscheidend ist, natürlich recht einfach an Deine jetzige PRESENCE-Version anpassen mit
befehl > dev/null; echo $?
das auch keinen allzu großen Overhead hat (obwohl bei sich ggf. schnell wiederholenden Kommandos natürlich jeder Overhead unschön ist, und im übrigen die "verlängerte" Skriptzeile natürlich unnötig kompliziert/fehlerträchtig ist).
Diese Lösung würde zwar auf Linux und FritzBoxen funktionieren, aber leider nicht unter Windows :-(
Viele Grüße
Markus
Zitat von: Markus Bloch schrieb am Mo, 15 April 2013 19:21Nun ist aber das Problem, dass PRESENCE diesen Shell-Befehl bereits in einem Fork abarbeitet. Ein Fork kann nicht nochmal erneut forken um den system-call durchzuführen.
Huch! Das wusste ich nicht ... Ich habe nicht allzu viel Ahnung von Perl und in C wäre das kein Problem, daher kam mir das nicht in den Sinn. Seltsam ...
ZitatWenn ich system() bei mir nutze, kommt bei jedem Befehl, egal welchem -1 zurück. Damit kann ich natürlich nichts auswerten
In der Tat ...
ZitatTut mir leid.
Da kannst Du ja nix für - dafür müsste man die Perl-Entwickler hauen. Danke für die Erläuterung!
Zitat von: Markus Bloch schrieb am Mo, 15 April 2013 19:30Diese Lösung würde zwar auf Linux und FritzBoxen funktionieren, aber leider nicht unter Windows :-(
FHEM läuft bei mir aber gar nicht unter Windows, sondern unter Linux, und da funktioniert es eben leider auch nicht, oder ich bin jedenfalls zu blöd dazu, das Ganze so in die Definition in
fhem.cfg zu schreiben, dass FHEM es ganz ausliest - es bricht immer irgendwo inmitten des Befehls mit dem Einlesen ab und gibt dann natürlich eine entsprechende Fehlermeldung über eine falsche Definition in
fhem.cfg aus.
Na gut, da muss ich wohl oder übel den Sourcecode des Befehls modifizieren, den ich mit
shellscript verwenden will. Ist zwar unschön, aber ich kann es ohne Source Fork machen, da ich der Autor bin.
Bei
ping geht das leider nicht, so dass ich es nicht mit
shellscript zusammen verwenden kann. Von daher die große Bitte an Dich, bei Gelegenheit noch den Ping-Count in
PRESENCE konfigurierbar zu machen.
Zitat von: justme1968 schrieb am Sa, 13 April 2013 11:14hallo markus,
das schaut klasse aus. mein anwesenheitscheck per smnp auf meine airport basestation funktioniert wunderbar. code unten falls es noch jemand brauchen kann. anlegen mit ip der basis station und mac des telefons als hex zahl:define iPhoneAndre PRESENCE function {snmpCheck("10.0.1.1","0x44d77429f35c")} 30 30
sub
snmpCheck($$)
{
my ($airport,$client)= @_;
my $community = "public";
my $host = $airport;
my $oid = ".1.3.6.1.2.1.3.1.1.2";
#my $oid = ".1.3.6.1.2.1.3.1.1.2.25.1.10.0.1";
my ( $session, $error ) = Net::SNMP->session(
-hostname => $host,
-community => $community,
-port => 161,
-version => 1
);
if( !defined($session) ) {
return 0;
return "Can't connect to host $host.";
}
my @snmpoids = ();
my $response = $session->get_next_request($oid);
my @nextid = keys %$response;
while ( $nextid[0] =~ m/^$oid/ ) {
push( @snmpoids, $nextid[0] );
$response = $session->get_next_request( $nextid[0] );
@nextid = keys %$response;
}
if( !defined($response = $session->get_request( @snmpoids ) ) ) {
return 0;
}
foreach my $value (values %$response) {
return 1 if( $value eq $client )
}
return 0;
}
Könntest du das zufällig unter
http://www.fhemwiki.de/wiki/Anwesenheitserkennung im Wiki mit einpflegen?
Das währe super.
Viele grüße
Markus
Hallo Markus,
Zitat von: Uli Zappe schrieb am Mo, 15 April 2013 23:19Na gut, da muss ich wohl oder übel den Sourcecode des Befehls modifizieren, den ich mit shellscript verwenden will.
Das habe ich jetzt gemacht, aber leider bleibt der Status von
PRESENCE grundsätzlich auf
absent.
Allerdings gilt das ebenso für einen konfigurierten
lan-ping, der zuvor bereits wunderbar funktionierte. Da hat sich also offenbar im jüngsten Update ein Bug eingeschlichen!?
Nachtrag:Wobei mir gerade auffällt, dass ich seit dem letzten Update bei einem Neustart von FHEM folgende Fehlermeldungen in der Logdatei habe:
Use of uninitialized value in concatenation (.) or string at /usr/share/fhem/FHEM/Blocking.pm line 105.
2013.04.16 03:22:29 1: CallBlockingFn: Can't connect to localhost:
Can't use an undefined value as a symbol reference at /usr/share/fhem/FHEM/Blocking.pm line 116.
Vielleicht ist das ja der Grund?
ZitatKönntest du das zufällig unter http://www.fhemwiki.de/wiki/Anwesenheitserkennung (//www.fhemwiki.de/wiki/Anwesenheitserkennung) im Wiki mit einpflegen?
schau mal ob dir das so gefällt.
gruss
andre
Zitat von: Uli Zappe schrieb am Di, 16 April 2013 01:51Da hat sich also offenbar im jüngsten Update ein Bug eingeschlichen!?
Hat sich nach erneutem Update von
fhem.pl heute erledigt - jetzt geht alles! :-)
@andre: Alles super :-)
@Uli: da bin ich froh.
Viele Grüße
Markus
Hallo Markus,
wäre es denn möglich, dass Du bei Gelegenheit noch meinen zweiten Vorschlag/Wunsch implementierst (den konfigurierbaren Ping-Count)?
Da PRESENCE nicht den exit-Status, sondern die Konsole-Ausgabe auswerten kann, kann ich den einfachen Workaround, ping mit shellscript zu benutzen, ja wie diskutiert nicht verwenden.
Danke schonmal, falls möglich!
Uli
Hallo Uli,
Asche auf mein Haupt. Ja werde ich umsetzen ;-)
Viele Grüße
Markus
Hallo Uli,
ich hab soeben eine neue Version im SVN bereitgestellt. Ab morgen kannst du diese Version via "update"-Befehl installieren.
Nach einem Neustart hast du die Möglichkeit den Count mit folgendem Attribut einzustellen:
attr <name> ping_count 1
Viel Spaß
Gruß
Markus
Zitat von: Markus Bloch schrieb am Sa, 18 Mai 2013 14:17ich hab soeben eine neue Version im SVN bereitgestellt.
Toll, tausend Dank!!
:-))Uli
Hallo Markus,
funktioniert prima jetzt! Nochmals vielen Dank!
BTW: Der shellscript-Modus ist nicht in der Dokumentation, ist das Absicht?
Uli
Ja, da ich gehofft habe eine andere Methode zu finden um an den exit-Status zu kommen und auf den Output zu verzichten, aber das wird wohl nix werden. Ich werde ihn daher demnächst so wie er ist in die Doku aufnehmen.
Viele Grüße
Markus
Zitat von: Markus Bloch schrieb am So, 19 Mai 2013 17:35Ja, da ich gehofft habe eine andere Methode zu finden um an den exit-Status zu kommen und auf den Output zu verzichten, aber das wird wohl nix werden.
Ach so. Hoffentlich habe ich Dir da jetzt nicht unnötig Kopfzerbrechen bereitet ...
Es müsste sich ja eigentlich mit
befehl > dev/null; echo $?[/color][/font]
bewerkstelligen lassen (als individuelle Eingabe oder optional von
PRESENCE ergänzt), aber wie gesagt, mir ist es partout nicht gelungen, das so in
fhem einzugeben, dass obige Zeile am Ende in "Reinform" in der Shell ankommt ...
Wie auch immer, mit
shellscript und
function sollten ja auch jetzt hinreichend viele Möglichkeiten gegeben sein.
Uli
Hallo
Wäre schön wenn ein Hinweis auf den Ping Count in der Command Ref stehen würde.
Wenn unsere Androiden vor sich hin schlummern brauchen die 5-8 Pings um wach zu werden.
Hallo Frank,
in der Commandref steht dazu:
Zitat
ping_count
(Only in Mode "ping" on non-Windows machines applicable)
Changes the count of the used ping packets to recognize a present state. Depending on your network performance sometimes a packet can be lost or blocked.
Default Value is 4 (packets)
Viele Grüße
Markus
Hallo
Markus
Sorry Anfängerfehler.
Hab nicht so weit runter gescrollt.
Nach 3 Tagen duschen bei ECO Temperatur wäre schön wenn es jetzt funktioniert.
Wenn nicht bleibt mir nur noch die Shellscript Variante, das sich die Handys irgentwie meldet.