Nmap readingsGroup

Begonnen von igami, 03 April 2017, 17:07:36

Vorheriges Thema - Nächstes Thema

igami

Ich fange hier mal an Vorschläge für eine Nmap readingsGroup zu sammeln.
Folgende Versionen wurden bisher vorgestellt:
Zitat von: sylvester am 29 März 2017, 18:29:10

define LAN readingsGroup <>,<IP-Adresse>,<Rechner-Name>,<State> LANmap:@3,<#1>,#1_alias,(.*)_state

Zitat von: supernova1963 am 28 März 2017, 22:14:47

defmod nmapListe readingsGroup <>,<Nr>,<IP-Adresse>,<Rechner-Name>,<MAC>,<Hersteller> \
nmap:@3,#1_ip,<#1>,(.*)_hostname,#1_macAddress,#1_macVendor
attr nmapListe cellStyle { "c:1" => 'style="text-align:right"' }
attr nmapListe room 92 Informationen
attr nmapListe sortColumn 2
attr nmapListe valueFormat { NmapNr($VALUE) }


myutils:

sub
NmapNr($)
{
  my ($ipV4) = @_;
  my $Nr = "";
 
  $Nr = substr($ipV4,rindex($ipV4,".")+1);

  return $Nr;
}


Vorschläge dazu bitte hier posten, auch ein für mich sind die Readings ... wichtig ist hilfreich. Ich bastel daraus dann eine readingsGroup und möchte die als template zur Verfügung stellen.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

choetzu

Hallo,

ich habe das genau so übernommen. Leider zeigt es mir alle  "Rechner-Namen" nur mit "home" an. Im Reading Nmap werden sämtliche aliase mit geraet.home angezeigt. also z.b. TvBox.home oder iPhone.home.

In der ReadingsGroup kommt aber nur der Teil home.. Woran könnte das liegen?

Danke für die Hilfe.
Lg c
Raspi3, EnOcean, Zwave, Homematic

igami

Zitat von: choetzu am 23 April 2017, 09:18:12
ich habe das genau so übernommen. Leider zeigt es mir alle  "Rechner-Namen" nur mit "home" an. Im Reading Nmap werden sämtliche aliase mit geraet.home angezeigt. also z.b. TvBox.home oder iPhone.home.

In der ReadingsGroup kommt aber nur der Teil home.. Woran könnte das liegen?
In meinem Beitrag stehen schon zwei Definitionen. Welche davon hast du genommen?
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

choetzu

Hallo, danke, ich habe die von supernova https://forum.fhem.de/index.php/topic,57804.msg613022.html#msg613022 genommen.. aber es geht auch bei der ersten Definition nicht..


Gesendet von iPhone mit Tapatalk Pro
Raspi3, EnOcean, Zwave, Homematic

igami

Ich persönlich verwende

defmod Nmap_readingsGroup readingsGroup <>,<host>,<IP>,<MAC>,<uptime>,<lastSeen>,<>\
Nmap:@1,(.*)_alias,#1_ip,!#1_macAddress,#1_uptimeText,#1_lastSeen,<>
attr Nmap_readingsGroup nameStyle style="font-weight: bold;; text-align: center;;"
attr Nmap_readingsGroup room Netzwerk
attr Nmap_readingsGroup sortColumn 0
attr Nmap_readingsGroup valueFormat {return("unknown") if($VALUE =~ m/_macAddress/);;}
attr Nmap_readingsGroup valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "font-family: monospace;;";;\
\
return('style="color: #61CE3C;; text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="color: #61CE3C;; '.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}


Werde mir die andere DEF bei Gelegenheit mal ansehen
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

Hallo igami,

tolle Lösung für eine nmap-readingsGroup! Ich habe meine Definition sofort angepasst.

Ist es eigentlich irgendwie möglich den Wert einer einzelnen Spalte nach der Gruppierung zu bearbeiten, - oder -, vor der Gruppierung zu beeinflussen?

Danke,

Gernot

@choetzu: Ich vermute, dass Dein Problem nicht an der readingsGroup liegt. Die listet und gruppiert nur die Readings des nmap - Devices. Hast du dort das Attribut attr [Device-Name] sudo 1 gesetzt und dem User fhem erlaubt nmap ohne Passwort auszuführen? Linux: sudo visudo mit dem Eintrag vor "#Include ..." oder, - wie empfohlen -, in einer eigenen Datei in /etc/sudoers.d?fhem ALL=(ALL) NOPASSWD: /usr/bin/nmap

igami

Zitat von: supernova1963 am 30 April 2017, 07:58:25
tolle Lösung für eine nmap-readingsGroup! Ich habe meine Definition sofort angepasst.
Habe ich schon in dem andern Thread gelesen, vielen Dank für das Lob :)

Zitat von: supernova1963 am 30 April 2017, 07:58:25
Ist es eigentlich irgendwie möglich den Wert einer einzelnen Spalte nach der Gruppierung zu bearbeiten, - oder -, vor der Gruppierung zu beeinflussen?
Was meinst du damit? Am besten mal ein Beispiel.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

Hallo igami,

ich hatte ursprünglich vor den Wert der Spalte #1_state mit einem Symbol zu ersetzen (rc_RED für absent oder rc_GREEN für present).
Zusätzlich will ich in dem Falle, dass "#1_macVendor eq "Espressif" ist ein entsprechender Link hinter den #1_Alias gelegt wird (es handelt sich dabei um ESP8266 mit ESPEASY). 

Schöner fände ich natürlich, wenn mit nmap die offenen Ports jedes Gerätes abgefragt würden und dann z.B. bei Port 80: http://[IP-Adresse] bzw. bei Port 443: https://[IP-Adresse] bei allen entsprechenden Geräten hinterlegt werden könnte. Aber dafür bedarf es, - glaube ich -, eines neuen Moduls, das auch nicht so oft aktualisiert werden muss.

sudo nmap -Pn 192.168.1.20

Starting Nmap 7.40 ( https://nmap.org ) at 2017-04-30 09:46 CEST
Nmap scan report for 192.168.1.20
Host is up (0.0027s latency).
Not shown: 999 closed ports
PORT   STATE SERVICE
80/tcp open  http
MAC Address: 5C:CF:7F:0F:C0:6C (Espressif)


Danke,

Gernot

supernova1963

Hallo igami,

bis ich dein Modul auf Basis von nmap entdeckte, habe ich mir mit fing https://www.fing.io/wp-content/uploads/2016/09/overlook-fing-3.0.deb etwas grob vergleichbares geschaffen. Nach der Installation habe ich mit dem Befehl:
sudo fing -o table,html,/opt/fhem/www/fing/discover.html
eine html Seite erzeugen lassen, die solange der Prozess läuft mit refresh fortgeschrieben wird.
und mit dem Befehl:
sudo fing -s 192.168.1.11/24 -o html,/opt/fhem/www/fing/scan.html
die offenen Ports anzeigen lassen. Diese Seite wird jedoch immer nur einmal erstellt.
Meine Versuche, die anderen Ausgabeformate zu nutzen sind aufgrund fehlender Perl-Kenntnisse kläglich gescheitert (html, csv, text, xml, json werden angeboten).

Damals fehlte mir schon die Möglichkeit mit einem Klick auf das Gerät eine Port-Scan für diese zu realisieren. Außerdem hat dein Modul den riesen Vorteil der Alias Erfassung, den ich mit fing nicht hinbekommen habe.

Danke noch einmal für die Mühe,

Gernot

igami

In diesem Thread geht es eigentlich nur um die Darstellung der Ergebnisse. Wenn du eine weitere Funktion in Nmap haben willst, dann bitte in dem Nmap Thread posten oder einen neuen Thread erstellen.
Prinzipiell ist mit der möglichkeit, dass args vorgegeben werden kann möglich auch einen portscan einzubauen, aber wozu das in einer Smarthome Software erforderlich ist verstehe ich noch nicht.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

Ok, ich habe verstanden.
Ich wollte nur auf deine Frage nach dem, was ich meine, antworten.

Sorry,

Gernot

igami

Zitat von: supernova1963 am 30 April 2017, 15:42:36
Ok, ich habe verstanden.
Ich wollte nur auf deine Frage nach dem, was ich meine, antworten.

Sorry,

Gernot
Also mir ist noch nicht klar was du genau machen möchtest. Du möchtest im Prinzip einen Button oder so in die ReadingsGroup einbauen auf den du klicken kannst und dann eine Liste offener Ports bekommst?

Du brauchst dich nicht Entschuldigen. Es geht mir nur darum, dass die Informationen an der richtigen Stelle stehen. In dem Thread zu dem Modul wurde schon einmal danach gefragt einen Port Scanner einzubauen. Da ich mir aber momentan keine Anwendug dafür vorstellen kann wäre es Sinnvoller wenn die, die das haben wollen darüber diskutieren und mir dann möglichst detailliert mitteilen, was sie möchten damit ich das einbauen kann
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963


Mir ging und geht es in diesem Thema an sich nur darum, ob und wie man statt absent und present ein rotes und ein grünes Icon innerhalb einer gruppierten readingsGroup anzeigen kann.

Alles Andere ist Vision,

Gernot


P.S.: Ein Grund für den Sinn einer Port Überwachung in einer Smarthome Software ist die Sicherheit und dazu vielleicht noch Debugging für Entwickler.

igami

Zitat von: supernova1963 am 30 April 2017, 16:05:49
Mir ging und geht es in diesem Thema an sich nur darum, ob und wie man statt absent und present ein rotes und ein grünes Icon innerhalb einer gruppierten readingsGroup anzeigen kann.
Jetzt verstehe ich, aber ich weiß leider nicht wie man das umsetzen kann
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

justme1968

und valueIcon hilft nicht ?
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

supernova1963

Leider nicht, da ich es nicht schaffe den Value des readings #1_state.absent durch das icon rc_RED und den Value #1_state.present durch das Icon rc_GREEN zu ersetzen.

Die sonst funktionierenden Ersetzungen greifen nicht.

Gernot

justme1968

nimm die perl code version von value format und ordne sie dem default '' zu.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

supernova1963

Hallo andre,

Danke für den Hinweis. Mit valueFormat funktioniert die Ersetzung. Was muss ich ändern, damit des Textes "rc_GREEN" und "rc_RED" das jeweiligen Icon angezeigt wird?

Danke,

Gernot


defmod nmapListe readingsGroup <>,<Nr>,<IP-Adresse>,<Rechner-Name>,<MAC>,<Status>,<Hersteller> \
nmap:@3,#1_ip,<#1>,(.*)_alias,#1_macAddress,#1_state,#1_macVendor
attr nmapListe cellStyle { "c:1" => 'style="text-align:right"' }
attr nmapListe icon it_network
attr nmapListe room 92 Informationen
attr nmapListe sortColumn 2
attr nmapListe valueFormat { ($VALUE eq 'absent')?"rc_RED":($VALUE eq 'present')?"rc_GREEN":NmapNr($VALUE)}
attr nmapListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}

supernova1963

#18
Ich hab's dank andre und igami geschafft.
Meine readingsGroup (jetzt ohne die Nutzung von 99_myUtils):
defmod nmapListe readingsGroup <>,<Nr>,<IP-Adresse>,<onl>,<RechnerName>,<MAC>,<Hersteller> \
nmap:@4,#1_ip,<#1>,#1_state,(.*)_alias,#1_macAddress,#1_macVendor
attr nmapListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr nmapListe icon it_network
attr nmapListe room 92 Informationen
attr nmapListe sortColumn 2
attr nmapListe valueFormat { if ($VALUE eq 'absent') {\
     "<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>"\
     }\
  elsif ($VALUE eq 'present') {\
     "<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>"\
     }\
  elsif (substr($READING,rindex($READING,"_")) eq "_ip") {\
     substr($VALUE,rindex($VALUE,".")+1)\
     } \
  else {\
    ""\
    }\
}
attr nmapListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}


Anregungen für zu Optimierung des Codes nehme ich gerne an.

Danke noch einmal an andre und igami,

Gernot

igami

Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

Ich habe noch etwas aufgeräumt, die Farbe der abwesenden geändert und einen Link hintern den Namen gelegt, wenn der #1_alias mit -80 bzw. -443 endet.
Es öffnet sich ein neues Fenster (wer das nicht mag, kann target='_blank' entfernen oder durch target='_self' ersetzen) mit der URL aus der IP-Adresse (http://[#1_ip] bei 80 bzw. https://[#1_ip]:443)

Einen schönen Feiertag,

Gernot

defmod nmapListe readingsGroup <>,<Nr>,<IP-Adresse>,<onl>,<RechnerName>,<MAC>,<Hersteller> \
nmap:@4,#1_ip,<#1>,#1_state,(.*)_alias,#1_macAddress,#1_macVendor
attr nmapListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr nmapListe icon it_network
attr nmapListe room 92 Informationen
attr nmapListe sortColumn 2
attr nmapListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'Nr' zur Sortierung aus der IP extrahieren    \
  return(substr($VALUE,rindex($VALUE,".")+1)) if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("<a url='http://".$ipAddr."' onclick='window.open(\"http://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "80");;\
  return("<a url='https://".$ipAddr."' onclick='window.open(\"https://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "443");;\
  #Anderenfalls soll das valueFormat leer bleiben bzw. nachstehenden Inhalt verwenden\
  return("");;\
}
attr nmapListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}




choetzu

Hallo Supernova1963

wow, das sieht sehr schön aus... Woher hast du das FHEM-Template? Danke fürs Feedback.

Lg C
Raspi3, EnOcean, Zwave, Homematic

supernova1963


choetzu

Danke für deine Antwort, werde ich gleich mal ausprobieren ;)

