FHEM Forum

FHEM => Anfängerfragen => Thema gestartet von: Mundus am 31 Oktober 2016, 20:25:20

Titel: Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 31 Oktober 2016, 20:25:20
Hallo liebe FHEM-Gemeinde,

ich habe einen RasPi mit FHEM laufen und außerdem nutze ich eine Fritzbox 7490. Meine Idee war es, alle aktiven Netzwerkgeräte zu ermitteln. Grundsätzlich ist mir dies mit der nachfolgenden Datei gelungen:

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;

sub getValue($$);
sub doMakeHtml ($@);
sub returnHtmlCode($%);
#########################

sub
myUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################
#Eingefügt am 14.10.2016
#kopiert aus fhemwiki Fritzbox Status, stark modifiziert
#zudem muss
#define FritzBoxValues weblink htmlCode {ShowFritzBoxValues()}
#angelegt werden

sub ShowFritzBoxValues()
{
 
  my $DevNameFB = "FritzBox";
  my $n = "";
  my $posTbl = 0;
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
 
  my @wLan;
  my @Lan;
  my @FritzValues;
  my $wLanNr = 0;
  my $LanNr = 0;
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $wLan[$wLanNr] = getValue($AktivLan,"'NewHostName' => '").', '.
            getValue($AktivLan,"'NewIPAddress' => '"), $wLanNr++}
         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $Lan[$LanNr] = getValue($AktivLan,"'NewHostName' => '").', '.
            getValue($AktivLan,"'NewIPAddress' => '"), $LanNr++}
         }
};   

$FritzValues[$posTbl] = ("Aktive WLan-Geräte" .','. $wLanNr);
$posTbl++;
#######AKtive W-LAN-Verbindungen hinzufügen
$wLanNr = 1;
foreach (@wLan) {
        $FritzValues[$posTbl] = ("W-LAN Gerät $wLanNr" .','. $_);
$wLanNr++;
$posTbl++; 
                   };
###############################################
#######Anzahl Aktiver LAN-Geräte
$FritzValues[$posTbl] = ("Aktive LAN-Geräte" .','. $LanNr);
$posTbl++;
#######Aktive LAN-Geräte hinzufügen
$LanNr = 1;
foreach (@Lan) {
        $FritzValues[$posTbl]=("LAN Gerät $LanNr" .','. $_);
$LanNr++;
$posTbl++;
        };
##############################################
 
$FritzValues[$posTbl] = ("Neue Nachricht auf dem AB" .','. ReadingsVal($DevNameFB,'tam1_newMsg',""));
$posTbl++;
$FritzValues[$posTbl] = ("Fritz-CPU-Temperatur" .','. ReadingsVal($DevNameFB,'box_cpuTemp',""));

return doMakeHtml($DevNameFB,@FritzValues);
}

# Enter you functions below _this_ line.
########################################
####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}

#########################################
###
# Funktion Rückgabe Werte mit HtMl-Code
#########################################
# Übergabe-Parameter
# Überschrift der Tabelle
# Werte
#########################################
sub
doMakeHtml($@) {
my ($tblName, @line ) = @_;
#my $tr_class = "odd";
my $htmlcode ="<table>\n";
$htmlcode .= "<tr><td><div class=\"devType\">$tblName</div></tr></td>\n";
$htmlcode .= "<tr><td>\n";
$htmlcode .= "<table class=\"block wide\" id=\"dev\">\n";

foreach (@line) {
my ($title, $value) = split (",",$_);
my $cssTitle = $title;
$cssTitle =~ s,[: -],,g;
$htmlcode .= "<tr><td><span \"$cssTitle-title\">$title</span></td><td><span \"$cssTitle-value\">$value</span></td></tr>\n";
#if ($tr_class eq "odd") {$tr_class = "even"} else {$tr_class = "odd"};
}
$htmlcode .= "</table></div>";
return $htmlcode;
}
##########Ende#######################
1;

Der Code wird über ein WEBLINK angesprochen. Leider ist das ganze sehr langsam. Daher meine Frage, gibt es eine Alternative, die deutlich schneller ist? Die Variante über die Readings der FritzBox zu gehen, scheidet meines Erachtens aus, da ich nicht alle MAC-Adressen kenne.

Habt ihr Ideen?

Gruß

Mundus
Titel: Abfrage aktiver Netzwerkgeräte
Beitrag von: justme1968 am 31 Oktober 2016, 20:46:58
schau dir doch mal das nmap modul an. die darstellung kannst du z.b. über eine readingsGroup machen.

