[gelöst]Einstellungen um mit net::telnet Modul die Ausgabe des fhem commands ...

Begonnen von supernova1963, 05 Februar 2019, 07:05:37

Vorheriges Thema - Nächstes Thema

supernova1963

Nur so für mein Verständnis, benötige ich Unterstützung bei der Nutzung von dem perl Modul net::telnet.

Vorbereitungen, Tests:
1. ferner fhem Server ist im Terminal per telnet über den Port 7072 mit dem globalpassword erreichbar
Nachdem die Verbindung hergestellt ist, werden fhem commands korrekt ausgeführt. Das Ergebnis des fhem commands: list TYPE=DUMMY wird auf der console korrekt ausgegeben.
2. Auch aus dem perl Script kann ich die telnet Verbindung herstellen. Ein $telnet->print('define test dummy'); funktioniert ebenfalls

Aber:

Der perl Script Befehl @a = $telnet->cmd('list test') bricht mit Fehler im telnet Modul ab und der $b = $telent->print('List test') gibt ja nur 1 zurück.

Frage:
Was muss ich tun, um an die Ausgabe des fhem commands zu kommen?

Vielen Dank,

Gernot



CoolTux

Ich habe auch noch nicht viel mit telnet gemacht. Für mich würde es aber Sinn ergeben beim zweiten auch ein