Zitat von: supernova1963 am 01 Mai 2017, 21:52:21
Funktioniert dein nmap jetzt?

Nein, leider nicht. Ich konnte aber den Fehler etwas einkreisen. Am device nmap liegt es m.E. nicht. Denn ohne readingsGroup geht es problemlos, also ohne Fehlermeldung.

Wenn ich es gemäss der Anleitung von igami mache (https://forum.fhem.de/index.php/topic,70041.msg625079.html#msg625079) dann klappt die readingsGroup solange, bis ich folgendes Attribut setze

attr Nmap_readingsGroup valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "font-family: monospace;;";;\
\
return('style="color: #61CE3C;; text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="color: #61CE3C;; '.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}


sobald ich dies mache, kommen die Fehlermeldungen wieder. Meine perl-Kenntnisse sind gleich 0, so dass ich auch nach xmal durchlesen, keine Ahnung habe, woran es liegen könnte...

hmm, ich habe jetzt mal die readingsGroup deaktiviert.
Raspi3, EnOcean, Zwave, Homematic

igami

Wie gibts du das Attribut ein? Das ist die Raw definition.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

#25
Meine Perl Kenntnisse sind ebenfalls mehr als bescheiden. Das valueStyle Attribut habe ich, - bis auf Anpassungen des Farb Codes -, unverändert von igami übernommen.

Nur sicherheitshalber, den defmod Code trägst du doch in der "Raw definition" ein und führst ihn mit "Execute commands" aus, oder?
Insbesondere dieser Code funktioniert nämlich nicht mit dem "bösen, bösen, bösen" direkt editieren der fhem.conf.

Anderenfalls hilft den Experten ein list Nmap_readingsGroup bei der Fehleranalyse oft weiter.

Gernot

@igami: du warst schneller


choetzu

Hallo, was ist genau mit raw Definition gemeint? Ich mache es wie folgt. Im Device nmap_readingGroup klicke ich auch attr und wähle dann valueStyle in der Liste aus. Danach gebe ich den Code ein.. Save und fertig..

Ist das falsch?
Raspi3, EnOcean, Zwave, Homematic

supernova1963

Daran liegt es, nimm den Link Raw definition in der letzten Zeile der Anzeige der Definition des Devices und ersetze den Code  ganz oder teilweise.
Es funktioniert sogar in der Raw Definition eines beliebigen Devices. Ich habe mir ein defmodEdit als einfachen Dummy angelegt, den ich für diese Code-Erfassung verwende.

Vergleich Attribut und Raw Definition:

Attribut Editor valueStyle:

{$READING =~ m/(.+)_/;
my $state = ReadingsVal($DEVICE, $1."_state", "NA");
my $style = "";

return('style="text-align: right; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);
return('style="color: #bfbfbf; text-align: right; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);

return('style="'.$style.'"') if($state eq "present");
return('style="color: #bfbfbf; '.$style.'"') if($state eq "absent");
}

Aus der Raw Definition:

attr nmapListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\


Probier's aus, und es klappt!

Gernot


TWART016

Vielen Dank. Sieht super aus.

Bei mir wird der farbige Punkt für Online/Offline links angezeigt. Wie kann ich das zentrieren?

supernova1963

Hier wird es festgelegt (c:1 = Spalte 1, ...)

....
attr nmapListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
...

curt

#30
Das gefällt mir, das möchte ich auch.
Leider gibt es ein Problem: MAC und Hersteller werden in der Tabelle nicht angezeigt.

Ich nahm von @supernova1963 die Definitionen. Via PN erkläre er mir das für mich völlig neue Vorgehen mit "Raw definition" und "Execute commands" (Danke!). Nr / IP-Adresse / onl / RechnerName werden angezeigt. Leider werden MAC / Hersteller nicht angezeigt.

in meiner fhem.cfg steht

define Netzwerk Nmap 192.168.127.0/24 192.168.128.0/24
attr Netzwerk room 05 Die Lage

define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<onl>,<RechnerName>,<MAC>,<Hersteller> \
Netzwerk:@4,#1_ip,<#1>,#1_state,(.*)_alias,#1_macAddress,#1_macVendor
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Informationen
attr NetzwerkListe sortColumn 2
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'Nr' zur Sortierung aus der IP extrahieren    \
  return(substr($VALUE,rindex($VALUE,".")+1)) if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("<a url='http://".$ipAddr."' onclick='window.open(\"http://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "80");;\
  return("<a url='https://".$ipAddr."' onclick='window.open(\"https://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "443");;\
  #Anderenfalls soll das valueFormat leer bleiben bzw. nachstehenden Inhalt verwenden\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}


Auszugsweises Ergebnis in der dargestellten Tabelle ist

106 - 192.168.127.111 - <present> - 192.168.127.111


Da fehlt also MAC/Hersteller - in JEDER Zeile.

Ich klicke also mal bei "Netzwerk" drauf und schaue mir die Readings an: _alias, _hostname, _ip, _lastSeen, _state, _uptime, -uptimeText. Nicht mehr. Es fehlen MAC und Hersteller.

Ok, da wird offensichtlich "/usr/bin/nmap -sn 192.168.127.0/24" aufgerufen. Das vollziehe ich mal mit der bash nach (Auszug):


map scan report for 192.168.127.111
Host is up (-0.10s latency).
MAC Address: 00:0C:29:8B:A8:AA (VMware)


Cool, negative Latenz. - Ok: MAC und Vendor kommen da schon ... nun muss ich nur noch FHEM davon überzeugen.

Was mache ich falsch?

Ganz nebenbei:
Zitat von: supernova1963 am 02 Mai 2017, 06:43:35
Anderenfalls hilft den Experten ein list Nmap_readingsGroup bei der Fehleranalyse oft weiter.

Ähmmm:
Zitat
No device named Netzwerk_readingsGroup found
No device named NetzwerkLIste_readingsGroup found

Nichtmal das kriege ich hin.
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Commandref zum NMap Modul:
Zitat
[...]
<metaReading>_macAddress
MAC-Adresse des Netzwerkgeräts. Diese kann nur ermittelt werden, wenn der Scan mit Root-Rechten ausgeführt wird.
<metaReading>_macVendor
Vermutlicher Hersteller des Netzwerkgeräts. Dieser kann nur ermittelt werden, wenn der Scan mit Root-Rechten ausgeführt wird.
[...]
Vermutlich wird der Scan bei dir also nicht mit root rechten ausgeführt.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Zitat von: igami am 08 März 2018, 05:57:52
Vermutlich wird der Scan bei dir also nicht mit root rechten ausgeführt.

Vermutlich hast Du recht.

Sagst Du mir bitte, wo und wie ich das konkret einschalte?

Ich danke Dir.
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Soll nicht pampig klingen, aber so wie in der Commandref beschrieben.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

@curt:

Zitat
sudo 1
Der Scan wird mit Root-Rechten ausgeführt.
Voraussetzung ist, dass der Benutzer unter dem FHEM ausgeführt diese Rechte besitzt. Für den Benutzer "fhem", auf einem Debian (basierten) System, lassen sich diese in der Datei "/etc/sudoers" festlegen. Dafür muss im Abschnitt "# User privilege specification" die Zeile "fhem ALL=(ALL) NOPASSWD: /usr/bin/nmap" eingefügt werden.

Bitte beachten, das du Änderungen an der /etc/sudoers unbedingt mit sudo visudo /etc/sudoersmachst. Besser wäre ggf. eine eigene Datei anzulegen in die du die o.g. Zeile einfügst
sudo visudo -f /etc/sudoers.d/nmap
Anschließend noch booten!
Ich hoffe, dass ich die Befehlssyntax ungetestet noch richtig wiedergegeben habe.

Gernot

curt

Zitat von: igami am 08 März 2018, 06:34:37
Soll nicht pampig klingen

Das klingt nicht nur pampig - sondern ist es auch.

Zwar bin ich ohne Frage doof - aber ich frage nun nicht ohne jeden Hintergrund. Ich komme nicht weiter - was tatsächlich mit Sicherheit an mir liegt. Leider kann ich nicht erkennen, wo der Fehler ist.

Zitat von: supernova1963 am 08 März 2018, 07:08:41
@curt:
Bitte beachten, das du Änderungen an der /etc/sudoers unbedingt mit sudo visudo /etc/sudoersmachst.

Es ist völlig egal, mit welchem Werkzeug man sudoers bearbeitet, da wirkt keine magische Maschine im Hintergrund. Der ständige Hinweis auf visudo bedeutet lediglich, dass man nicht den geringsten Syntaxfehler machen darf.

Bislang stand dort:

fhem    ALL=(ALL) NOPASSWD: ALL


Nun steht dort:

fhem    ALL=(ALL) NOPASSWD: ALL
fhem    ALL=(ALL) NOPASSWD: /usr/bin/nmap

was im Grunde eine Doppelung ist.

Ja, ich habe nicht vergessen, das System zu booten.

Das beeindruckt FHEM genau gar nicht - der Fehler muss an einer anderen Stelle liegen.
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

@curt: Wenn du dich mit dem user fhem per ssh oder direkt in der shell anmeldest, und
sudo /usr/bin/namp 192.168.127.0/24 192.168.128.0/24 -sn
aufrufst, wird dann noch nach dem Passwort gefragt oder erhältst du direkt eine Ausgabe von nmap in der Console?

Der list fhem Befehl lautet korrekt:

list <devicename>

ohne "_" und beinhaltet mehr Informationen als der fhem.cfg Auszug hergibt.

Gernot

P.S.: Ich kann verstehen, dass es dich nervt, wenn's nicht funktioniert, aber einen Verweis auf die commandref ist imo nicht pampig.

igami

Hast du in FHEM denn auch das sudo Attribut vergeben?
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Zitat von: supernova1963 am 08 März 2018, 08:29:27
P.S.: Ich kann verstehen, dass es dich nervt, wenn's nicht funktioniert, aber einen Verweis auf die commandref ist imo nicht pampig.

Es war zugegeben wenig geschickt um Hilfe zu bitten und gleichzeitig zu kritisieren. Ja, zugegeben. Leider ist die commandref für mich oft wenig hilfreich. Sicher wird sie hilfreich, wenn ich das Modul schon im Einsatz habe und alles kann. Bein neuen Erschließen hilft mir eher ein Beispiel. Solche sind in der commandref leider sehr dünn gesät.

Zitat von: igami am 08 März 2018, 10:30:22
Hast du in FHEM denn auch das sudo Attribut vergeben?

Hallo allerseits,

ich hab ohne Ende gesucht, Forum, Wiki, commandref. Und nichts in der Sache gefunden. Aber die Blöße, nochmals nachzufragen wollte ich mir nun auch nicht geben.

Dann klickte ich in meiner nmap-Device "Netzwerk" die möglichen Attribute durch. Da steht ja ein Attribut "sudo". Das steht auf "0" und kann man auf "1" setzen. Cool, gleich mal probieren. Ahhh - wie schön. Siehe, es funktioniert. Danke!

Gleich mal ein anderes Problem:
Ich habe mehrere Netzwerke, also 192.168.127.0/24, 192.168.128.0/24 usw. Die Sortierung mit den von @supernova1963 Mitteln nutzt aber nur den vierten Block, so dass die Netzwerke munter durcheinander sind. Auf den ersten Blick dachte ich: Das kann ja nun kein Hit sein, höchstens musst Du herausfinden/fragen, wie man da eine Perl-Subroutine unterbringt. Es ginge zum Beispiel (ungestestet) so (aus https://stackoverflow.com/questions/6917314/how-can-i-sort-a-list-of-ip-addresses-in-perl):


#!/usr/bin/perl

use strict;
use warnings;

sub Compare {
    # TODO: Error checking
    my @a  = split /\./, $a;
    my @b = split /\./, $b;
    # TODO: This might be cleaner as a loop
    return $a[0] <=> $b[0] ||
           $a[1] <=> $b[1] ||
           $a[2] <=> $b[2] ||
           $a[3] <=> $b[3];
}

my @ip = qw( 172.20.1.2 10.10.2.3 10.1.2.3 192.168.1.2 );

@ip = sort Compare @ip;

print join("\n", @ip), "\n";


Dann sah ich bei genauerem Hinsehen, dass es sooo einfach nun doch nicht ist. In dem von @supernova1963 gegebenen Code wird gar nicht sortiert, da wird jediglich der letzte Block als Sortierkriterium zurückgegeben.

Gut, ich könnte die IPv4 in eine dezimale Ganzzahl wandeln und als Sortierkriterium zurückgeben - aber sehr schön sieht das dann nicht aus.

Wie müsste man die Sache anstellen? Den Entwickler des Moduls "nmap" um Aufnahme dieser Sortierung bitten? Oder ist es da vielleicht so gar drin und ich stelle mich nur wieder zu dumm an?
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Zum sortieren gibt es das Attribut leadingZeros
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

justme1968

und was spricht dagegen die in readingsGroup dafür vorgesehene rgSortIP routine zu verwenden?

siehe hier: https://forum.fhem.de/index.php/topic,14425.msg496332.html#msg496332
und hier: https://forum.fhem.de/index.php/topic,57804.msg509823.html#msg509823
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

curt

Zitat von: igami am 09 März 2018, 17:14:12
Zum sortieren gibt es das Attribut leadingZeros

Das führt in beschriebenen Fall fehl.

Zitat von: justme1968 am 09 März 2018, 17:26:38
und was spricht dagegen die in readingsGroup dafür vorgesehene rgSortIP routine zu verwenden?

Issjageil!
Dagegen spräche nichts - wenn ich das doch nur gekannt hätte. Nun kenne ich es und nun funktioniert das wunderfein.

Nun gibt es noch eine kleine Kleinigkeit an der ich trotz vieler Experimente scheitere, die Optik. Mein Bezug ist Beitrag #30, ich nutze den Vorschlag von @supernova1963 , viellleicht kann er mir dabei helfen: Die Spalte 1 (Dreieck und "Nr") sowie Spalte 4 ("Rechnername") halte ich in meinem Fall für entbehrlich, das würde ich gern wegmachen wollen.

Das ich die "sortColumn" dann ändern muss ist mir klar. Mir ist auch klar, dass dem Attribut "valueFormat" anschließend etwas zu ändern ist. Aber ich scheitere trotz vieler Experimente schon am define für die readingsGroup - anschließend sehe ich nur eine leere Tabelle. Was tun?
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#42
Ich habe laienhaft versucht deinen Vorstellungen entsprechend die Definition zu ändern.
Die Definition einer readingsGroup ist imo wirklich tricky.
Wo ich etwas länger gebraucht habe um es zu verstehen, ist, dass mit dem nmap:@<SpaltenNr> die Spalte angegeben werden muss, in der die Regex (.*)<immer gleicher Teil des Readings-Namens> für die Gruppierung steht.

z.B. Achtung "raw Definition" und ohne rgSortIP Routine!

defmod nmapListe2 readingsGroup <>,<IP-Adresse>,<onl>,<MAC>,<Hersteller> \
nmap:@3,#1_ip,#1_state,(.*)_macAddress,#1_macVendor
attr nmapListe2 valueFormat { if ($VALUE eq 'absent') {\
     "<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>"\
     }\
  elsif ($VALUE eq 'present') {\
     "<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>"\
     }\
  else {\
    ""\
    }\
}
attr nmapListe2 sortFn rgSortIP
attr nmapListe2 valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}



Hoffentlich hilft es dir und ist nicht ganz falsch,

Gernot

curt

Zitat von: supernova1963 am 10 März 2018, 06:23:44
Ich habe laienhaft versucht deinen Vorstellungen entsprechend die Definition zu ändern.
Die Definition einer readingsGroup ist imo wirklich tricky.

Du beschreibst meine Probleme aber sehr schön.

Und ich habe einen neuen Stand:
Ich habe nun via commandref gelernt, dass man den "Rechnernamen" via 192.168.127.1:Router_eth0 quasi von Hand setzen kann. Ganz prima, die Sache.

Du hast es mir ja verboten, aber ich löschte dann direkt in der fhem.cfg MAC und Hersteller. MAC kommt nicht über verschiedene Netzwerke, damit Hersteller auch nicht. Das bleibt faktisch immer leer. Das sieht bei mir auch ganz schick aus, siehe mal bitte das Bild.

Aber nun zu readingsGroup und der Formatierung - da verstehe ich viele Sachen nicht. Ich zitiere mal den aktuellen Stand meiner fhem-Dinge:

define Netzwerk Nmap 192.168.127.0/24 192.168.128.0/24 192.168.1.0/24
attr Netzwerk absenceThreshold 1
attr Netzwerk devAlias 192.168.127.1:Router_eth0
attr Netzwerk keepReadings 1
attr Netzwerk leadingZeros 0
attr Netzwerk room 92 Intranet
attr Netzwerk sudo 1

define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<Status>,<Name> \
Netzwerk:@4,#1_ip,<#1>,#1_state,(.*)_alias
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Intranet
attr NetzwerkListe sortColumn 1
attr NetzwerkListe sortFn rgSortIP
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'Nr' zur Sortierung aus der IP extrahieren    \
  return(substr($VALUE,rindex($VALUE,".")+1)) if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("<a url='http://".$ipAddr."' onclick='window.open(\"http://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "80");;\
  return("<a url='https://".$ipAddr."' onclick='window.open(\"https://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "443");;\
  #Anderenfalls soll das valueFormat leer bleiben bzw. nachstehenden Inhalt verwenden\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}


* Eigentlich will ich gar nicht Dein "http bei '*-80'": Ich will den Link auf Port 80 immer. Da habe ich mich erfolglos versucht. (Ich verstand das return-Prinzip nicht.)

* Schaue Dir bitte auch nochmal mein Bild an. Ganz links steht ja "Nr" und danach kann man ja sortieren. Brauche ich so nicht, diese "Nr" sagt in meinem Fall ja nichts. Kann diese "Nr" weg?

Kann ich das auf eine andere Spalte ändern? Oder kann ich das gar wie bei Wikipedia-Tabellen mehrere Spalten sortierbar  machen?

Danke für Deinen Langmut - das nmap-Modul ist geil!
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#44
Zitat von: curt am 13 März 2018, 03:12:55
* Eigentlich will ich gar nicht Dein "http bei '*-80'": Ich will den Link auf Port 80 immer. Da habe ich mich erfolglos versucht. (Ich verstand das return-Prinzip nicht.)

* Schaue Dir bitte auch nochmal mein Bild an. Ganz links steht ja "Nr" und danach kann man ja sortieren. Brauche ich so nicht, diese "Nr" sagt in meinem Fall ja nichts. Kann diese "Nr" weg?

Kann ich das auf eine andere Spalte ändern? Oder kann ich das gar wie bei Wikipedia-Tabellen mehrere Spalten sortierbar  machen?
Ungetestet, nur deinen Code geändert (wo immer er herkommt ;) ): Ohne Nr - Spalte und mit generellem Link bei Klick der IP Adresse:
define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<Status>,<Name> \
Netzwerk:@3,<#1>,#1_state,(.*)_alias
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:2" => 'style="text-align:center"'}
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Intranet
attr NetzwerkListe sortFn rgSortIP
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'IP' mit Link "http://<IP>" \
  return("<a url=\"http://$ipAddr\" onclick='window.open(\"http://$ipAddr\")')>$ipAddr</a>") if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}

Spalte "Nr" entfernt:
"<Nr>" aus Überschrift entfernt, Gruppierungsspalte angepaßt: "Netzwerk:@3" und Datenspalte "$1_IP" entfernt. Zusätzlich die Spaltennummern des Attributes "cellStyle" geändert.
URL auf die Werte der IP gelegt.

Wenn ich es richtig verstanden habe, wird das Attribut valueStyle auf jede Wertausgabe der readingsGroup angewendet und die bedingten return's werden statt dem Wert in die Zelle eingetragen. Zur Verfügung stehen die Variablen $READING und $VALUE.

Ich hoffe es hilft,

Gernot

curt

Das brachte leider nicht den gewünschten Erfolg. Keine Links auch nur zu erahnen, auch im html-Quelltext nicht. Und die letzte Spalte leer. Ok, mal spielen.

So funktioniert es, der Link ist in der ersten Spalte:

define NetzwerkListe readingsGroup <>,<IP-Adresse>,<Status>,<Name> \
Netzwerk:@3,#1_ip,#1_state,(.*)_alias
[/quote]

Nun darf mich aber niemand fragen, warum das funktioniert. Und warum da @3 stehen muss und @1 nicht funktioniert.

Ich freue mich. Danke!
RPI 4 - Jeelink HomeMatic Z-Wave

curt

Ich weiß, dass das mit nmap primär gar nichts zu tun hat. Aber in der Tabelle würde ich bei den Debian- bzw. Linux-Systemen als Information ja schön machen, wenn man sehen könnte, dass Updates vorliegen.

Wie man Updates bei entfernten Maschinen grundsätzlich erkennen kann, ist in https://www.soeren-hentzschel.at/sonstiges/debian-server-auf-updates-prufen-via-shell-script/ ganz schön beschrieben. Mit einer Frequenz von 900 aufrufen ist natürlich Quatsch.

Im Forum nach "update debian server" suchen - da findet man natürlich 5.000 Seiten, die sich mit anderen derartigen Problemen beschäftigen.

Jemand eine Idee?
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#47
Zitat von: curt am 14 März 2018, 01:52:51
Nun darf mich aber niemand fragen, warum das funktioniert. Und warum da @3 stehen muss und @1 nicht funktioniert.

Damit du antworten kannst: Die "@3" gibt die Spalte an, nach der die readings gruppiert werden und muss auf die Spalte mit der Gruppierungs-Regex, im vorliegenden Fall: (.*)_alias, zeigen.

Da der Namensaufbau der Readings bei Nmap <IP>_<Wertbezeichner> ist und nach IP gruppiert werden soll, kann man an-für-sich nach jeder Spalte gruppieren. Da aber die Werte in den anderen Spalten mit valueFormat "manipuliert" werden sollen, habe ich diese Spalte gewählt.

Gernot

OffTopic: System-/Update-Stati der gefundenen Netzwerkgeräte
Sehe ich eher als eigenes Thema. Ggf. wäre es sogar möglich, im Nmap-Modul ein Art autoCreate für fhem Devices zu ergänzen, das dann wiederum Gerät-spezifische Zusatzinformationen einholt.
Mit einer eindeutigen Beziehung zu Nmap Readings (z.B. MAC-Adresse oder Netzname), könnte man dann eine geeignete ReadingsGroup erstellen.

curt

Zunächst nochmals mein herzlicher Dank.

Zitat von: supernova1963 am 14 März 2018, 06:55:40
OffTopic: System-/Update-Stati der gefundenen Netzwerkgeräte. Sehe ich eher als eigenes Thema.

Das versuchte ich schon in einem eigenen Thema zu diskutieren, hier: https://forum.fhem.de/index.php/topic,85498.0.html

Das Modul SYSMON https://wiki.fhem.de/wiki/SYSMON scheint in diese Richtung zu gehen. Das habe ich installiert, allerdings lediglich auf dem FHEM-Server, (noch) nicht die Abfrage der "inneren Werte" anderer Server angefasst. Möglicherweise kann man da die Abfrage des Update-Status selbst anfrickeln. Was mir da aber weniger gefällt: Die Abfrage läuft über telnet. Das halte ich für eine ganz schlechte Idee.

Ein völlig anderer Ansatz wäre xymon, welches @Reinhart in FHEM integrieren konnte. Das habe ich nicht installiert, mich schreckt ab, dass da der nächste Webserver um die Ecke guckt. Und da fehlt mir auch jede Idee, wie man den Update-Status integiert - vermutlich überhaupt nicht.

Zitat von: supernova1963 am 14 März 2018, 06:55:40
Ggf. wäre es sogar möglich, im Nmap-Modul ein Art autoCreate für fhem Devices zu ergänzen, das dann wiederum Gerät-spezifische Zusatzinformationen einholt.

Ich habe ja inzwischen gelernt, dass alles was nicht weglaufen kann, ein Device wird. Also warum nicht, der Gedanke hat ja Charme. Das liefe wohl auf ein neues Modul hinaus? Das kann ich nicht, dafür bin ich zu frisch - oder zu alt. Wir fragen mal igami was er von diesem Gedanken hält.

@igami
Die Idee besteht darin, dass jeder Teilnehmer (Server, aber auch Clients wie Handy usw.) ein Device der (noch nicht vorhandenen) Klasse "Netzwerkgerät" wird. Ein konkretes Device hat dann Eigenschaften (Readings, ich hab's gelernt) wie IP, MAC, lastSeen, CPU_temp, platte_1_Auslastung, updates_vorhanden, da kann man sich ja viel ausdenken. Ich denke allerdings weniger an sekundengenau, eher schon an Aktualisierungswerte 300..900.

Zitat von: supernova1963 am 14 März 2018, 06:55:40
Mit einer eindeutigen Beziehung zu Nmap Readings (z.B. MAC-Adresse oder Netzname), könnte man dann eine geeignete ReadingsGroup erstellen.

MAC-Adresse ist kein Allheilmitel, ganz im Gegenteil. Ich erklär's.
Eine typische einfache Netzstruktur ist die von Kevin Schulz: Vorn der Router vom Provider, Wlan onboard. Das wächst über die Zeit, aber alles ist im 192.168.1.0/24. Und typischerweise DHCP for all. Da und nur da funktioniert die Eindeutigkeit via MAC.

In dem anderen nmap-Thread war ab und an zu lesen "aber der liefert gar keine MAC" - und dort wurde das nie aufgeklärt.

Das liegt daran, dass dann mehrere Subnetze, also mehr als ein Router im Spiele sind - nmap aber nur in einem Subnetz sein kann. Wenn es nun über eine Subnet-Grenze geht, fliegt die MAC weg. Wird von nmap schlicht nicht gesehen.

Bei mir ist es so, dass praktisch alles statische Adressen sind. Lediglich ein kleiner Bereich ist DHCP für Sonderfälle.

Damit müsste das (nicht vorhandene) IP-Device-Modul als "Kennung" alternativ IP, MAC, devAlias (von nmap-device!) haben.

Das waren meine Überlegungen dazu. Mal sehen, was @igami sagt.
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Ist wirklich schon ein bisschen offtopic mittlerweile und wir sollten es in einem andern Thread weiter diskutieren.

Warum habe ich das Nmap Modul geschrieben? Ich wollte automatisch neue Geräte im WLAN erkennen und dann automatisierte Funktionen ablaufen lassen (z.B. das Gerät einer Person zuweisen für Anwesenheitserkennung). Dabei ist es aber leider geblieben und ich nutze das Modul selbst eigentlich gar nicht mehr ::)
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Zitat von: igami am 14 März 2018, 20:30:08
Ist wirklich schon ein bisschen offtopic mittlerweile und wir sollten es in einem andern Thread weiter diskutieren.

Gern - wo wäre es denn recht?
https://forum.fhem.de/index.php/topic,85498.0.html wäre ok?

Zitat von: igami am 14 März 2018, 20:30:08
und ich nutze das Modul selbst eigentlich gar nicht mehr ::)

<lacht> Darf ich Dir Deinen einzigen Nutzer vorstellen?

Nein, im ernst: Warum nutzt Du es nicht mehr? Was nutzt Du nun? (Vielleicht ist das ja viel schöner ... auch für uns.)
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Zitat von: curt am 14 März 2018, 20:54:52
Gern - wo wäre es denn recht?
https://forum.fhem.de/index.php/topic,85498.0.html wäre ok?
sofern es um das Thema geht ja

Zitat von: curt am 14 März 2018, 20:54:52
<lacht> Darf ich Dir Deinen einzigen Nutzer vorstellen?
Laut Statistik "nutzen" es ja auch noch andere, bei mir läuft es ja auch noch mit, ich Werte es nur nicht aus.

Zitat von: curt am 14 März 2018, 20:54:52
Nein, im ernst: Warum nutzt Du es nicht mehr? Was nutzt Du nun? (Vielleicht ist das ja viel schöner ... auch für uns.)
Die Zuordnung von 6 Geräten zu einem Bewohner durch einen Automatismus stand nicht im Verhältnis Aufwand/Nutzen.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Ich möchte Dich um etwas bitten. Ich möchte Dich darum bitten, Dein Modul testweise zu erweitern.

Zitat von: igami am 15 März 2018, 06:00:21
Die Zuordnung von 6 Geräten zu einem Bewohner durch einen Automatismus stand nicht im Verhältnis Aufwand/Nutzen.

Nun ist es aber so, dass mindestens mal ich (aber auch supernova1963) Potential in Deinem nmap-Modul erkannt haben. Offenbar Potenzial, welches Du selbst wegen Deiner 6 Geräte und Deiner ursprünglichen Intension nicht siehst.

Schau mal bitte mich an:
Ich habe gerade den RPi Zero W entdeckt, den gibt es aktuell für 11 Euro plus Versand. Das ist also ein vollwertiger Server und schon Wlan an Bord. Das ist billiger als jeder Sensor. Ok, wir brauchen noch USB-Strom und SD-Card- Aber dann haben wir zig Server im Wlan. Das schreit nach Automatisierung,  nach Überwachung: Wie geht es denen denn? Gibts die noch? Haben die Wehwehchen?

Dein nmap-Modul ist da der geniale erste Schritt: Das fängt alles ein, was nicht bei drei auf dem Baum ist. Und (leider) sehr rudimentäre Detailinformationen gibt es kostenlos dazu. Das ist schon mal sehr schön für ein künftiges Hausnetz.

Nun muss noch mehr an Infos rum, es werden ja viele kleine Server: CPU-Temperatur, Platte noch was frei, Update notwendig? Klar wird das ohne die Server, die bezogen auf FHEM-Modul nmap Clients sind nicht gehen. Aber das ist eine andere Sache, das kommt viel später.

Die Idee von supernova1963 ist nicht dumm: Jedes Gerät mit IP-Adresse muss ein FHEM-Device werden. Ein Device mit irgendwelchen zwei Readings und irgendwelchen zwei Attributen erstmal. Als erster Schritt.

Andere Module können offensichtlich neue Devices anlegen. Ich habe mal (etwas Perl kann ich) Dein Modul überflogen. Und Module, die Devices anlegen. Mit dem Ergebnis, dass ich dachte: Ok, so viel Perl kann ich nun wieder nicht.

Also möchte ich Dich bitten, das testweise zu bauen.

Ja, der Primärschlüssel ist problematisch: MAC kann es nicht sein, weil die MAC über mehrere Subnetze nicht verfügbar ist.

@supernova1963 @igami
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Ich habe noch nicht ganz verstanden was ich nun Einbauen soll. Ein Autocreate, damit jedes gefundene Gerät ein eigenes Device wird?
Das lässt sich über ein Notify lösen.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Ich wusste nicht, dass das über "notify" möglich ist. Offen gesagt habe ich gar keine Erfahrung mit "notify". Und das Nachlesen hat mich auch nicht schlauer gemacht.

In meiner fhem.cfg finde ich ein notify
define initialUsbCheck notify global:INITIALIZED usb create
Das könnte in diese Richtung gehen - ich weiß aber auch das nicht.

Ok, ich versuche zu erklären:
Es gibt doch in nmap das Reading _alias. Das gibt es genau dann, wenn ich einer IP über eine Liste sage, wie deren Alias zu lauten hat.

Nun stelle ich mir vor, dass beim erstmaligen Auftreten (und nur dann) eines neuen *_alias genau dafür ein Device angelegt wird. Diesem müsste mindestens _IP (besser natürlich zudem auch _alias) mitgegeben werden.

Ich möchte Dich darum bitten, mir (kurz) zu erklären,  wie ich das anstelle.

(Vielleicht geht die Idee von @supernova1963 völlig fehl, aber unabhängig davon habe ich dann wenigstens was gelernt.)


RPI 4 - Jeelink HomeMatic Z-Wave

igami

zu notify:
Zitat
Führt eine oder mehrere Anweisungen aus, wenn ein Event generiert wurde, was dem <Suchmuster> (Gerätename oder Gerätename:Event) entspricht.

Nmap bietet dafür:
Zitat
Wird ein neues Gerät erkannt wird ein Event "<name> new host: <hostname> (<IPv4>)" erzeugt.

Also braucht man ein notify welches vereinfacht dargestellt so aussieht:

define new_host_notify notify Nmap:new.host:..+ {<perl um Device Namen festzulegen und IP und alias zu ermitteln>; fhem("define ...");}
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

Super, dass Event "<name> new host: <hostname> (<IPv4>)" habe ich bisher wohl übersehen.

Wäre es nicht sinnvoller an Stelle des "... fhem("define ...");}" ein "... fhem("defmod ...");}" zu verwenden damit, wenn vorhanden, kein Fehler entsteht?

Jetzt stellt sich nur noch die Frage auf Basis welchen Moduls das device erstellt werden soll. Zum Testen reicht sicher ein Dummy, dem man "händisch" die gewünschten readings beibringt.

Im Idealfall gäbe es eine Art "nmapClient Modul", das z.B. über eine nmap Port-Abfrage, ssh oder Vergleichbarem versucht Dienste zu erkennen (http, https, ssh, telnet, ftp, sql-Server, mqtt, ha-bridge, fhem-Server, ...) und diese z.B. als Link in einem reading anbietet.
Wenn möglich, könnte je nach erkanntem Betriebssystem, ein Systemmonitor-Device mit einer geeigneten Verknüpfung z.B. über die Namensgebung angelegt. Auch das von curt gewünschte Update reading könnte in das Modul integriert werden.
Für fhem-Einsteiger wäre vielleicht sogar ein optionales autoCreate der gefundenen Systeme denkbar (HMCCU, VCCU, MQTT, ESPEasy, Netatmo, ...)
...

Die Wunschliste erhebt keinen Anspruch auf Vollständigkeit! 
   
Wie ich feststellen mußte, fehlen mir das notwendige Nmap-/Perl-/Fhem-Wissen.

Ein schönes, sonniges Wochenende,

Gernot



curt

Zitat von: supernova1963 am 18 März 2018, 14:17:17
Super, dass Event "<name> new host: <hostname> (<IPv4>)" habe ich bisher wohl übersehen.
Wäre es nicht sinnvoller an Stelle des "... fhem("define ...");}" ein "... fhem("defmod ...");}" zu verwenden damit, wenn vorhanden, kein Fehler entsteht?

Bezogen auf die Aufgabenstellung "anhand des *_alias" vermutlich nicht. Denn das Device soll nur einmal erstellt werden - nicht immerzu neu, wenn das physikalische Gerät mal abwesend war.

Zitat von: supernova1963 am 18 März 2018, 14:17:17
Jetzt stellt sich nur noch die Frage auf Basis welchen Moduls das device erstellt werden soll. Zum Testen reicht sicher ein Dummy, dem man "händisch" die gewünschten readings beibringt.

Du bist mir immer zu schnell. Mir würde jetzt erstmal reichen, wenn jemand (Du?) mal den Befehl richtig ausformuliert - also so, dass anschließend bei mir neue Devices entstehen.

Zitat von: supernova1963 am 18 März 2018, 14:17:17
Im Idealfall gäbe es eine Art "nmapClient Modul", das z.B. über eine nmap Port-Abfrage, ssh oder Vergleichbarem versucht Dienste zu erkennen (http, https, ssh, telnet, ftp, sql-Server, mqtt, ha-bridge, fhem-Server, ...) und diese z.B. als Link in einem reading anbietet.

Du bist aus meiner Sicht viel-viel zu schnell. Zuerst benötigen wir wie gesagt das Obige. Dann atmen wir mal tief durch. Dann denken wir konzeptionell weiter. Nmap kann das im Ergebnis sein, muss es aber nicht. Da fiele mir noch anderes ein.
   
Zitat von: supernova1963 am 18 März 2018, 14:17:17
Wie ich feststellen mußte, fehlen mir das notwendige Nmap-/Perl-/Fhem-Wissen.

Nmap könnte ich. Perl langt für den Hausgebrach, derzeit aber nicht für neue Module. Fhem ... ich übe ...

Wer gibt mir nun den korrekten Code nach der Andeutung von @igami ?
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Zitat von: curt am 18 März 2018, 22:36:00
Nmap könnte ich. Perl langt für den Hausgebrach, derzeit aber nicht für neue Module. Fhem ... ich übe ...

Wer gibt mir nun den korrekten Code nach der Andeutung von @igami ?
Wäre das dann nicht eine gute Einstiegsaufgabe für dich? Du hast ja selbst Vorstellungen was du erreichen möchtest und musst nun "nur" noch das notify dazu schreiben.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

#59
Es fehlt doch nur noch der Perl Code!

Ungetestet (unbedingt vorher prüfen!!!), würde ich es laienhaft so versuchen:

define new_host_notify notify Nmap:new.host:..+ {
my $newDeviceName = "";
my $ip = "";
my $regex = qr/host: (.*)? \(/p;
if ( $EVENT =~ /$regex/g )
  {
  $ip = $1;
  }
$regex = qr/\./p;
my $subst = '_';
$newDeviceName = $ip =~ s/$regex/$subst/rg;
fhem("defmod $newDeviceName dummy");
fhem("setreading $newDeviceName IP $ip");
fhem("set $newDeviceName ".ReadingsVal("Netzwerk",$ip.'_state','unknown'));
#...
}


Edit: ")" vergessen !

Aber das kannst du sicher besser und ausbauen. Wenn du es umgesetzt hast, poste doch mal deine rawDefinition des notify's.

Gernot

curt

Ich habe das mal laienhaft so übernommen, das ging so ohne Fehler:
define new_host_notify notify Netzwerk:new.host:..+ {\
my $newDeviceName = "";;\
my $ip = "";;\
my $regex = qr/host: (.*)? \(/p;;\
if ( $EVENT =~ /$regex/g )\
  {\
  $ip = $1;;\
  }\
$regex = qr/\./p;;\
my $subst = '_';;\
$newDeviceName = $ip =~ s/$regex/$subst/rg;;\
fhem("defmod $newDeviceName dummy");;\
fhem("setreading $newDeviceName IP $ip");;\
fhem("set $newDeviceName ".ReadingsVal("Netzwerk",$ip.'_state','unknown'));;\
#...\
}
attr new_host_notify room 05 Die Lage


Damit purzelt sowas in die fhem.cfg:

define 192_168_1_1 dummy
define 192_168_1_103 dummy
define 192_168_1_104 dummy


Das nehme ich jetzt mal als schönen Zwischenstand, da ich bis Ostern leider nur wenig Zeit haben werde. Herzlichen Dank!
RPI 4 - Jeelink HomeMatic Z-Wave

curt

Ganz kurz:
Es scheint mir (ungetestet) möglich, auf diesem Weg SYSMON automatisiert die IP der im Intranet befindlichen Geräte zuzuführen. Und die haben wir ja dank des NMAP-Moduls.

Je IP ein Device sowie zugehörige Attribute, das scheint automatisiert machbar. Insoweit habe ich mir SYSMON angesehen, das sollte gehen. Da hat man dann für Server Plattenbelegung und weitere Interna.

Mit einem ganz schweren Nachteil: Das läuft von FHEM-Server via TELNET. Das setzt voraus, dass auf jedem Zielsystem telnetd als Dienst installiert ist. Real schiebt SYSMON via TELNET-Login Abfrage-Befehle. Also Sicherheit sieht anders aus.

Allgemeiner:
Es stellt sich die Frage, was wir überhaupt wollen, @igami hat das vor langer Zeit sinngemäß mit 'wofür brauchst Du denn einen Portscan" auf den Punkt gebracht.

Es gibt genau zwei Versionen:

1) Zeitkritisch
Ich will genau sehen, wer JETZT (sagen wir: vor einer Minute) in meinem Netz ist. Und wie es dem geht.

2) Systemkritisch
Zeit ist relativ untergeordnet, ich will aber sehen wie es dem Plattenplatz geht, ob die Hardwareports Schluckauf haben, ob mal wieder ein Update anliegt. - Da reicht "einmal am Tag", vielleicht noch weniger.

1) und 2) beißen sich, das kann man nicht gleichzeitig haben.