wenn das nicht macht was du möchtest schau dir die verwendung von BlockingCall im wiki an. damit blockiert fhem nicht mehr weil der langsame code im
hintergrund ausgegeführt wird.

gruss
  andre
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 31 Oktober 2016, 23:26:17
Danke justme1968.
Das nmap-Modul ist total klasse und liefert bei mir schon die ersten Ergebnisse.

Leider kann ich nicht erkennen, ob die erkannten Geräte wlan- oder lan-Geräte sind. Also schaue ich mir noch den zweiten Teil der Antwort an ;).

Soll ich diesen Thread jetzt auf gelöst setzen?

Gruß

Mundus 
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 31 Oktober 2016, 23:29:29
Sollten alle Deine Geräte an der Fritzbox hängen, dann schau Dir das FRITZBOX Modul an. Da sieht man auch ob WLan oder Lan.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: justme1968 am 01 November 2016, 09:34:51
er nimmt doch schon das fritzbox modul :)
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 01 November 2016, 10:05:04
Zitat von: justme1968 am 01 November 2016, 09:34:51
er nimmt doch schon das fritzbox modul :)

Ups. Sorry. War bisschen zu spät gestern.


Grüße
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 21 November 2016, 03:16:52
Guten Abend,

leider habe ich bislang noch nicht den gewünschten Erfolg erzielt... Ich verstehe den BlockingCall nicht richtig bzw. mache wahrscheinlich einen großen Gedankenfehler. Ich hoffe, dass ihr mir weiterhelfen könnt.

##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;
use Blocking;

sub getValue($$);
sub doMakeHtml ($@);
sub deleteDummyValues ($);

#sub returnHtmlCode($%);
#########################

sub
FritzWLANUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################

sub FBLANValues()
{
my ($hash) = @_;
my $DevNameFB = "NameFritzBox";

##Aufruf des Blocking Call CreateValues
Log3 $DevNameFB, 4 , "HauptSub";

$hash->{helper}{RUNNING_PID} = BlockingCall("CreateValues",$DevNameFB) unless(exists($hash->{helper}{RUNNING_PID}));

#delete($hash->{helper}{RUNNING_PID});
}


sub CreateValues ($)
{
 
  my $DevNameFB = @_; #für CreateValues , die Zeile darunter entfernen
  #my $DevNameFB = "NameFritzBox";
  my $n = "";
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
  my $nameDummy = 'dFritzLan';
  my $ReadingName;
  my $TextReading;
  my $wLanNr = 0;
  my $LanNr = 0;
########Debug######################
Log3 $DevNameFB, 4, "Create Values wird ausgeführt!";
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   deleteDummyValues($nameDummy);
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $ReadingName = $wLanNr + 1;
$ReadingName = "WLan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .', ' .getValue($AktivLan,"'NewIPAddress' => '");

fhem("setreading $nameDummy $ReadingName $TextReading");

$wLanNr++
}

         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $ReadingName = $LanNr + 1;
$ReadingName = "Lan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .', ' .getValue($AktivLan,"'NewIPAddress' => '");

fhem("setreading $nameDummy $ReadingName $TextReading");

$LanNr++;
}
}
};   

#######Anzahl Aktiver WLan-Geräte deaktivieren
fhem("setreading $nameDummy AktiveWLanGeraete $wLanNr");
#######Anzahl Aktiver LAN-Geräte
fhem("setreading $nameDummy AktiveLanGeraete $LanNr");
#######Neue Nachrichten auf AB
$TextReading = ReadingsVal($DevNameFB,'tam1_newMsg',"");
fhem("setreading $nameDummy NeueNachrichtenAB $TextReading");
#######FritzBox-Temp
$TextReading = ReadingsVal($DevNameFB,'box_cpuTemp',"");
fhem("setreading $nameDummy FritzCPUTemp $TextReading")

}

# Enter you functions below _this_ line.
########################################
####
# Funktion zum Löschen der Dummy-Werte der FritzBoxParameter
#
sub deleteDummyValues($) {
     my ($nameDummy) = @_;
     my $n;
my $Anzahl = ReadingsVal($nameDummy,'AktiveWLanGeraete',"");

foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy WLan$n")
}

$Anzahl = ReadingsVal($nameDummy,'AktiveLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy Lan$n")
}
}




####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}

