Telnet - Prompt eines Geräts als String abfragen

Begonnen von gibacht, 15 Dezember 2013, 14:45:34

Vorheriges Thema - Nächstes Thema

gibacht

Hallo,

Ich möchte den Status meiner Squeezeboxen abfragen. Gibt es irgendeine Möglichkeit die Antwort auf den gesendeten Telnet-Befehl (z.B. "mixer muting ?") in einer Variablen zu speichern?

sub SB_switch (@) {
   my ($typ,$eno,$ename) = @_;
        my ($id1) = "00:04:20:2c:59:f5";
        my ($ip) = "192.168.178.2";
        my ($port) = "9090";
        use Net::Telnet;
   my $telnet = new Net::Telnet ( Timeout=>15, Errmode=>'die', Port=>$port);
        $telnet->open($ip);
        if ($typ =~ m"mute"i) { # off or OFF
      my @lines = $telnet->cmd("mixer muting ?");  # Das hier bringt leider einen timeout
                Log 3, @lines;
                }
   $telnet->print('exit');

Leider habe ich nirgends ein Information / Antwort finden können und wäre für einen Tipp sehr dankbar!

Viele Grüße Dirk






HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

gibacht

Zitat von: gibacht am 15 Dezember 2013, 14:45:34
Hallo,

Ich möchte den Status meiner Squeezeboxen abfragen. Gibt es irgendeine Möglichkeit die Antwort auf den gesendeten Telnet-Befehl (z.B. "mixer muting ?") in einer Variablen zu speichern?

sub SB_switch (@) {
   my ($typ,$eno,$ename) = @_;
        my ($id1) = "00:04:20:2c:59:f5";
        my ($ip) = "192.168.178.2";
        my ($port) = "9090";
        use Net::Telnet;
   my $telnet = new Net::Telnet ( Timeout=>15, Errmode=>'die', Port=>$port);
        $telnet->open($ip);
        if ($typ =~ m"mute"i) { # off or OFF
      my @lines = $telnet->cmd("mixer muting ?");  # Das hier bringt leider einen timeout
                Log 3, @lines;
                }
   $telnet->print('exit');

Leider habe ich nirgends ein Information / Antwort finden können und wäre für einen Tipp sehr dankbar!

Viele Grüße Dirk

Schade, dass ich noch keine Antwort erhalten habe. Woran liegt es?
Fehlen evtl. noch Details, oder geht das einfach nicht?
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

justme1968

#2
musst du dich auf der squeezebox wirklich nicht einloggen? oder könnte es sein das dein telnet darauf wartet weil der prompt nicht richtig gesetzt ist?

siehe Net::Telnet doku:
ZitatThe methods login() and cmd() use the prompt setting in the object to determine when a login or remote command is complete. Those methods will fail with a time-out if you don't set the prompt correctly.

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

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

gibacht

Hallo Andre,
danke für Deine Rückmeldung.

Das käm eigentlich nur in Frage, wenn SSH aktiviert wäre. Das ist aber nicht der Fall.
Die Befehle werden von der Squeezebox angenommen und umgesetzt. (Z.B. "mixer muting 0"). Mein einziges Problem ist, dass ich die Antwort auf die Statusabfrage (z.B. "mixer muting ?") nicht in nicht in Fhem reinbekomme. Diese würde ich dann gerne u.a. zur Aktualisierung der Symbole im Webfrontend nutzen.

Wenn ich per Telnet auf der Squeezebox eingeloggt bin und "mixer muting ?" eingebe, antwortet diese z.B. so:
"00:04:20:2c:59:f6 mixer muting 1". Diesen String möchte ich in eine Variable speichern, um diese dann weiter bearbeiten / nutzen zu können.

Viele Grüße Dirk
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

justme1968

wie schaut denn eine terminal session aus wenn du es von hand per telnet machst. gibt es wirklich keinen prompt am zeilenanfang?

ich glaube den braucht das Net::Telnet modul um zu erkennen wann die ausgabe des kommandos fertig ist.

wie gesagt: schau mal in die doku von Net::Telnet.

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

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

gibacht

nein ein Prompt ("#") kommt nicht. Und die Dokus habe ich schon alle durch.
Eigentlich müsste die S-Box beim Einloggen per Telent doch dann auch den Login abfragen.
Das tut sie aber nicht.
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

gibacht

Zitat von: gibacht am 16 Dezember 2013, 19:02:07
nein ein Prompt ("#") kommt nicht. Und die Dokus habe ich schon alle durch.
Eigentlich müsste die S-Box beim Einloggen per Telent doch dann auch den Login abfragen.
Das tut sie aber nicht.

Habe gerade noch einmal getestet und den Logeintrag kopiert:
SB_mute_Notify return value: command timed-out at ./FHEM/99_myUtils.pm
Hier steht auch kein Hinweis auf einen fehlenden Login, so wie ja in der Doku beschrieben ist.
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

justme1968

wenn es keinen prompt gibt ist das vermutlich genau das problem. Net::Telnet braucht einen prompt um zu erkennen wann die ausgabe beendet ist. versuch mal den prompt auf \n also newline zu setzen.

ansonsten ist Net::Telnet vielleicht der falsche weg und IO::Socket::INET besser geeignet.

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

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

gibacht

hmm, mit newline klapps auch nicht.
Du meinst ich sollte dann auf die xml/txt-Methode über http setzen.
Oje, und das für einen blutigen Anfänger..., über diesen Lösungsansatz bin ich auch schon gestolpert, habe ihn
aber dann wegen zu wenig Hintergrundwissen verworfen.



HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

justme1968

nein. das hatte ich nicht gemeint. sondern direkt ein socket auf den telnet port aufmachen. dein kommando mit syswrite und die antwort direkt mit sysread lesen. oder mit send und recv.

wenn du im fehlerfall nicht blockieren willst ist es sinnvoll vor dem read mit select zu warten bis daten da sind und erst dann zu lesen. wenn die daten nach x sekunden nicht da sind kannst du dann abbrechen.

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

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

gibacht

ok, ich lese mal weiter. Vielen Dank erst einmal. Vielleicht hat ja jemand mitgelesen und hat eine Lösung, so dass ich das Rad nicht neu erfinden muß.

HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

gibacht

So, nachdem mir Andre eine andere Vorgensweise vorgschlagen hat, habe ich stundenlang gesucht und folgendes getestet.
Leider funktioniert der Verbindungsaufbau mit dem Squeezeserver nicht. Meldung: "illegal seek". Ich würde mich freuen wenn jemand einen Tipp hätte.

use CGI qw(:standard);
use IO::Socket;
use IO::Socket::INET;
use MIME::Base64;
use Time::HiRes qw(usleep nanosleep);

sub radio($)
{
  my ($socket,$client_socket);
  my $response ="";

  $socket = new IO::Socket::INET (
      PeerHost => '192.168.178.2',
      PeerPort => '9090',
                Proto => 'tcp',
  ) or die "ERROR in Socket Creation : $!\n";

  $socket->send('mixer muting ?');
  usleep(30000);
  $socket->recv($response, 2);
  if($response !~  m/OK/)
    {
    Log 1, "Error from radio ! Response from Radio : $response" ;
    }

  $socket->close();
  return;
}
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

justme1968

schau dir mal das beispiel hier an: http://forum.fhem.de/index.php/topic,15928.msg116012.html#msg116012. vielleicht hilft dir das weiter. vor allem etwas weiter unten die version mit timout. du brauchst natürlich nicht eine readFn sondern kannst nach dem auf machen mit select auf die antwort warten und dann gleich zu machen.

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

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

gibacht

Danke für die Info, aber das Problem mit dem fehlerhaften connect löst der Thread auch nicht,
da der Verbindungsaufbau (per io::socket::inet) ist der gleiche ist.
HMLAN, TVserver Headless YAVDR mit LMS und FHEM, Rasperry PI Openelec als Clients.

erwin

#14
Hi Gibacht,

bei mir schaut ein vergleichbares stück code so aus:

  ....
  # create a connecting socket
  my $socket = new IO::Socket::INET (
    PeerHost => $serverhost,
    PeerPort => $serverport,
    Proto => 'tcp',
  );
  unless ($socket) {
    return "cannot connect to the server $!\n"; #  unless $socket;
  }
  my $size = $socket->send($devname);
  # notify server that request has been sent
  shutdown($socket, 1);

  # receive a response of up to 1024 characters from server
  my $response = "";
  $socket->recv($response, 1024);

  $socket->close();
  return "$response";
  ....


PS: es könnt aber auch sein, dass dein Gerät ein \n oder \r am Schluß braucht....
l.g. erwin
FHEM aktuell auf RaspberryPI Mdl 1-4
Maintainer: 00_KNXIO.pm 10_KNX.pm
User: CUNO2 (868 SLOWRF) - HMS100xx, FS20, FHT, 1-Wire  - 2401(iButton), 18x20, 2406, 2413 (AVR), 2450,..,MQTT2, KNX, SONOFF, mySENSORS,....
Hardware:  Busware ROT, Weinzierl IP731, 1-Wire GW,...