Für 2) Muss definitiv ein aktiver Client auf der Seite der zu überwachenden Server sein. Soweit das hier als grundsätzliche Basis diskutierte Modul NMap besteht, muss man damit leben, dass im Intranet angemeldete Handys usw. genau nichts liefern, da können wir ja keinen Zulieferer installieren.

Grenzfall ist der von @supernova1963 immer wieder angeforderte Portscan. Der könnte durchaus in der Fallgruppe 2) einmal täglich laufen. Oder (ich bin nicht fähig, FHEM-Knöpfe mit Aktionen zu machen) der Portscan ist abhängig von einer realen Aktivität eines Nutzers (Nutzer klickt Link).

P.S: Da @supernova1963 sagte, dass er sich mit NMap nicht auskennt: Probiere mal dieses auf die IP Deines Netzes:
nmap -sS -O -p1-1024 192.168.1.123

Du erhältst die offenen Ports im Bereich 1 - 1024 (die möglichen offenen Ports gehen bis 65536, bis 1024 ist aber typisch). Du erhältst zudem eine von außen gemachte Abschätzung, welches Betriebssystem Dir da eigentlich antwortet.
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

Vielen Dank für deine Nmap Parameter Empfehlung.
Sie hilft mir nicht wirklich, da insbesondere Homeautomation Geräte i.d.R. Ports > 1024 verwenden.
Ich hatte eher an:
sudo nmap -v -O 192.168.1.10
Den Unterschied sehe bzw. kenne ich nicht, aber OS X HighSierra, Tasmota oder ESPEasy werden in beiden Fällen nicht erkannt.
(Der Bitte um Erfassung des fingerprints in einem web-Formular, dass an eine Adresse, die ich nicht kenne, gesendet wird, habe ich bisher nicht erfüllt, weil ich den Inhalt bzw. die in meinem System mit root Rechten zusammengetragenen Daten nicht kenne.)
Insgesamt dauert der scan auch ohne Betriebssystemerkennung bei nicht Windows oder Linux Geräten ca. 1 bis 2 Minuten.