#########################################
###
# Funktion Rückgabe Werte mit HtMl-Code
#########################################
# Übergabe-Parameter
# Überschrift der Tabelle
# Werte
#########################################
sub
doMakeHtml(@) {
my (@line ) = @_;
#my $tr_class = "odd";
my $tblName ="FritzBoxJuFa";
my $htmlcode ="<table>\n";
$htmlcode .= "<tr><td><div class=\"devType\">$tblName</div></tr></td>\n";
$htmlcode .= "<tr><td>\n";
$htmlcode .= "<table class=\"block wide\" id=\"devJuFa\">\n";

foreach (@line) {
my ($title, $value) = split (",",$_);
my $cssTitle = $title;
$cssTitle =~ s,[: -],,g;
$htmlcode .= "<tr><td><span \"$cssTitle-title\">$title</span></td><td><span \"$cssTitle-value\">$value</span></td></tr>\n";
#if ($tr_class eq "odd") {$tr_class = "even"} else {$tr_class = "odd"};
}
$htmlcode .= "</table></div>";
return $htmlcode;
}
##########Ende#######################
1;


In einem Dummy speichere ich die Werte, sodass ich keine Return-Werte benötige. Zumindest glaube ich das  ;). Das Log gibt aus, dass CreateValue nie ausgeführt wird.

Grundsätzlich funktionieren die Befehle, daher muss mein Fehler beim BlockingCall liegen....


Gruß Mundus
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 21 November 2016, 06:52:28
Hier ist ein Beispiel wie NonBlocking verwendet wird.
Bei Dir fehlt die Hälfte. Und bitte lese den Wikiartikel zu NonBlocking. Innerhalb der $blockingFn kann nicht auf FHEM zugegriffen werden.

https://forum.fhem.de/index.php/topic,28753.msg501336.html#msg501336
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 21 November 2016, 23:14:24
Guten Abend,

CoolTux, vielen Dank für deinen Hinweis. Das wiki habe ich mehrfach gelesen, aber nicht verstanden... Ich habe meine Funktion nun so angepasst
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;
use Blocking;

sub getValue($$);
sub doMakeHtml ($@);
sub createValues_done ($);
sub deleteDummyValues ($);

#sub returnHtmlCode($%);
#########################

sub
FritzWLANUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################
sub FBLANValues()
{
my ($hash) = @_;
my $DevNameFB = "JuFaFritzBox";

##Aufruf des Blocking Call CreateValues
Log3 $DevNameFB, 4 , "HauptSub";
#$hash->{helper}{RUNNING_PID} =
BlockingCall("CreateValues",$DevNameFB,"createValues_done")
#unless(exists($hash->{helper}{RUNNING_PID}));

}


sub CreateValues ($)
{
 
  my $DevNameFB = @_; #für CreateValues , die Zeile darunter entfernen
  #my $DevNameFB = "JuFaFritzBox";
  my $n = "";
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
  my $nameDummy = 'dFritzLan';
  my $ReadingName;
  my $TextReading;
  my $returnValue;
  my $wLanNr = 0;
  my $LanNr = 0;
########Debug######################
Log3 $DevNameFB, 4, "BlockingCall wird ausgeführt";
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   #deleteDummyValues($nameDummy);
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $ReadingName = $wLanNr + 1;
$ReadingName = "WLan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .', ' .getValue($AktivLan,"'NewIPAddress' => '");

$returnValue .="|$ReadingName,$TextReading";
#fhem("setreading $nameDummy $ReadingName $TextReading");

$wLanNr++
}

         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $ReadingName = $LanNr + 1;
$ReadingName = "Lan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .', ' .getValue($AktivLan,"'NewIPAddress' => '");

$returnValue .="|$ReadingName,$TextReading";
#fhem("setreading $nameDummy $ReadingName $TextReading");

$LanNr++;
}
}
};   

#######Anzahl Aktiver WLan-Geräte deaktivieren
$returnValue .="|AktiveWLanGeraete,$wLanNr";
#fhem("setreading $nameDummy AktiveWLanGeraete $wLanNr");
#######Anzahl Aktiver LAN-Geräte
$returnValue .="|AktiveLanGeraete,$LanNr";
#fhem("setreading $nameDummy AktiveLanGeraete $LanNr");
#######Neue Nachrichten auf AB
$TextReading = ReadingsVal($DevNameFB,'tam1_newMsg',"");
$returnValue .="|NeueNachrichtenAB,$TextReading";
#fhem("setreading $nameDummy NeueNachrichtenAB $TextReading");
#######FritzBox-Temp
$TextReading = ReadingsVal($DevNameFB,'box_cpuTemp',"");
$returnValue .="|FritzCPUTemp,$TextReading";
#fhem("setreading $nameDummy FritzCPUTemp $TextReading")

Log3 $DevNameFB, 3, "Block Sub abgearbeitet -> Werte $returnValue";

return $returnValue;
}