$telnet->print('

Zu machen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

justme1968

hast du dir mal fhem2fhem und rfhem angeschaut? damit sollte das was du möchtest ohne zusätzliche perl module gehen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

CoolTux

Zitat von: justme1968 am 05 Februar 2019, 08:44:10
hast du dir mal fhem2fhem und rfhem angeschaut? damit sollte das was du möchtest ohne zusätzliche perl module gehen.

Ich denke mal ihm geht darum zu lernen und zu verstehen. Aber Du hast Recht, da kann man reinschauen wie es in der Tat geht. Gerade bei rfhem.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

justme1968

ok. dann wäre für das lernen und verstehen wichtig drauf hin zu weisen das ganze auf jeden fall ohne potentiell blockierendes perl telnet modul zu machen sondern selber
per socket und noch blockierend.

perl telnet ist die schlechteste variante von allen.
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

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

rudolfkoenig

Ich gehe davon aus, dass hier nicht um ein Modul, sondern um eine standalone Loesung handelt, was blockieren kann.

Da das FHEM-telnet Modul das telnet Protokoll nur marginal implementiert, empfehle ich eher aus fhem.pl den Abschnitt mit "# Client code" anzuschauen, kopieren und anzupassen. Es sei denn, man will net::telnet kennenlernen, dazu kann ich nichts sagen.

supernova1963

Vielen Dank CoolTux, JustMe1968 und rudolfkoenig,

ok, habe verstanden, dass das perl Modul net::telnet der falsche bzw. nicht geeignete Weg ist und mir fhem2fhem und rfhem angesehen.

rfhem und fhem.pl:

Verwendet scheinbar das perl Modul IO::Socket::INET (versuche ich mal)
...
my $socket = IO::Socket::INET->new('PeerAddr' => $HOSTNAME,'PeerPort' => $HOSTPORT,'Proto' => 'tcp') ;
    my $msg = $command."\n" ;
    #Log3 $name, 3, "$msg";
my @values =  RFHEM_GetNet($hash,$HOSTNAME);
if ( $values[1] eq "present") {
Log3 $name, 3, "Host present, executing command...";
syswrite($socket, $HOSTPW . "\n")if($hash->{PASSWORD});
print $socket $msg;
Log3 $name, 3, "Command executed."; }
else { Log3 $name, 3, "Error: host not present!"; }
...


Die Zeile, wo eine Ausgabe eines auf dem entfernten fhem System ausgeführten Befehls ausgewertet wird, habe ich nicht gefunden.

fhem2fhem:

adhoc finde ich nur die sub "FHEM2FHEM_SimpleRead( ..." die in etwa in die Richtung "Rückmeldung auf fhem command" gehen könnte. Da finde ich aber den zugehörigen fhem command nicht.

Da es sich um einen System dienst außerhalb von fhem handelt, wäre "blockieren des Dienstes" nicht ganz so tragisch, da er eh nur Werte liefern soll, wenn verfügbar. Damit der Dienst nicht hängt, fand ich die Möglichkeit bei net::telnet die "Timeout" und "Errmode" Parameter sehr hilfreich.

Auf "localhost" funktioniert das abfangen der Ausgabe eines fhem commands mit dem Systembefehl:
$a=`perl /opt/fhem/fhem.pl 7072 "list test" &`
Auf einem entfernten System (mit Aufruf des System telnet) müßte ich erst "fhem>" mit "exit" verlassen. Ob ich dann den Befehl wie auf localhost auf der Systemebene aufrufen kann habe ich noch nicht getestet

Nach wie vor bin dankbar für jeden Hinweis,

Gernot

betateilchen

Warum gehst Du nicht einfach den umgekehrten Weg? Lass doch FHEM auf der entfernten Instanz die Datei ins Dateisystem schreiben und hole die Datei von dort ab, mit welchen Mitteln auch immer Du das magst - ftp, scp oder wie auch immer.

define at_test at +*00:01 {FileWrite({FileName => '/tmp/myFile', ForceType=> "file"}, fhem("list test"))};;
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Wernieman

Die Frage ist, ob Du dann wirklich perl brauchst. Anstatt mit perl /opt/fhem/fhem.pl 7072 "list test"
geht es auch direkt mit der Commandozeile:
echo -en "list test\nquit\n" | nc <fhem-server> 7072
- Bitte um Input für Output
- When there is a Shell, there is a Way
- Wann war Dein letztes Backup?

Wie man Fragen stellt: https://tty1.net/smart-questions_de.html

supernova1963

Danke betateilchen,

das hatte ich alternativ auch noch auf dem Schirm, habe ich aber als Umgehung aufgrund fehlenden Wissens gesehen.

Danke wernieman,

funktioniert mit (************ = globalpassword):
echo -en "************\nlist test\nquit\n" | nc 192.168.1.103 7072

Ich versuche aber noch  "IO::socket::INET->..." Tip von justme1968 und rudolfkoenig.

Danke, macht echt Freude mit dieser Unterstützung im Forum,

Gernot

supernova1963

Zitat von: supernova1963 am 05 Februar 2019, 17:13:24
Ich versuche aber noch  "IO::socket::INET->..." Tip von justme1968 und rudolfkoenig.

Hab's probiert, leider stehe ich auch hier vor dem Problem, wie komme ich an die Ausgabe des fhem commands?


my $client = IO::Socket::INET->new(PeerAddr => $host.':'.$port);
die "Can't connect to $host:$port\n" if (!$client);
syswrite($client,$globalpw."\n");
syswrite($client,"list test"."\n");

Der returnCode von syswrite ist 9 = Anzahl der übertragenen Zeichen.
Zum testen der Verbindung habe ich "syswrite($client,"define test2 dummy"."\n") verwendet und, es hat funktioniert. Die Verbindung steht genau so, wie bei der Verwendung des net::telnet Moduls. Der print bzw. syswrite Befehl kommt an. Hier gab's die Funktion "cmd", die die Ausgabe zurück geben soll. Die finde ich jedoch bei IO::Socket::INET nicht.

Da komme ich zur Zeit nicht weiter und bin gespannt auf die Lösung.

betateilchen

Entschuldige die blöde Frage (ich habe mich mit der Thematik noch nie praktisch beschäftigt):

Müsstest Du nicht mit sysread() die Antwort abholen, wenn Du nach syswrite() mit einer verwertbaren Rückmeldung rechnest?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

supernova1963

Hallo betateilchen,

Meinst du das so:

sysread($client,syswrite($client,"list test"."\n"));


Danke,

Gernot

CoolTux

Du musst dafur sorgen daß innerhalb einer Schleife alle x Sekunden ein sysread schaut ob Daten Anliegen und diese dann abholen.

Zum Spielen machst Du es ohne Schleife.

Also zuerst ein write schreiben und danach ein read.


my $leng;
syswrite($client,"list test"."\r\n");
sysread($client);
$leng = sysread($client,$buf,1024);

In $buf stehen Deine Daten in $leng die Länge der erhaltenen Daten.

Denke mal so sollte was kommen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Zitat von: supernova1963 am 05 Februar 2019, 20:58:32
Hallo betateilchen,

Meinst du das so:

ich meine, Du solltest mal ein paar perl-Dokumentationen zum Thema lesen. Mit FHEM selbst hat Dein Vorhaben grundsätzlich nicht so sehr viel zu tun.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

supernova1963

Vielen Dank cooltux,

probiere ich sobald wie möglich aus.

Gernot

P.S.:
Zitat von: betateilchen am 05 Februar 2019, 21:36:41
ich meine, Du solltest mal ein paar perl-Dokumentationen zum Thema lesen. Mit FHEM selbst hat Dein Vorhaben grundsätzlich nicht so sehr viel zu tun.
Sorry für mein Unvermögen, betateilchen. Du hast natürlich recht, erst lesen, dann Fragen.
Zum Thema net::telnet habe ich viel gelesen und ausprobiert.
Soviel habe ich herausgefunden: $telent->cmd( Funktion funktioniert ja auch ohne die Portweiterleitung von fhem und $telnet->print( funktioniert problemlos auch mit fhem.
Was hat das mit fhem zu tun:
Ich versuche gerade laienhaft ein fhem Modul zu erstellen, das Parameter für einen System Dienst zur Verfügung stellt. Der Dienst soll entsprechend der Parameterisierung Daten an fhem liefern.
Warum einen Dienst:
Da nicht vorhersehbar, wann Daten geliefert werden, muss es dauerhaft laufen. Eine blocking Funktion mit 24 Std. Timeout (oder häufiger) und umittelbarem Neusstart ggf. auf fernem Rechner gefiel mir nicht ganz so gut.
Warum ich bis dato keine cfg oder yaml verwende, die ja auch sehr leicht aus fhem heraus eingestellt werden könnte:
Hat mich einfach nur interessiert, ob es möglich ist die Redundanz zu vermeiden.

Dein Lösungsvorschlag ist für mich genial und zeigt mir die Unterschied zu anderen Programmiersprachen.

Vielen Dank nocheinmal dafür!

CoolTux

Zitat von: supernova1963 am 06 Februar 2019, 07:03:18
Vielen Dank cooltux,

probiere ich sobald wie möglich aus.

Gernot

P.S.:Sorry für mein Unvermögen, betateilchen. Du hast natürlich recht, erst lesen, dann Fragen.
Zum Thema net::telnet habe ich viel gelesen und ausprobiert.
Soviel habe ich herausgefunden: $telent->cmd( Funktion funktioniert ja auch ohne die Portweiterleitung von fhem und $telnet->print( funktioniert problemlos auch mit fhem.
Was hat das mit fhem zu tun:
Ich versuche gerade laienhaft ein fhem Modul zu erstellen, das Parameter für einen System Dienst zur Verfügung stellt. Der Dienst soll entsprechend der Parameterisierung Daten an fhem liefern.
Warum einen Dienst:
Da nicht vorhersehbar, wann Daten geliefert werden, muss es dauerhaft laufen. Eine blocking Funktion mit 24 Std. Timeout (oder häufiger) und umittelbarem Neusstart ggf. auf fernem Rechner gefiel mir nicht ganz so gut.
Warum ich bis dato keine cfg oder yaml verwende, die ja auch sehr leicht aus fhem heraus eingestellt werden könnte:
Hat mich einfach nur interessiert, ob es möglich ist die Redundanz zu vermeiden.

Dein Lösungsvorschlag ist für mich genial und zeigt mir die Unterschied zu anderen Programmiersprachen.

Vielen Dank nocheinmal dafür!

Ich muss da noch mal Fragen, sorry. Willst Du ein FHEM Modul entwickeln oder willst Du ein kleines Perl Skript schreiben was Daten sammelt und dann an FHEM sendet? Ist wichtig zu wissen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

supernova1963

Hallo CoolTux,

an-für-sich, beides. Meine Frage zum Thema telnet bezieht sich aber auf ein "kleines perl script", dass als System Dienst gestartet wird und geeignet aufbereitete Daten (Vorgaben im fhem Modul einstellbar) nach fhem schubsen soll.

Gernot


CoolTux

Also hier hast Du erstmal ein funktionierenden Prototype


#!/usr/bin/perl
use warnings;
use strict;
use POSIX;
use Net::Telnet;



my $host = 'localhost';
my $port = 7072;
my $timeout = 1;

my $socket = new Net::Telnet ( Host=>$host,
        Port => $port,
        Timeout=>$timeout,
        Errmode=>'return')
        or die 'Geht nicht';



my $string = 'list TYPE=dummy';
$string .= "\r\n";


syswrite($socket,$string);

my $buf;
my $leng;
$leng = sysread($socket,$buf,1024);

$socket->close;


print 'Länge ist: ' . $leng . ' und Daten sind: ' . $buf . "\n";


Er macht genau das was er soll. Er schreibt einen list Befehl in die telnet session und liest die Antwort dann aus.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

betateilchen

Zitat von: supernova1963 am 06 Februar 2019, 07:03:18
Warum einen Dienst:
Da nicht vorhersehbar, wann Daten geliefert werden, muss es dauerhaft laufen.

nur mal so zur Info: Die allermeisten Module in FHEM wissen auch nicht im voraus, WANN Daten zur Verarbeitung geliefert werden.
Genau dafür gibt es bewährte Mechanismen und Vorgehensweisen innerhalb von FHEM. Dazu brauchst Du das Rad nicht neu erfinden.

-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

CoolTux

Zitat von: supernova1963 am 06 Februar 2019, 08:30:39
Hallo CoolTux,

an-für-sich, beides. Meine Frage zum Thema telnet bezieht sich aber auf ein "kleines perl script", dass als System Dienst gestartet wird und geeignet aufbereitete Daten (Vorgaben im fhem Modul einstellbar) nach fhem schubsen soll.

Gernot

In diesem Fall solltest du Dir mal lepresenced anschauen. Das ist genau so ein Perl Skript für die Konsole und läuft als Dämon.
Da haste Dir aber was vorgenommen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

supernova1963

Hallo CoolTux,

danke für den Code, das wären sonst unzählige debug Durchläufe geworden um herauszufinden, dass ein "\r\n" angehangen werden soll. Ich hatte die net::telnet Beschreibung so verstanden, dass diese Option als Standard voreingestellt ist.
Es läuft, und, wenn ich es richtig interpretiere müsste das Auslesen der Rückgabe des fhem commands bei mit IO::Socket::INET ja ähnlich funktionieren

Zitat von: CoolTux am 06 Februar 2019, 09:29:38
In diesem Fall solltest du Dir mal lepresenced anschauen. Das ist genau so ein Perl Skript für die Konsole und läuft als Dämon.
Da haste Dir aber was vorgenommen.
Wenn ich mir lepresenced so anschaue, werde ich diese Qualität nie erreichen. Vielleicht wird es ja doch etwas schmaler, da ich ein bestehendes Programm die meisten Aufgaben der Überwachung liefert.
Konkret:
Ich hatte mir damals mal eine fingBox über Indiegogo zur Netzwerküberwachung zugelegt. Die rennt auch an-für-sich sehr gut. Aber sie "telefoniert halt permanent mit zuhause". Da die Jungs von fing eine neue offline Version von fingCLI zur Verfügung gestellt haben, will ich 'mal versuchen die mir wichtigen Funktionen ohne die Box hinzubekommen. Dafür muss ich die Discovery Funktion in ein perl script packen, da es nur text oder csv im log Modus auf die Console oder in eine Datei abwirft. Das schöne daran ist, dass es bei mir keine 5 Sekunden dauert, bis das fing discovery einen neuen Teilnehmer oder eine Statusveränderung eines bekannten Teilnehmers im Netz entdeckt. Zusätzlich erfolgt alle 60 Sekunden ein vollständiger Netzwerk Scan der als json ausgegeben wird. Nicht zuletzt sind die .config Dateien einstell-/erweiterbar.
Nach meiner Vorstellung soll ein fhem Modul die Parameter für den Discovery Dienst vorgeben und den Dienst stoppen und aktivieren.

Na, mal sehen wie weit ich komme. 


@betateilchen:
Zitat von: betateilchen am 06 Februar 2019, 09:15:35
Dazu brauchst Du das Rad nicht neu erfinden.
Will ich auch gar nicht, ich will nur lernen wie es geht ...
Vorweggenommen: Ja, ich weiss, dass es ein nmap Modul gibt  ;)

Noch einmal danke an alle,

Gernot

CoolTux

Dein fingCli scheint als Daemon laufen zu können. Eventuell arbeitet er mit Unixsocket dann kannst Du direkt über FHEM mittels DevIo arbeiten.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

supernova1963

Hallo CoolTux,

ich bin deiner Alternative einmal nach gegangen. Wenn ich es richtig verstanden habe, würden dann im Verzeichnis /proc/<PID>/fd *.sockets zu finden sein. Das ist bei fingCLI nicht der Fall. Oder gibt es andere Wege das ,,Vorhandensein" von entsprechenden Sockets zu prüfen?
Ich vermute, dass dies eher bei fingKIT verwendet wird. Der für mich wesentliche Unterschied ist, dass fingCLI ausschließlich lokal läuft und nicht Lizensierungspflichtig ist, fingKIT u.A. eine API zur fingBox wäre.
Mit letzterem habe ich mich noch nicht näher beschäftigt.

Danke,

Gernot

CoolTux

Selbst kenne ich keinen anderen Weg. Dann also doch Perlskript auf der Konsole.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net