Weißt du, welche Daten in den Fingerprints abgelegt werden und gibt es die Möglichkeit z.B. über eine lokale Datei mit fingerprints die Erkennung gezielt zu erweitern und zu beschleunigen?

Danke

Gernot

P.S.: Hier eine erweiterte Variante mit Erstellung von Dummies dessen readings aktualisiert werden, wenn ein neuer nmap Scan gelaufen ist (mit Link auf die IP Adresse, unabhängig ob der Port 80 vorhanden ist oder nicht):


defmod nmapClientAddNew notify nmap:new.host:..+ {\
my $newDeviceName = "";;\
my $ip = "";;\
my $alias = "";;\
my $temp = "";;\
my $regex = qr/new host:\s(.*)?\s\((.*)\)/p;;\
\
if ( $EVENT =~ /$regex/g ) \
{\
$alias = $1;;\
$temp = $1;;\
$ip = $2;;\
}\
$regex = qr/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/p;;\
if ( $ip =~ /$regex/ )  \
{\
$regex = qr/\./p;;\
my ($A,$B,$C,$D) = split(/\./, $ip);;\
$newDeviceName = substr("000".$A, -3, 3)."_".substr("000".$B, -3, 3)."_".substr("000".$C, -3, 3)."_".substr("000".$D, -3, 3);;\
}\
else\
{\
$newDeviceName = $alias;;\
}\
\
fhem("defmod ".$newDeviceName." dummy");;\
fhem("attr ".$newDeviceName." room nmap");;\
fhem("attr ".$newDeviceName." group nmapClient");;\
fhem("attr ".$newDeviceName." devStateIcon present:10px-kreis-gruen absent:10px-kreis-rot .*:10px-kreis-gelb");;\
fhem("setreading ".$newDeviceName." IP ".$ip);;\
my $userreadings = ""\
."state { ReadingsVal('nmap','".$ip."_state','na');;;;},"\
."hostname { ReadingsVal('nmap','".$ip."_hostname','na');;;;},"\
."macAddress { ReadingsVal('nmap','".$ip."_macAddress','na');;;;},"\
."macVendor { ReadingsVal('nmap','".$ip."_macVendor','na');;;;},"\
."http80 { return('<html><a href=\"http://".$ip."\"><img src=\"/fhem/images/default/icoWelt.png\"></a></html>');;;;},"\
."lastSeen { ReadingsVal('nmap','".$ip."_lastSeen','na');;;;},"\
."uptime { ReadingsVal('nmap','".$ip."_uptime','na');;;;},"\
."uptimeText { ReadingsVal('nmap','".$ip."_uptimeText','na');;;;}";;\
fhem("attr ".$newDeviceName." userReadings ".$userreadings);;\
fhem("set ".$newDeviceName." ".ReadingsVal('nmap',$ip.'_state','na'));;\
}
attr nmapClientAddNew room nmap