# Enter you functions below _this_ line.
########################################
####
#Funktion zum Speichern der Werte
sub createValues_done ($){

my $valueString = @_;
####VALUE-String in einzelne Elemente zerlegen !muss generisch sein, da Anzahl LAN und WLAN vorher nicht bekannt ist
my ($name,@Values) = split("|",$valueString);
#########LOG########
Log3 $name, 3, "Die NonBlocking Funktion ist abgearbeitet";
####################
my $readingName;
my $textReading);
my $nameDummy = 'dFritzLan';
deleteDummyValues($nameDummy);

#Nunmehr erfolgt das Beschreiben des Dummys
foreach @Values {
($readingName,$textReading) = split (",",$_);
fhem("setreading $nameDummy $readingName $textReading");
}

}
####
# Funktion zum Löschen der Dummy-Werte der FritzBoxParameter
#
sub deleteDummyValues($) {
     my ($nameDummy) = @_;
     my $n;
my $Anzahl = ReadingsVal($nameDummy,'AktiveWLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy WLan$n")
}

$Anzahl = ReadingsVal($nameDummy,'AktiveLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy Lan$n")
}
}




####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}

#########################################
###
# Funktion Rückgabe Werte mit HtMl-Code
#########################################
# Übergabe-Parameter
# Überschrift der Tabelle
# Werte
#########################################
sub
doMakeHtml(@) {
my (@line ) = @_;
#my $tr_class = "odd";
my $tblName ="FritzBoxJuFa";
my $htmlcode ="<table>\n";
$htmlcode .= "<tr><td><div class=\"devType\">$tblName</div></tr></td>\n";
$htmlcode .= "<tr><td>\n";
$htmlcode .= "<table class=\"block wide\" id=\"devJuFa\">\n";

foreach (@line) {
my ($title, $value) = split (",",$_);
my $cssTitle = $title;
$cssTitle =~ s,[: -],,g;
$htmlcode .= "<tr><td><span \"$cssTitle-title\">$title</span></td><td><span \"$cssTitle-value\">$value</span></td></tr>\n";
#if ($tr_class eq "odd") {$tr_class = "even"} else {$tr_class = "odd"};
}
$htmlcode .= "</table></div>";
return $htmlcode;
}
##########Ende#######################
1;


Da ich gerade nur vor einem Editor sitze und mein FHEM nicht greifbar ist, die Frage, kann das so überhaupt funktionieren. Der Timeout und die $abortFn, $abortArg sind ja optional, sodass ich sie mir jetzt erstmal gespart habe.

Aus deiner Aussage CoolTux schließe ich, dass kein Zugriff auf fhem möglich ist.
Zitat von: CoolTux am 21 November 2016, 06:52:28
Innerhalb der $blockingFn kann nicht auf FHEM zugegriffen werden.
Das wiki zu BlockingCall verstehe ich so, dass ein Zugriff auf fhem möglich ist, aber nicht persistent gespeichert werden kann.
Daher die nächste Frage, funktionieren die Befehle
$TextReading = getValue($AktivLan,"'NewHostName' => '") .', ' .getValue($AktivLan,"'NewIPAddress' => '");
überhaupt im BlockingCall.

Vielen Dank für eure Hilfe.

Gruß

Mundus
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Tedious am 22 November 2016, 10:26:19
Mag sein dass ich nicht ganz verstanden habe was das exakte Ansinnen ist. Ich vergebe in der FB immer statische IPs für die Geräte und prüfe sie denn einfach per PRESENCE lan-ping auf Anwesenheit/Aktivität... Da mein WLan dicht ist und die FB mir bei neuen Geräten sowieso eine EMail schickt ist passt das mit sehr wenig Aufwand für mich.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 22 November 2016, 11:21:10
Innerhalb der $blockingFn Kannst Du zwar Abfragen tätigen, kannst aber nicht schalten. Ausserdem sollte Dir klar sein das die Abfragen nicht aus dem Livesystem stammen sondern aus einer Spiegelung. Ändert sich also innerhalb der ms oder gar s das Value des ab zu fragenden Readings so bekommt das Dein Fork nicht mit.

Und es wäre gut wenn Du einfach mal alles so übernimmst wie ich es geschrieben habe damit Du besser verstehst was genau passiert. Eine Abort Funktion macht schon Sinn sollte Deine $blackingFn mal hängen bleiben.

Du kannst in Deinem Fall mit list $DevNameFB prüfen ob alle Helper Einträge gelöscht wurden. Ich denke nämlich mal nicht.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 25 November 2016, 00:07:18
Zitat von: Tedious am 22 November 2016, 10:26:19
Ich vergebe in der FB immer statische IPs für die Geräte und prüfe sie denn einfach per PRESENCE lan-ping auf Anwesenheit/Aktivität...
Das ist auch eine Variante, ich wollte es aber generisch, sodass ich keine Anpassungen brauche, wenn ich ein weiteres WLAN/LAN-Device hinzufüge.

Zitat von: CoolTux am 22 November 2016, 11:21:10
Ändert sich also innerhalb der ms oder gar s das Value des ab zu fragenden Readings so bekommt das Dein Fork nicht mit.
Was bedeutet ms oder s? Wenn ich nur auf eine Spiegelung zugreife, wie könnte ich alternativ auf das Live-System zugreifen?

Zitat von: CoolTux am 22 November 2016, 11:21:10
Und es wäre gut wenn Du einfach mal alles so übernimmst wie ich es geschrieben habe damit Du besser verstehst was genau passiert. Eine Abort Funktion macht schon Sinn sollte Deine $blackingFn mal hängen bleiben.
Die Ergänzung habe ich hinzugefügt, sodass mein Code jetzt so aussieht:
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;
use Blocking;

sub getValue($$);
sub createValues_done ($);
sub deleteDummyValues ($);
sub createValues_Aborted ($);
#########################

sub
FritzWLANUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################
sub FBLANValues()
{
my ($hash) = @_;
my $DevNameFB = "JuFaFritzBox";
#$hash = $defs{$DevNameFB};

#BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));

##Aufruf des Blocking Call CreateValues
Log3 $DevNameFB, 4 , "Aufruf Create Values wird gestartet. Der Wert ist $DevNameFB";

$hash->{helper}{RUNNING_PID} = BlockingCall("CreateValues","$DevNameFB","createValues_done",30,"createValues_Aborted",$DevNameFB) unless(exists($hash->{helper}{RUNNING_PID}));

}


sub CreateValues ($)
{

  my ($DevNameFB) = @_;
  my $n = "";
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
  my $ReadingName;
  my $TextReading;
  my $returnValue = $DevNameFB;
  my $wLanNr = 0;
  my $LanNr = 0;
########Debug######################
Log3 $DevNameFB, 4 , "BlockingCall wird ausgeführt, der returnValue lautet $returnValue";
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $ReadingName = $wLanNr + 1;
$ReadingName = "WLan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$wLanNr++
}

         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $ReadingName = $LanNr + 1;
$ReadingName = "Lan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$LanNr++;
}
}
};   

#######Anzahl Aktiver WLan-Geräte deaktivieren
$returnValue .="|AktiveWLanGeraete,$wLanNr";
#######Anzahl Aktiver LAN-Geräte
$returnValue .="|AktiveLanGeraete,$LanNr";
#######Neue Nachrichten auf AB
$TextReading = ReadingsVal($DevNameFB,'tam1_newMsg',"");
$returnValue .="|NeueNachrichtenAB,$TextReading";
#######FritzBox-Temp
$TextReading = ReadingsVal($DevNameFB,'box_cpuTemp',"");
$returnValue .="|FritzCPUTemp,$TextReading";

Log3 $DevNameFB, 4, "NonBlocking Sub abgearbeitet -> Werte $returnValue";

return $returnValue;
}
########################################
####
#Funktion zum Speichern der Werte
sub createValues_done ($){

my ($valueString) = @_;
####VALUE-String in einzelne Elemente zerlegen !muss generisch sein, da Anzahl LAN und WLAN vorher nicht bekannt ist
my (@Values) = split("\\|",$valueString);
my $name = $Values[0];
my $readingName;
my $textReading;
my $nameDummy = 'dFritzLan';

#########LOG########
Log3 $name, 3, "createValues_done wird gestartet DevName ist $name";
####################
#Löschen des ersten Elementes im Array
shift(@Values);
#Löschen der alten Values im Dummy
deleteDummyValues($nameDummy);

#Nunmehr erfolgt das erneute Beschreiben des Dummys
foreach (@Values) {
($readingName,$textReading) = split (",",$_);
fhem("setreading $nameDummy $readingName $textReading");
}
}
########################################
####
# Funktion zum Löschen der Dummy-Werte der FritzBoxParameter
#
sub deleteDummyValues($) {
    my ($nameDummy) = @_;
    my $n;
my $Anzahl = ReadingsVal($nameDummy,'AktiveWLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy WLan$n")
}

$Anzahl = ReadingsVal($nameDummy,'AktiveLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy Lan$n")
}
}