defmod nmapClientUpdate notify nmap:done { fhem("set 192.168.* 1");;}
attr nmapClientUpdate room nmap



 

curt

Ich habe leider bis Ostern sehr wenig Zeit.

Zitat von: supernova1963 am 22 März 2018, 19:12:43
Vielen Dank für deine Nmap Parameter Empfehlung.
Sie hilft mir nicht wirklich, da insbesondere Homeautomation Geräte i.d.R. Ports > 1024 verwenden.

Das ist kein Problem. Die anzusprechenden Ports werden über den Parameter -p gesteuert. Wenn Du beispielsweise viel Zeit hast, kannst Du mal alle möglichen Ports abklappern: "-p1-65536". Das dauert natürlich. Du kannst auch gruppieren, dann wird mit Komma getrennt: "-p23,80,443,2222-2290" geht beispielsweise auch. Wenn Du also die Ports der von Dir genannten Systeme kennst, können wir uns die anderen Ports ja sparen.

Allgemein gilt:
Ein Portscan ist eine Sache, die man ab und an macht. Es erscheint sinnlos, das alle 5 Minuten oder jede Stunde zu machen. Einmal am Tag - ist im Grunde schon viel zu viel.

Zitat von: supernova1963 am 22 März 2018, 19:12:43
aber OS X HighSierra, Tasmota oder ESPEasy werden in beiden Fällen nicht erkannt.

Das liegt daran, dass nmap mit vielen Heuristiken eigentlich rät. Wenn ein System nur einen oder gar keinen Port offen hat, ist das ausnehmend schwierig - Stichwort Firewall. Aber dieses Feature ist auch nicht dafür gedacht, eine ordentliche Doku der eigenen Systemlandschaft anzulegen, das kommt schon aus dem Baukasten für den kleinen Nachwuchs-Hacker ...

Zitat von: supernova1963 am 22 März 2018, 19:12:43
Weißt du, welche Daten in den Fingerprints abgelegt werden und gibt es die Möglichkeit z.B. über eine lokale Datei mit fingerprints die Erkennung gezielt zu erweitern und zu beschleunigen?

Das sagt Dir nmap doch selbst. Da steht nach einem Scan (bei mir): "Read data files from: /usr/bin/../share/nmap". Das ist also real /usr/share/nmap - da liegen die von Dir gesuchten Dateien.

Vermutlich (!) kannst Du Dir neuere Dateien von der nmap-Projektseite holen, ich selbst habe das noch nie auch nur in Erwägung gezogen.

Zitat von: supernova1963 am 22 März 2018, 19:12:43
P.S.: Hier eine erweiterte Variante mit Erstellung von Dummies dessen readings aktualisiert werden, wenn ein neuer nmap Scan gelaufen ist (mit Link auf die IP Adresse, unabhängig ob der Port 80 vorhanden ist oder nicht):

Leider habe ich im Moment keine Zeit, sonst würde ich mir das mal genauer anschauen.

Ich hatte nun SYSMON derart angesehen, als das ich auf einem zu überwachenden Testsystem TELNET freischaltete. Und mal schaute, was da eigentlich passiert. Denn es scheint ja möglich, das Erstellen der neuen Device so anzupassen, dass die gleich in das Beuteschema von SYSMON fällt, also dessen Überwachung/Darstellung anheim fällt.

Mal ganz abgesehen von TELNET (fällt aus, damit machen wir das nie) ist da wieder mein Problem: Ich sehe die Readings, kann die aber im Grunde nicht formatieren - meine Schwachstelle.

Das von @Reinhart in https://forum.fhem.de/index.php/topic,85498.0.html vorgeschlagene xymon habe ich mir noch nicht daraufhin angesehen, ob man dem auch Devices unterschieben kann.
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

Danke für die Erläuterung von Nmap.

Bei dem Thema Serverüberwachung bin ich raus.
Der Ansatz von fhem bzw. anderen Geräten Internas eines Servers abzufragen ist imo nicht der geeignete Ansatz. Server sollten sich, bis auf wenige Punkte z.B. LAN Status und ggf. offene Ports, selbstständig überwachen und wichtige Informationen von sich aus melden. Dafür gibt es etliche Tools je Betriebssystem. Um diese Daten in Fhem anzuzeigen, wäre z.B. ein Tool bzw. Script für ein Tool sinnvoll, das die gewünschten Informationen an einen MQTT Broker sendet. Diese können dann von Fhem empfangen und optisch aufbereitet angezeigt werden.

Ich wünsche dir frohe Ostern, und hoffe, dass du deine Ideallösung findest.

Gernot

curt

@supernova1963 @igami
Zitat von: supernova1963 am 22 März 2018, 19:12:43P.S.: Hier eine erweiterte Variante mit Erstellung von Dummies dessen readings aktualisiert werden, wenn ein neuer nmap Scan gelaufen ist (mit Link auf die IP Adresse, unabhängig ob der Port 80 vorhanden ist oder nicht):

Das habe ich testweise aufgenommen (siehe Grafik - das muss so aussehen?).

Ich habe nicht verstanden - erkläre bitte:
Was genau ist der Unterschied der bisherigen Version zu der nun von Dir vorgeschlagenen Version? Was ist da anders? Was sind die Vorteile?

Zitat von: supernova1963 am 23 März 2018, 05:55:44
Bei dem Thema Serverüberwachung bin ich raus.
Der Ansatz von fhem bzw. anderen Geräten Internas eines Servers abzufragen ist imo nicht der geeignete Ansatz. Server sollten sich, bis auf wenige Punkte z.B. LAN Status und ggf. offene Ports, selbstständig überwachen und wichtige Informationen von sich aus melden. Dafür gibt es etliche Tools je Betriebssystem. Um diese Daten in Fhem anzuzeigen, wäre z.B. ein Tool bzw. Script für ein Tool sinnvoll, das die gewünschten Informationen an einen MQTT Broker sendet. Diese können dann von Fhem empfangen und optisch aufbereitet angezeigt werden.

Ich glaube da liegt -mit Verlaub- der Denkfehler.
Natürlich kann ich beispielsweise Wettervorhersagen im Web abrufen. Und ich kann ich als iframe in FHEM einbinden. Geht, kein Problem. Trotzdem haben mehrere Programmierer mehrere Module geschrieben, um diese Informationen quasi nativ in FHEM zu haben.