####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}
#####################################
### Abbruch Funktion
sub createValues_Aborted($) {

    my ($hash) = @_;
    my $name = $hash->{NAME};

    delete($hash->{helper}{RUNNING_PID});
    Log3 $name, 3, "($name) - The BlockingCall Process terminated unexpectedly. Timeout";

}


##########Ende#######################
1;
Und das ganze funktioniert auch. Aber sobald ich die beiden Zeile 
#$hash = $defs{$DevNameFB};
#BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));

einfüge, funktioniert der Aufruf leider nur einmal. Außerdem ergibt list $DevNameFB in diesem Fall, dass die Helper-Einträge nicht gelöscht werden...

Kommentiere ich diese Zeilen aus, läuft alles korrekt...

Was mache ich also falsch bzw. wo ist der Code falsch.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 25 November 2016, 07:29:37
Du kannst nicht auf das Livesystem zugreifen.

Deine Heller bleiben stehen weil der Fork nicht vernünftig abgeschlossen wird. Er kann die Werte nicht an die $FnDone übergeben. Du solltest also erstmal raus finden wie das was du an die Done übergeben willst aussieht. Und ob er nicht doch in die Done springt aber nach der ersten Zeile nur nicht weiter kommt. Bau Dir also Debugzeilen ein.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: justme1968 am 25 November 2016, 09:27:00
ich weise noch mal auf das nmap modul hin.
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: Mundus am 28 November 2016, 23:29:57
Guten Abend,

das Problem ist gelöst. Ich hatte in der Funktion createValues_done die Zeile
delete($hash->{helper}{RUNNING_PID});
vergessen. Vielen Dank für eure Hilfe, die Anmerkungen haben mich zum Ziel gebracht.

Das ganze Produkt sieht jetzt so aus.
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;
use Blocking;

sub getValue($$);
sub createValues_done ($);
sub deleteDummyValues ($);
sub createValues_Aborted ($);
#########################

sub
FritzWLANUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################
sub FBLANValues()
{
my ($hash) = @_;
my $DevNameFB = "JuFaFritzBox";
$hash = $defs{$DevNameFB};

BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));

##Aufruf des Blocking Call CreateValues
Log3 $DevNameFB, 4 , "Aufruf Create Values wird gestartet. Der Hash lautet $hash";

$hash->{helper}{RUNNING_PID} = BlockingCall("CreateValues","$DevNameFB","createValues_done",30,"createValues_Aborted",$DevNameFB) unless(exists($hash->{helper}{RUNNING_PID}));

}


sub CreateValues ($)
{

  my ($DevNameFB) = @_;
  my $n = "";
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
  my $ReadingName;
  my $TextReading;
  my $returnValue = $DevNameFB;
  my $wLanNr = 0;
  my $LanNr = 0;
########Debug######################
Log3 $DevNameFB, 4 , "BlockingCall wird ausgeführt, der returnValue lautet $returnValue";
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $ReadingName = $wLanNr + 1;
$ReadingName = "WLan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$wLanNr++
}

         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $ReadingName = $LanNr + 1;
$ReadingName = "Lan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$LanNr++;
}
}
};   

#######Anzahl Aktiver WLan-Geräte deaktivieren
$returnValue .="|AktiveWLanGeraete,$wLanNr";
#######Anzahl Aktiver LAN-Geräte
$returnValue .="|AktiveLanGeraete,$LanNr";
#######Neue Nachrichten auf AB
$TextReading = ReadingsVal($DevNameFB,'tam1_newMsg',"");
$returnValue .="|NeueNachrichtenAB,$TextReading";
#######FritzBox-Temp
$TextReading = ReadingsVal($DevNameFB,'box_cpuTemp',"");
$returnValue .="|FritzCPUTemp,$TextReading";

##################Debug#############################
Log3 $DevNameFB, 4, "NonBlocking Sub abgearbeitet -> Werte $returnValue";
####################################################

return $returnValue;
}
########################################
####
#Funktion zum Speichern der Werte
sub createValues_done ($){

my ($valueString) = @_;
#############Debug#############################
Log3 "JuFaFritzBox", 4, "createValues_done wird ausgeführt und hat den Wert $valueString übergeben bekommen";
####VALUE-String in einzelne Elemente zerlegen !muss generisch sein, da Anzahl LAN und WLAN vorher nicht bekannt ist
my (@Values) = split("\\|",$valueString);
my $name = $Values[0];
my $hash = $defs{$name};
my $readingName;
my $textReading;
my $nameDummy = 'dFritzLan';

#############Debug und löschen des $hash########
Log3 "JuFaFritzBox", 4, "createValues_done löscht jetzt den aktiven $hash";
delete($hash->{helper}{RUNNING_PID});
####################

####Löschen des ersten Elementes im Array####
shift(@Values);
#Löschen der alten Values im Dummy
deleteDummyValues($nameDummy);

#Nunmehr erfolgt das erneute Beschreiben des Dummys
foreach (@Values) {
($readingName,$textReading) = split (",",$_);
fhem("setreading $nameDummy $readingName $textReading");
}
}
########################################
####
# Funktion zum Löschen der Dummy-Werte der FritzBoxParameter
#
sub deleteDummyValues($) {
    my ($nameDummy) = @_;
    my $n;
my $Anzahl = ReadingsVal($nameDummy,'AktiveWLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy WLan$n")
}

$Anzahl = ReadingsVal($nameDummy,'AktiveLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy Lan$n")
}
}

####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}
#####################################
### Abbruch Funktion
sub createValues_Aborted($) {

    my ($hash) = @_;
    my $name = $hash->{NAME};

    delete($hash->{helper}{RUNNING_PID});
    Log3 $name, 4, "($name) - The BlockingCall Process terminated unexpectedly. Timeout";

}


##########Ende#######################
1;

Wenn ihr aber noch Verbesserungen findet, dann teilt mir diese bitte mit, da ich davon super lernen kann.

Zitat von: CoolTux am 25 November 2016, 07:29:37
Bau Dir also Debugzeilen ein.
Wie mache ich das? Ist hierbei Log3 der richtige Weg -so habe ich es gemacht- oder gibt es ein anderen Weg bzw. ein Tool.

Zitat von: justme1968 am 25 November 2016, 09:27:00
ich weise noch mal auf das nmap modul hin.
Wie kann ich mit nmap herausfinden, ob die Geräte via WLAN oder LAN angebunden sind. Meine Recherche hat nichts erbracht?
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: CoolTux am 29 November 2016, 00:06:09
Zitat von: Mundus am 28 November 2016, 23:29:57
Guten Abend,

das Problem ist gelöst. Ich hatte in der Funktion createValues_done die Zeile
delete($hash->{helper}{RUNNING_PID});
vergessen. Vielen Dank für eure Hilfe, die Anmerkungen haben mich zum Ziel gebracht.

Das ganze Produkt sieht jetzt so aus.
##############################################
# $Id: myUtilsTemplate.pm 7570 2015-01-14 18:31:44Z rudolfkoenig $
#
# Save this file as 99_myUtils.pm, and create your own functions in the new
# file. They are then available in every Perl expression.

package main;
use strict;
use warnings;
use POSIX;
use Blocking;

sub getValue($$);
sub createValues_done ($);
sub deleteDummyValues ($);
sub createValues_Aborted ($);
#########################

sub
FritzWLANUtils_Initialize($$)
{
  my ($hash) = @_;
}

###############################################
sub FBLANValues()
{
my ($hash) = @_;
my $DevNameFB = "JuFaFritzBox";
$hash = $defs{$DevNameFB};

BlockingKill($hash->{helper}{RUNNING_PID}) if(defined($hash->{helper}{RUNNING_PID}));

##Aufruf des Blocking Call CreateValues
Log3 $DevNameFB, 4 , "Aufruf Create Values wird gestartet. Der Hash lautet $hash";

$hash->{helper}{RUNNING_PID} = BlockingCall("CreateValues","$DevNameFB","createValues_done",30,"createValues_Aborted",$DevNameFB) unless(exists($hash->{helper}{RUNNING_PID}));

}