Mit Serverüberwachung kenne ich mich aus - oder sagen wir besser: Lasse ich mich auskennen. Klar könnte ich irgendwo ein Nagios aufsetzen. Oder Xymon oderoderoder. Das ist aber alles nicht nativ, da ist dann immer ein weiterer Überwachungsserver im Spiel. Oder man packt das Nagios mit auf den Server, der auch FHEM hostet - ändert aber auch nichts.

Den wirklich genialen gedanklichen Ansatz hattest Du:
Jedes Gerät hinter einer IP ist ein Device. Ein Device mit ganz konkreten Eigenschaften. (Diese Eigenschaften haben wir immer nur nacheilend, nie realtime. Es kann bei FHEM nicht um realtime gehen!)

Selbstverständlich hast Du recht:
Es gibt für jede IP Eigenschaften, die man von außen sehen kann. Vermittels nmap beispielsweise. (Wobei nmap hier eine Doppelfunktion hat: Es liefert vor allem die Information, welche IP überhaupt verfügbar sind!).

Die internen Eigenschaften eines Servers kann nur der Server selbst liefern, natürlich hast Du recht.
Entweder pusht er Daten (mal lieber nicht) oder er stellt Daten für Poll zur Verfügung. DAS setzt zwingend ein wie auch immer geartetes Programm auf der Seite der/des zu überwachenden Systems voraus. Natürlich.

Sysmon löst das so:
Sysmon erwartet auf jedem zu überwachendem System einen offenen telnet-Port sowie gültigen Account. Dann loggt sich Sysmon ein, startet verschiedene Befehle. Und greift sich die Ausgaben und hat sie nativ in FHEM.

Es scheint mir überhaupt kein Problem, die bisherige nMap-Dummy-Device-Erstellung so umzubauen, dass Devices für Sysmon entstehen. Das scheint mir wirklich eine Fingerübung.

Ich schrecke trotzdem zurück. Weil diese Systemidee auf telnet aufbaut. Das ist schon hinreichend gruselig. Zudem ist der Befehlssatz eingeschränkt: Du bekommst die CPU-Temperatur eines "normalen" Linux-Systems - oder nicht von Raspberry: Dort ist der Befehl ein anderer. Und den kennt Sysmon nicht.

Ansich wollte ich nur sagen, dass DEINE Kernidee, dass jede IP für FHEM ein Device sein muss, wirklich genial ist.

P.S: Ganz oben bitte nicht vergessen: Was macht Dein neuer Codeentwurf im Gegensatz zum bisherigen besser/schöner/toller?

PP.S: Frohe Ostern!
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#66
Hallo curt,

Zitat"Muss dass so aussehen?"
Fast, da stimmt noch etwas mit dem userReading nicht, da der Status nicht 'absent' = rot oder 'present' = grün ist (alles andere ergibt den gelben Punkt).

Aber, diese Konkretisierung des notify von igami, sollte nur die Möglichkeit zeigen, dass man auf Basis von neu erkannten Netz-Klienten ein eigenes fhem device, hier als Beispiel auf Basis des dummy - Moduls erstellen kann.
Es ist der erste Schritt, nicht mehr und nicht weniger.

Der nächste Schritt ist, statt der Anlage von fhem devices auf Basis des dummy - Moduls, ein geeignetes bestehendes oder neues fhem Modul zu verwenden.
Ich habe mich vor einiger Zeit, nur zum Verstehen von fhem, 'mal an einem netClient - Modul versucht. Damals auf Basis von fing und mit der Identifikation über die MAC - Adresse.
In der Anlage stelle ich meinen auf Nmap und auf IP zur Identifikation angepassten ersten Grobentwurf eines 74_NmapClient.pm - Moduls zur ersten Demonstration meines Gedankens ein.

UNBEDINGT BEACHTEN:
ES IST NUR EIN GROBENTWURF AUSSCHLIESSLICH FÜR ENTWICKLUNGSUMGEBUNGEN ZUR DEMONSTRATION DES SCHEMAS, AUF KEINEN FALL PRODUKTIV EINSETZBAR!!!

Ich kann kein Perl, wie man unschwer erkennen kann, und, mit der XML Schnittstelle von Nmap bin ich auch nicht klargekommen!

Vielleicht kannst du oder ein anderer Perl-Kenner es optimieren/verbessern/erweitern und ein fhem - Modul daraus machen, dass entweder einzeln oder auf Basis des notify auf die neuen Geräte aus dem Nmap - Modul von igami anlegt.

Vorgehensweise zum Testen:

1. Schritt: Folgenden Code prüfen und ggf. in eine neue Datei /opt/fhem/FHEM/74_NmapClient.pm kopieren und speichern. 
# $Id: 74_NmapClient.pm$
##############################################
#
#     74_NmapClient.pm
#     FHEM module to check remote network device using Nmap.
#
#     Author:
#
#     This file is not part of fhem.
#                  ---
#     Fhem is free software: you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 2 of the License, or
#     (at your option) any later version.
#
#     Fhem is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.
#
#     You should have received a copy of the MIT - License.
#
##############################################################################

package main;

use strict;
use warnings;
use Blocking;
use JSON;
use Data::Dumper;


sub NmapClient_Initialize($)
{
    my ($hash) = @_;

    $hash->{DefFn}         = "NmapClient_Define";
    $hash->{UndefFn}       = "NmapClient_Undefine";
    $hash->{DeleteFn}      = "NmapClient_Delete";
    $hash->{SetFn}         = "NmapClient_Set";
    $hash->{GetFn}         = "NmapClient_Get";
    $hash->{AttrFn}        = "NmapClient_Attr";
    #$hash->{ReadFn}        = "NmapClient_Read";
    #$hash->{ReadyFn}       = "NmapClient_Ready";
    $hash->{NotifyFn}      = "NmapClient_Notify";
    #$hash->{RenameFn}      = "NmapClient_Rename";
    #$hash->{ShutdownFn}    = "NmapClient_Shutdown";


    $hash->{AttrList} = ""
    ."NmapDeviceName "
    ."PortScan:on,off "
    ."PortScanInterval "
    ."Ping:off,on "
    ."PingInterval "
    ."disable:0,1"
    . $readingFnAttributes;
    return undef;
}