sub CreateValues ($)
{

  my ($DevNameFB) = @_;
  my $n = "";
  my $AnzahlDev = getValue(fhem("get $DevNameFB tr064Command Hosts:1 hosts GetHostNumberOfEntries"),"'NewHostNumberOfEntries' => '");
  my $ReadingName;
  my $TextReading;
  my $returnValue = $DevNameFB;
  my $wLanNr = 0;
  my $LanNr = 0;
########Debug######################
Log3 $DevNameFB, 4 , "BlockingCall wird ausgeführt, der returnValue lautet $returnValue";
############ Auslesen der aktiven wLan-  bzw Lan-Geräte
foreach $n (0..$AnzahlDev -1) {
   
   my $AktivLan = fhem("get $DevNameFB tr064Command Hosts:1 hosts GetGenericHostEntry 'NewIndex' '$n'");
   
   if (getValue($AktivLan,"'NewActive' => '") == 1) {
         if (getValue($AktivLan,"'NewInterfaceType' => '")eq "802.11") {
            $ReadingName = $wLanNr + 1;
$ReadingName = "WLan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$wLanNr++
}

         elsif (getValue($AktivLan,"'NewInterfaceType' => '")eq "Ethernet") {
            $ReadingName = $LanNr + 1;
$ReadingName = "Lan".$ReadingName;
$TextReading = getValue($AktivLan,"'NewHostName' => '") .':' .getValue($AktivLan,"'NewIPAddress' => '");
$returnValue .="|$ReadingName,$TextReading";
$LanNr++;
}
}
};   

#######Anzahl Aktiver WLan-Geräte deaktivieren
$returnValue .="|AktiveWLanGeraete,$wLanNr";
#######Anzahl Aktiver LAN-Geräte
$returnValue .="|AktiveLanGeraete,$LanNr";
#######Neue Nachrichten auf AB
$TextReading = ReadingsVal($DevNameFB,'tam1_newMsg',"");
$returnValue .="|NeueNachrichtenAB,$TextReading";
#######FritzBox-Temp
$TextReading = ReadingsVal($DevNameFB,'box_cpuTemp',"");
$returnValue .="|FritzCPUTemp,$TextReading";

##################Debug#############################
Log3 $DevNameFB, 4, "NonBlocking Sub abgearbeitet -> Werte $returnValue";
####################################################

return $returnValue;
}
########################################
####
#Funktion zum Speichern der Werte
sub createValues_done ($){

my ($valueString) = @_;
#############Debug#############################
Log3 "JuFaFritzBox", 4, "createValues_done wird ausgeführt und hat den Wert $valueString übergeben bekommen";
####VALUE-String in einzelne Elemente zerlegen !muss generisch sein, da Anzahl LAN und WLAN vorher nicht bekannt ist
my (@Values) = split("\\|",$valueString);
my $name = $Values[0];
my $hash = $defs{$name};
my $readingName;
my $textReading;
my $nameDummy = 'dFritzLan';

#############Debug und löschen des $hash########
Log3 "JuFaFritzBox", 4, "createValues_done löscht jetzt den aktiven $hash";
delete($hash->{helper}{RUNNING_PID});
####################

####Löschen des ersten Elementes im Array####
shift(@Values);
#Löschen der alten Values im Dummy
deleteDummyValues($nameDummy);

#Nunmehr erfolgt das erneute Beschreiben des Dummys
foreach (@Values) {
($readingName,$textReading) = split (",",$_);
fhem("setreading $nameDummy $readingName $textReading");
}
}
########################################
####
# Funktion zum Löschen der Dummy-Werte der FritzBoxParameter
#
sub deleteDummyValues($) {
    my ($nameDummy) = @_;
    my $n;
my $Anzahl = ReadingsVal($nameDummy,'AktiveWLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy WLan$n")
}

$Anzahl = ReadingsVal($nameDummy,'AktiveLanGeraete',"");
foreach $n (1..$Anzahl){
fhem("deletereading $nameDummy Lan$n")
}
}

####
# Funktion zum Auslesen der FritzBoxParameter
#
sub getValue($$) {
     my ($resp_FB, $searchstr) = @_;

     my $PosStart = index($resp_FB,$searchstr) + length($searchstr);
     my $AnzChar = index($resp_FB,"'",$PosStart) - $PosStart;
     my $Value = substr ($resp_FB,$PosStart,$AnzChar);

     return $Value;
}
#####################################
### Abbruch Funktion
sub createValues_Aborted($) {

    my ($hash) = @_;
    my $name = $hash->{NAME};

    delete($hash->{helper}{RUNNING_PID});
    Log3 $name, 4, "($name) - The BlockingCall Process terminated unexpectedly. Timeout";

}


##########Ende#######################
1;

Wenn ihr aber noch Verbesserungen findet, dann teilt mir diese bitte mit, da ich davon super lernen kann.
Wie mache ich das? Ist hierbei Log3 der richtige Weg -so habe ich es gemacht- oder gibt es ein anderen Weg bzw. ein Tool.
Wie kann ich mit nmap herausfinden, ob die Geräte via WLAN oder LAN angebunden sind. Meine Recherche hat nichts erbracht?

Du kannst Log3 oder Log1 nehmen. Das sind Subs von FHEM. Oder Du nimmst einfach das gute alte Perl printf  ;D
Titel: Antw:Abfrage aktiver Netzwerkgeräte
Beitrag von: justme1968 am 29 November 2016, 22:45:00
mit dem nmap modul kannst du nicht nach lan/waln unterscheiden.

aber darum ging es ja zumindest laut titel des thread auch noch nicht :)