#######################################################################################
sub NmapClient_Define($$)
{
    my ($hash, $def) = @_;
    my @args = split("[ \t][ \t]*", $def);
    return "Usage: define <name> NmapClient <ID = Identifier>"  if(@args < 3);

    my $rc = `sudo nmap -V`;
    my $regex = qr/Nmap version\s(.*)\s\(/p;
    if ( $rc =~ /$regex/ ) {
        $hash->{NmapVersion} = $1;
      }
    else {
        return "Fehler bei der Überprüfung von Nmap!\nKann es sein, dass das Programm nicht installiert ist, oder der sudo Aufruf ohne Passwort nicht definiert ist?\nFür Debian sollte:\n sudo apt update &&sudo apt install Nmap ausreichen um Nmap zu intallieren.\nEintrag in sudoers: sudo visudo -f /etc/sudoers.d/nmap \n'fhem    ALL=(ALL) NOPASSWD: /usr/bin/nmap,'";
    }
    my ($name, $type, $id) = @args;
    $hash->{ID} = $id;
    readingsSingleUpdate($hash, "state", "Initialized", 1);
    $attr{$name}{"NmapDeviceName"} = "nmap" if (!defined($attr{$name}{"NmapDeviceName"}));
    $attr{$name}{"PortScan"} = "off" if (!defined($attr{$name}{"PortScan"}));
    $attr{$name}{"PortScanInterval"} = 60*60*24 if (!defined($attr{$name}{"PortScanInterval"}));
    $attr{$name}{"Ping"} = "off" if (!defined($attr{$name}{"UpdateScan"}));
    $attr{$name}{"PingInterval"} = 60*60*24 if (!defined($attr{$name}{"UpdateScanInterval"}));
    $attr{$name}{"group"} = "NmapClients" if (!defined($attr{$name}{"group"}));
    $attr{$name}{"room"} = AttrVal(AttrVal($name,"NmapDeviceName","nmap"),"room","nmap") if (!defined($attr{$name}{"room"}));
    $attr{$name}{"devStateIcon"} = "present:10px-kreis-gruen absent:10px-kreis-rot .*:10px-kreis-gelb" if (!defined($attr{$name}{"devStateIcon"}));
    NmapClient_SetNextTimer($hash,"all");

    delete $hash->{helper}{PORTSCANRUNNING_PID};
    delete $hash->{helper}{PINGRUNNING_PID};
    return undef;
}
#######################################################################################

#######################################################################################
sub NmapClient_Notify($$) {

    my ($hash, $dev_hash) = @_;
    my $name = $hash->{NAME};
    my $devName = $dev_hash->{NAME};
    my $regex = "";
    my $subst = "";

    return if(IsDisabled($name)); # Return without any further action if the device is disabled

    my $events = deviceEvents($dev_hash,1);

    return if( !$events );

    if($devName eq "global" && grep(m/^INITIALIZED|REREADCFG$/, @{$events}))
    {
      if (AttrVal($name,"PortScan","off") eq "on") {
        NmapClient_SetNextTimer($hash,"PortScan");
      }
      if (AttrVal($name,"Ping","off") eq "on") {
        NmapClient_SetNextTimer($hash,"Ping");
      }
      NmapClient_Basics($hash);
    }
    else {
      foreach my $event (@{$events}) {
        $event = "" if(!defined($event));
        if ($devName eq AttrVal($name,"NmapDeviceName","nmap")) {
          if (index($event,"done") != -1) {
            NmapClient_Basics($hash);
          }
        }
      }
    }
}


#######################################################################################
sub NmapClient_Undefine($$)
{
    my ($hash,$arg) = @_;

    RemoveInternalTimer($hash);

    BlockingKill($hash->{helper}{PORTSCANRUNNING_PID}) if(defined($hash->{helper}{SCANRUNNING_PID}));
    BlockingKill($hash->{helper}{PINGRUNNING_PID}) if(defined($hash->{helper}{PINGRUNNING_PID}));

    return undef;
}
#######################################################################################

#######################################################################################
sub NmapClient_Delete($$)
{
    my ($hash,$arg) = @_;

    RemoveInternalTimer($hash);

    BlockingKill($hash->{helper}{PORTSCANRUNNING_PID}) if(defined($hash->{helper}{SCANRUNNING_PID}));
    BlockingKill($hash->{helper}{PINGRUNNING_PID}) if(defined($hash->{helper}{PINGRUNNING_PID}));

    return undef;
}
#######################################################################################

#######################################################################################
sub NmapClient_Get($@)
{
  return undef;
}
#######################################################################################

#######################################################################################
sub NmapClient_Set($@)
{
  my ($hash, $name, $cmd, @args) = @_;
  my ($arg, @params) = @args;
  my $list = '';
  my $regex = '';
  my $subst = '';
  if ($cmd eq 'PortScan') {
      if ($arg eq 'on') {
        if (AttrVal($name,'PortScan','off') eq 'off') {
          $attr{$name}{"PortScan"} = $arg;
          NmapClient_StartPortScan($hash);
        }
        else {
          Log3 ($hash, 5, "$name: $cmd is already $arg");
        }
      }
      else {
          $attr{$name}{"PortScan"} = "off";
          BlockingKill($hash->{helper}{PORTSCANRUNNING_PID}) if(defined($hash->{helper}{PORTSCANRUNNING_PID}));
          RemoveInternalTimer($hash,"NmapClient_StartPortScan");
      }
  }
  elsif ($cmd eq 'PortScanInterval') {
      if ($arg < 180 || $arg >60*60*24) {
        $attr{$name}{"PortScanInterval"} = 60*60*24;
        NmapClient_SetNextTimer($hash,"PortScan");
      }
      else {
        $attr{$name}{"PortScanInterval"} = $arg;
        NmapClient_SetNextTimer($hash,"PortScan");
      }
  }
  elsif ($cmd eq 'Ping') {
      if ($arg eq 'on') {
        if (AttrVal($name,'Ping','off') eq 'off') {
          $attr{$name}{"Ping"} = $arg;
          NmapClient_StartPing($hash);
        }
      }
      else {
          $attr{$name}{"Ping"} = "off";
          BlockingKill($hash->{helper}{PINGRUNNING_PID}) if(defined($hash->{helper}{PINGRUNNING_PID}));
          RemoveInternalTimer($hash,"NmapClient_StartPing");
      }
  }
  elsif ($cmd eq 'PingInterval') {
      if ($arg < 60 || $arg >60) {
        $attr{$name}{"PingInterval"} = 60*60*24;
        NmapClient_SetNextTimer($hash,"Ping");
      }
      else {
        $attr{$name}{"PingInterval"} = $arg;
        NmapClient_SetNextTimer($hash,"Ping");
      }
  }
  elsif ($cmd eq 'BasicData') {
      NmapClient_Basics($hash);
  }
  elsif ($cmd eq 'disable') {
      if ($arg eq '1') {
        if (AttrVal($name,'disable','0') eq '0') {
          $attr{$name}{"disable"} = 1;
          BlockingKill($hash->{helper}{PORTSCANRUNNING_PID}) if(defined($hash->{helper}{PORTSCANRUNNING_PID}));
          RemoveInternalTimer($hash,"NmapClient_StartPortScan");
          BlockingKill($hash->{helper}{PINGRUNNING_PID}) if(defined($hash->{helper}{PINGRUNNING_PID}));
          RemoveInternalTimer($hash,"NmapClient_StartPing");
        }
      }
      else {
        if (AttrNum($name,"PortScanInterval",0) > 60*60*24 || AttrNum($name,"PortScanInterval",0) < 180) {
          $attr{$name}{"PortScanInterval"} = 60*60*24;
          NmapClient_SetNextTimer($hash,"PortScan");
        }
        else {
          NmapClient_SetNextTimer($hash,"PortScan");
        }
      }
  }
  else {
      $list = ""
        ."Disable:1,0"
        ." BasicData:noArg"
        ." PortScan:on,off"
        ." PortScanInterval"
        ." Ping:on,off"
        ." PingInterval";
      return "Unknown argument $cmd, choose one of $list";
  }
}
#######################################################################################

#######################################################################################
sub NmapClient_Attr($$$$)
{
    # Übergabeparamter auslesen
    my ($command,$name,$attribute,$val) = @_;
    # Einlesen des (device-)hash'es über den (als Paramter übergebenen device-)name
    my $hash = $defs{$name};
    # Beginn der Auswertung des ausgeführten Befehls:
    # Wenn der Befehl "set" ist:
    if ($command eq "set") {
        return fhem( "set $name disable $val" ) if ($attribute eq "disable");
        return fhem( "set $name PortScanInterval $val" ) if ($attribute eq "PortScanInterval");
        return fhem( "set $name PortScan $val" ) if ($attribute eq "PortScan");
        return fhem( "set $name PingInterval $val" ) if ($attribute eq "PingInterval");
        return fhem( "set $name Ping $val" ) if ($attribute eq "Ping");
        return fhem( "set $name BasicData" ) if ($attribute eq "BasicData");
    }
    # Sonst nur den Attributwert ändern
    else {
      $attr{$name}{$command} = $val;
      # Eintrag im Log (Level 5):
      Log3 ($hash, 5, "$hash->{NAME}_Attr: $attribute auf Value: ".$val);
    }
    return undef;
}
#######################################################################################

#######################################################################################
sub NmapClient_SetNextTimer($$)
{
    my ($hash,$scanmode) = @_;
    my $name = $hash->{NAME};
    my $functionName = "";
    my $rc = "";
    my $interval = "";
    if (!$scanmode) {
      my $scanmode = "";
    }
    if ($scanmode eq "PortScan" || $scanmode eq "Ping" || $scanmode eq "all") {
      if ($scanmode eq "PortScan" || $scanmode eq "all") {
          $functionName = "NmapClient_StartPortScan";
          $interval = AttrVal($name,"PortScanInterval",60*60*24);
          if (ReadingsVal($name,"PortScan","off") eq "off") {
              RemoveInternalTimer($hash,$functionName);
              return;
          }
          RemoveInternalTimer($hash,$functionName);
          InternalTimer(gettimeofday() + $interval, $functionName, $hash, 0);
          $rc = "Next timer ".$functionName.": ".FmtDateTime(gettimeofday() + $interval)."\n";
      }
      if ($scanmode eq "Ping" || $scanmode eq "all")  {
        $functionName = "NmapClient_StartPing";
        $interval = AttrVal($name,"PingInterval",60*60*24);
        if (ReadingsVal($name,"Ping","off") eq "off") {
            RemoveInternalTimer($hash,$functionName);
            return;
        }
        RemoveInternalTimer($hash,$functionName);
        InternalTimer(gettimeofday() + $interval, $functionName, $hash, 0);
        $rc = "Next timer ".$functionName.": ".FmtDateTime(gettimeofday() + $interval)."\n";
      }
      return;
    }
    else {
      RemoveInternalTimer($hash);
    }
}
#######################################################################################
#######################################################################################
sub NmapClient_StartPortScan($)
{
    my ($hash) = @_;
    return undef if (IsDisabled($hash->{NAME}));
    my $name = $hash->{NAME};
    return "PortScan = off!" if (AttrVal($name,"PortScan","off") eq "off");

    my $ip = ReadingsVal($name,"IP",undef);
    my $arg = $name."|".$ip;
    my $portname = "";
    my $blockingFn = "NmapClient_PortScan";
    my $finishFn = "NmapClient_PortScanDone";
    my $abortFn = "NmapClient_PortScanAbort";
    if (!(exists($hash->{helper}{PORTSCANRUNNING_PID}))) {
        for (my $i=0; $i <= 65000; $i++) {
          $portname = "PORT".substr("00000".$i, -5, 5);
          readingsSingleUpdate($hash, $portname, "closed", 1) if (defined(ReadingsVal($name,$portname,undef)));
        }
        $hash->{helper}{PORTSCANRUNNING_PID} = BlockingCall($blockingFn,$arg,$finishFn,600,$abortFn,$hash);
        Log3 $hash, 3, $hash->{NAME}." PortScan job run with PID: ".$hash->{helper}{PORTSCANRUNNING_PID}{pid}."!";
    }
    else {
        Log3 $hash, 3, $hash->{NAME}." Blocking Call PortScan is active, no new job started!";
        NmapClient_SetNextTimer($hash,"PortScan");
    }
}
#######################################################################################
#######################################################################################
sub NmapClient_PortScan($)
{
    my ($string) = @_;
    my ($name, $ip) = split("\\|", $string);
    my $hash = $defs{$name};
    my $result = "";
    my $rcCmd = "";
    my $scannedPorts = "";
    my $portPrefix = "";
    my $nmapCommand = "sudo nmap ".$ip;
    $result = `$nmapCommand`;
    #print $result;
    #my $regex = qr/Starting[\w\W]*at (?P<lastScan>.*)\sCE[\w\W]*Nmap scan report for (?P<netName>.*)\s\((?P<ip>.*)\)\s[\w\W]*up \((?P<latency>.*)\slatency[\w\W]*SERVICE\s*(?P<ports>.*[\w\W]*)\n\n[\w\W]*scanned\sin\s(?P<elapsed>.*)\sseconds/p;
    my $regex = qr/Starting[\w\W]*at (?P<lastScan>.*)\sCE[\w\W]*Nmap scan report for (?P<netName>.*)\s[\w\W]*up \((?P<latency>.*)\slatency[\w\W]*SERVICE\s*(?P<ports>.*[\w\W]*)\n[\w\W]*scanned\sin\s(?P<elapsed>.*)\sseconds/p;
    if ( $result =~ /$regex/ ) {

      $rcCmd = "deletereading $name PortScan.*;"
        ."setreading $name PORTScan_lastScan ".$+{lastScan}.";"
        ."setreading $name PORTScan_Name ".$+{netName}.";"
        # ."setreading $name PORTScan_IP ".$+{ip}.";"
        ."setreading $name PORTScan_latency ".$+{latency}.";"
        ."setreading $name PORTScan_Time ".$+{elapsed}.";";
    }
    $scannedPorts = $+{ports};
    if (!$scannedPorts || $scannedPorts eq "") {
      $rcCmd = $rcCmd."setreading PORTScan_OpenPorts 0;";
      return $name."|".$rcCmd;
    }

    $regex = qr/(?P<line>.*)\s?/p;
    my $portlist = "<html><table>";
    my @ports = "";
    my $i = 0;
    $rcCmd = $rcCmd."deletereading $name PORT.*;";
    my @matches = ($scannedPorts =~ /$regex/g);
    foreach my $xline (@matches) {
        if (index($xline,"MAC Address:") == -1) {
          $regex = qr/(?P<port_ID>.*)\/(?P<port_Name>.*) [\s]*(?P<port_State>.*) \s(?P<port_Description>.*)\s?/p;
          if ( $xline =~ /$regex/g ) {
            my $portPrefix = "PORT".substr("00000".$+{port_ID}, -5, 5);
            $rcCmd = $rcCmd.""
              ."setreading ".$name." ".$portPrefix."_ID ".$+{port_ID}.";"
              ."setreading ".$name." ".$portPrefix."_Name ".$+{port_Name}.";"
              ."setreading ".$name." ".$portPrefix."_State ".$+{port_State}.";"
              ."setreading ".$name." ".$portPrefix."_Description ".$+{port_Description}.";"
              ."";

            if ($+{port_ID} eq "80") {
              $rcCmd = $rcCmd.""
              ."setreading ".$name." ".$portPrefix." <html><table><tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"http://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr></table></html>;"
              ."";
              $portlist = $portlist."<tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"http://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr>";
            }
            elsif ($+{port_ID} eq "443") {
              $rcCmd = $rcCmd.""
                ."setreading ".$name." ".$portPrefix." <html><table><tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"https://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr></table></html>;"
                ."";
              $portlist = $portlist."<tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"https://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr>";
            }
            elsif ($+{port_ID} eq "21") {
              $rcCmd = $rcCmd.""
                ."setreading ".$name." ".$portPrefix." <html><table><tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"ftp://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr></table></html>;"
                ."";
              $portlist = $portlist."<tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"ftp://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr>";
            }
            elsif ($+{port_ID} eq "445") {
              $rcCmd = $rcCmd.""
                ."setreading ".$name." ".$portPrefix." <html><table><tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"smb://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr></table></html>;"
                ."";
              $portlist = $portlist."<tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td><a href=\"smb://".ReadingsVal($name,"IP","")."\">".$+{port_Description}."</a></td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr>";
            }

            else {
              $rcCmd = $rcCmd.""
                ."setreading ".$name." ".$portPrefix." <html><table><tr><td style=\"text-align:Right;; width:10%\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td>".$+{port_Description}."</td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr></table></html>;"
                ."";

                $portlist = $portlist."<tr><td style=\"text-align:Right\">".$+{port_ID}."</td><td style=\"text-align:Center;; width:10%\">".$+{port_Name}."</td><td>".$+{port_Description}."</td><td style=\"text-align:Left;; width:10%\">".$+{port_State}."</td></tr>";
              }
            push @ports, $+{port_ID};
            $i = $i + 1;
          }
        }
    }
    $rcCmd = $rcCmd."setreading $name PORTScan_OpenPorts $i;";
    $portlist = $portlist."</table></html>";
    $rcCmd = $rcCmd."setreading $name PORTScan_List $portlist;";
    my $temp = "";
    foreach my $port (@ports) {
      if ($temp eq "") {
        $temp = $port;
      }
      else {
        $temp = $temp.",".$port;
      }
    }
    $rcCmd = $rcCmd." setreading $name PortScan_Ports $temp;";
    return $name."|".$rcCmd;
}
#######################################################################################
#######################################################################################
sub NmapClient_PortScanDone($)
{
    my ($string) = @_;
    my ($name, $rcCmd) = split("\\|", $string);
    my $hash = $defs{$name};
    my $errors = AnalyzeCommandChain ($hash, $rcCmd);
    if (!defined($errors)) {
      Log3($name, 5,"Success for PortScan: $rcCmd !");
    }
    else {
      Log3($name, 5, "PortScan for ".$name." causes an error: \n".$errors." in: \n".$rcCmd."\n");
    }
    # zum Abschluss wird die "RUNNING_PID des helpers des devices gelöscht
    delete($hash->{helper}{PORTSCANRUNNING_PID});
    # Aufruf der Sub-Routine zum setzten des Timers für die nächste Ausführung
    NmapClient_SetNextTimer($hash,"PortScan");
    # Abschluss der Sub-Routine ohne Rückgabewert
    Log3 $hash, 3, $hash->{NAME}." Success for PortScan job!";

    return undef;
}
#######################################################################################
#######################################################################################
sub NmapClient_PortScanAbort($)
{
    my ($hash) = @_;
    delete($hash->{helper}{PORTSCANRUNNING_PID});
    Log3 $hash->{NAME}, 3, "BlockingCall PortScan für ".$hash->{NAME}." wurde abgebrochen";
    NmapClient_SetNextTimer($hash,"PortScan");
}
#######################################################################################


#######################################################################################
sub NmapClient_StartPing($)
{
    my ($hash) = @_;
    return undef if (IsDisabled($hash->{NAME}));
    my $name = $hash->{NAME};
    return "Ping = off!" if (AttrVal($name,"Ping","off") eq "off");
    my $ip = ReadingsVal($name,"IP",undef);
    if (!defined(ReadingsVal($name,"IP",undef))) {
        if (!$ip =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {
            Log3 $name, 2, "$name: IP: $ip nicht gültig!" if( $@ );
            return "IP nicht gültig!";
        }
    }

    my $arg = $name."|".$ip;
    my $blockingFn = "NmapClient_Ping";
    my $finishFn = "NmapClient_PingDone";
    my $abortFn = "NmapClient_PingAbort";
    if (!(exists($hash->{helper}{PINGRUNNING_PID}))) {
        $hash->{helper}{PINGRUNNING_PID} = BlockingCall($blockingFn,$arg,$finishFn,20,$abortFn,$hash);
        Log3 $hash, 5, "$hash->{NAME} Ping Auftrag wird mit PID: ".$hash->{helper}{PINGRUNNING_PID}{pid}." ausgeführt!";
    }
    else {
        Log3 $hash, 5, "$hash->{NAME} Blocking Call Ping läuft, es wurde kein neuer gestartet!";
        NmapClient_SetNextTimer($hash,"Ping");
    }
}
#######################################################################################
#######################################################################################
sub NmapClient_Ping($)
{
    my ($string) = @_;
    my ($name, $ip) = split("\\|", $string);
    my $hash = $defs{$name};
    my $result = "";
    my $rcCmd = "";
    my $pingBefehl = "ping ".$ip." -c 5 -q &";
    $result = `$pingBefehl`;
    my $regex = qr/ping statistics[\w\W]*\n(?P<transmitted>.*)\spackets\stransmitted,\s(?P<received>.*)\sreceived,\s(?P<quote>.*)\spacket\sloss,\stime\s(?P<time>.*)ms\srtt[\w\W]*=\s(?P<min>.*)\/(?P<avg>.*)\/(?P<max>.*)\/(?P<mdev>.*)\sms/p;
    if ( $result =~ /$regex/g ) {
      $rcCmd = ""
        ."setreading ".$name." PING_transmitted ".$+{transmitted}.";"
        ."setreading ".$name." PING_received ".$+{received}.";"
        ."setreading ".$name." PING_quote ".$+{quote}.";"
        ."setreading ".$name." PING_time ".$+{time}.";"
        ."setreading ".$name." PING_min ".$+{min}.";"
        ."setreading ".$name." PING_avg ".$+{avg}.";"
        ."setreading ".$name." PING_max ".$+{max}.";"
        ."setreading ".$name." PING_mdev ".$+{mdev}.";"
    }
    return $name."|".$rcCmd;
}
#######################################################################################
#######################################################################################
sub NmapClient_PingDone($)
{
    my ($string) = @_;
    my ($name, $rcCmd) = split("\\|", $string);
    my $hash = $defs{$name};
    my $errors = AnalyzeCommandChain ($hash, $rcCmd);
    if (!defined($errors)) {
      Log3($name, 5,"Success for PortScan: $rcCmd !");
    }
    else {
      Log3($name, 5, "PortScan for ".$name." causes an error: \n".$errors." in: \n".$rcCmd."\n");
    }
    # zum Abschluss wird die "RUNNING_PID des helpers des devices gelöscht
    delete($hash->{helper}{PINGRUNNING_PID});
    # Aufruf der Sub-Routine zum setzten des Timers für die nächste Ausführung
    NmapClient_SetNextTimer($hash,"Ping");
    # Abschluss der Sub-Routine ohne Rückgabewert
}
#######################################################################################
#######################################################################################
sub NmapClient_PingAbort($)
{
    my ($hash) = @_;
    delete($hash->{helper}{PINGRUNNING_PID});
    Log3 $hash->{NAME}, 3, "BlockingCall Ping für ".$hash->{NAME}." wurde abgebrochen";
    NmapClient_SetNextTimer($hash,"Ping");
}
#######################################################################################

#######################################################################################
sub NmapClient_Basics($)
{
    my ($hash) = @_;
    my $name = $hash->{NAME};
    my $nmapDeviceName = AttrVal($name,"NmapDeviceName","nmap");
    my $ip = ReadingsVal($name,"IP",undef);
    readingsBeginUpdate($hash);
      readingsBulkUpdateIfChanged($hash, "ALIAS", ReadingsVal($nmapDeviceName,$ip."_alias",undef), 1);
      readingsBulkUpdateIfChanged($hash, "HOSTNAME", ReadingsVal($nmapDeviceName,$ip."_hostname",undef), 1);
      readingsBulkUpdateIfChanged($hash, "LASTSEEN", ReadingsVal($nmapDeviceName,$ip."_lastSeen",undef), 1);
      readingsBulkUpdateIfChanged($hash, "MAC", ReadingsVal($nmapDeviceName,$ip."_macAddress",undef), 1);
      readingsBulkUpdateIfChanged($hash, "VENDOR", ReadingsVal($nmapDeviceName,$ip."_macVendor",undef), 1);
      readingsBulkUpdateIfChanged($hash, "UPTIME", ReadingsVal($nmapDeviceName,$ip."_uptime",undef), 1);
      readingsBulkUpdateIfChanged($hash, "UPTIMETEXT", ReadingsVal($nmapDeviceName,$ip."_uptimeText",undef), 1);
      readingsBulkUpdateIfChanged($hash, "state", ReadingsVal($nmapDeviceName,$ip."_state",undef), 1);
    readingsEndUpdate($hash, 0);
}
#######################################################################################


# NmapClient
# Kennzeichen für das Ende des fhem - Moduls
1;

=pod
=begin html
<a name="NmapClient"></a>
No english description, please look al german
=end html
=begin html_DE
  <a name="NmapClient"></a>
  <h3>NmapClient</h3>
  <ul>
  <p>Dieses helper-Modul erzeugt aus den im Nmap-Modul mit dem Programm nmap</p>
  <p>gefundenen Netzwerkgeräten einzelen Geräte mit erweiterten Funktionen</p>
  <a name="NmapClient_define"></a>
  <p><b>Define</b></p>
  <ul>
  <p>Im "Normalfall" werden die Geräte durch ein notify automatisch angelegt</p>
  <p><code>defmod nmapClientAddNew notify nmap:new.host:..+ {\
my $newDeviceName = "";;\
my $ip = "";;\
my $hostname = "";;\
my $regex = qr/host:\s(?P<hostname>.*)\s\((?P<ip>.*)\)\Z/p;;\
\
if ( $EVENT =~ /$regex/g ) \
{\
$hostname = $+{hostname};;\
$ip = $+{ip};;\
}\
$regex = qr/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/p;;\
if ( $ip =~ /$regex/ )  \
{\
$regex = qr/\./p;;\
my ($A,$B,$C,$D) = split(/\./, $ip);;\
$newDeviceName = "nc_".substr("000".$A, -3, 3)."_".substr("000".$B, -3, 3)."_".substr("000".$C, -3, 3)."_".substr("000".$D, -3, 3);;\
}\
else\
{\
$newDeviceName = "nc_".$hostname;;\
return "No valid IP!";;\
}\
fhem("defmod ".$newDeviceName." NmapClient ".$newDeviceName);;\
fhem("setreading ".$newDeviceName." IP ".$ip);;\
fhem("attr ".$newDeviceName." NmapDeviceName ".$NAME);;\
if ($ip ne $hostname) \
{\
fhem("attr ".$newDeviceName." alias ".$hostname);;\
} \
}
attr nmapClientAddNew room nmap</code>
  <p><code>define &lt;name&gt; NmapClient &lt;"nc_".ID = MAC-Adress/IP-Adresse&gt</code></p>
  <p>definiert das NmapClient device.<br/>
  &lt;nc_MAC-Adresse/IP-Adressse&gt; sollte als Indentifikation eingegeben werden</p>
   </ul>
  <a name="NmapClient_readings"></a>
  <p><b>Readings</b></p>
  <ul>
  <li>
  <b>state</b><br/>
  [initialized|present|absent]: Zeigt den aktuellen Status.
  </li>
  <li>
  <b>ALIAS | HOSTNAME | IP | LASTSEEN | UPTIME | UPTIMETEXT | MAC | VENDOR </b><br/>
  Zeigen die Daten aus dem anlegendem Gerät auf Basis des Nmap - Moduls
  </li>
  <li>
  <b>PING_<Name></b><br/>
  Zeigen die Daten aus dem mit <code>set <device> Ping on</code> ausgeführten Ping-Befehls.
  </li>
  <li>
  <b>PORT<00000></b><br/>
  Zeigen die offenen Ports aus dem mit <code>set <device> PortScan on</code> ausgeführten nmap-Befehls.
  </li>
  <li>
  <b>PortScan_<Name></b><br/>
  Zeigen die Daten aus dem mit <code>set <device> PortScan on</code> ausgeführten Ping-Befehls.
  </li>
  </ul>
  <a name="NmapClient_attr"></a>
  <p><b>Attributes</b></p>
  <ul>
  <li>
  <b>PORTScanInterval</b><br/>
  Default: 60*60*24. Time after the connection is re-checked.
  </li>
  <li>
  <b>... be continued</b><br/>
  ... .
  </li>
  </ul>
  </ul>
  =end html_DE
=cut

2. Schritt: FHEM über die FHEM-Befehlszeile neu starten:
shutdown restart
3.Schritt: Test mit der manuellen Anlage eines devices auf Basis des NmapClient - Moduls. (ggf. Fehler aus der aktuellen Fhem - LogDatei bereinigen)
define nc_123_123_123_123 NmapClient 123_123_123_123
4. Schritt: Alle Test NmapClient - Devices und alte dummy - Devices löschen z.B. mit den Befehlen in der FHEM Befehlszeile:
delete nc_123_123_123_123
delete 192_168_.*

5. Schritt: Ebenfalls in der FHEM Befehlszeile die "OldReadings" und "Readings" löschen (bitte "Netzwerk" ggf. durch den korrekten Nmap-Device-Namen ersetzen:
set Netzwerk deleteOldReadings 1
set Netzwerk clear Readings

6. Schritt: Nur, wenn die Anlage des Test-Devices funktioniert hat! Nachstehendes notify in FHEM anlegen (raw Definition) und in der 1. Zeile hinter "... notify " den Device Namen "Netzwerk" durch den individuell vergebenen Namen für das Nmap device ersetzen: 
defmod nmapClientAddNew notify Netzwerk:new.host:..+ {\
my $newDeviceName = "";;\
my $ip = "";;\
my $hostname = "";;\
my $regex = qr/host:\s(?P<hostname>.*)\s\((?P<ip>.*)\)\Z/p;;\
\
if ( $EVENT =~ /$regex/g ) \
{\
$hostname = $+{hostname};;\
$ip = $+{ip};;\
}\
$regex = qr/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/p;;\
if ( $ip =~ /$regex/ )  \
{\
$regex = qr/\./p;;\
my ($A,$B,$C,$D) = split(/\./, $ip);;\
$newDeviceName = "nc_".substr("000".$A, -3, 3)."_".substr("000".$B, -3, 3)."_".substr("000".$C, -3, 3)."_".substr("000".$D, -3, 3);;\
}\
else\
{\
$newDeviceName = "nc_".$hostname;;\
return "No valid IP!";;\
}\
fhem("defmod ".$newDeviceName." NmapClient ".$newDeviceName);;\
fhem("setreading ".$newDeviceName." IP ".$ip);;\
fhem("attr ".$newDeviceName." NmapDeviceName ".$NAME);;\
if ($ip ne $hostname) \
{\
fhem("attr ".$newDeviceName." alias ".$hostname);;\
} \
}
attr nmapClientAddNew room nmap

7. Schritt: Warten, bis das Nmap Device turnusmäßig aktualisiert wird, oder über die FHEM - Befehlszeile den "StatusRequest" manuell erzwingen:
set Netzwerk statusRequest

Nachdem Abschluss des Nmap statusRequest sollten im Raum nmap in der Gruppe NmapClients alle derzeit erkennbaren Netzwerkgeräte angelegt sein.

Sie haben zunächst nur 3 rudimentäre Funktionen:

1. BasicData: Daten aus dem Nmap Device abfragen (erfolgt auch automatisch, wenn das Ereignis "Nmap .... done" auftritt)
2. PortScan: ausführen des Befehls nmap <ip> und einlesen des Outputs in Readings (dauert mit unter mehrere Minuten!)
3. Ping: ausführen des Befehls ping <ip> und einlesen des Outputs in Readings

Dazu kann die Vorgabe 1 x täglich als Interval sowohl für den PortScan als auch für Ping geändert werden.

Diese Intervalle werden nur aktiv, wenn die Funktion PortScan oder Ping auf "on" gesetzt sind.

Wird Ping oder PorScan erstmalig auf on gesetzt, wird der entsprechende Befehl zunächst aus geführt und anschliessend ein Timer auf Basis des entsprechenden Intervalls für die nächste Ausführung gesetzt.

Ich hoffe ich konnte in ersten Ansätzen zeigen, was ich mir vorstellte und du erkennst die Möglichkeiten.
Ich bin gespannt, was ein Perl Programmierer daraus macht und welche weiteren Funktionen möglich sind.

Gernot   

P.S.bzw. Off-Topic: Ich meinte nicht, dass man den Zustand eines Servers von aussen nicht sehen sollte, sondern, dass das was überwacht wird, der Server weitgehend selbst liefert (z.B. ausgewählte Auszüge aus log Dateien bzw. der Zustand ausgewählter Dienste oder ausgewählter Hardware - Werte). Also weder telnet noch sonst eine Schnittstelle für die Ausführung von Befehlen auf dem Server öffnen.