telnet read Probleme

  • Hallo Leute.
    ich habe folgendes Problem:

    -Ich lese über einen RFID-Reader einen Tag (CHECK)

    -Dieser gibt die Nummer in Hexadezimal über RS232 an einen telnet-server (CHECK)

    -Via Telnet kann ich mich nun von einem beliebigen gerät einloggen und sobald ein Tag gelesen wird, wird mir dieser im Terminal ausgegeben (CHECK)

    Dies soll ab jetzt aber nicht mehr via Terminal passieren sonder via Python damit ich mit den Daten im Programm Arbeiten kann.
    Momentan sieht mein Code wie folgt aus:

    Code
    import getpass
    import sys
    import telnetlib
    
    
    
    
    tn = telnetlib.Telnet('IP ARDESSE','PORT')
    while 1:    
       print (((tn.read_eager().decode().strip('b''7A00'))))

    Meine erste Frage:
    Wie sorge ich dafür dass der Print Befehl nur ausgeführt wird wenn auch Daten rein kommen?
    Also welche Bedingung muss ich setzen?

    Zweite Frage:
    in einem früheren Programm (ohne Telnetserver - direkte serielle Verbindung) habe ich die HEX-Werte einfach umrechnen können ( int(),16 )
    dies Funktioniert momentan in der Telnetvariante nicht.
    Wo liegt mein Fehler?

    Alter Code mid Seriell-Direkt:

    Code
    import serial
    ser = serial.Serial('/dev/tty.usbserial-FTG4SM2J',9600)
    while 1:
       print (int((ser.readline().decode().strip('7A00''\r\n')),16))

    Umrechnung im Telnetcode:

    Code
    import getpass
    import sys
    import telnetlib
    
    
    
    
    tn = telnetlib.Telnet('IP ADRESSE','PORT')
    while 1:    
       print (int((tn.read_eager().decode().strip('b''7A00')),16))

    Fehler:
    ValueError: invalid literal for int() with base 16:

    Danke im Voraus.

    Einmal editiert, zuletzt von d3v1l (12. Oktober 2015 um 20:21)

  • Hallo,

    ungetestet (sollte lt. Doku aber funktionieren):

    `read_eager` liest permanent von der Verbindung und gibt wenn nichts da ist einen leeren String zurück. Darauf musst du testen.

    Zitat

    n einem früheren Programm (ohne Telnetserver - direkte serielle Verbindung) habe ich die HEX-Werte einfach umrechnen können ( int(),16 )
    dies Funktioniert momentan in der Telnetvariante nicht.
    Wo liegt mein Fehler?


    Prüf' doch mal, von welchem Typ deine Daten sind. Das kannst du machen, indem du ein passender Stelle ein `print type(data)` einbaust.

    Gruß, noisefloor

  • Leider wird immer noch ohne Unterbrechung ausgegeben und zwar b''
    :(
    irgendwie hört python auch nicht auf die Bedingung. Ich weiß ehrlich gesagt nicht woran das liegt.

    • Offizieller Beitrag

    wie sieht denn der output von

    aus?

  • Okay,
    Ich revidiere meine Aussage von grade eben. es scheint so als habe ich vorgestern nicht richtig übertragen.
    mein momentaner Code:

    der RFID-tag den ich teste ist: 6403651 also in HEX 61B643

    meine Ausgabe sieht nun besser aus. allerdings teilt die Ausgabe willkürlich meine Datensätze und gibt noch leere Prints aus:

    >>> ================================ RESTART ================================
    >>>
    61B643


    61B643

    6
    1B643

    61B6
    43

    61B
    643

    61B643


    6
    1B643

    6
    1B643


    61B643

    61
    B643

    61B643


    61
    B643


    61B643

    61
    B643


    61B643

    61B643

    Einmal editiert, zuletzt von d3v1l (15. Oktober 2015 um 14:40)

  • Hallo,

    zum Teilen:

    `if data:` trifft zu, sobald Daten vorliegen - der Bedingung ist es ja egal, ob der kompletten Datensatz / zu übertragenden String vorliegt oder nur ein Teil davon. Das - vermute ich - ist hier das Problem. Wobei ich selber telnet noch nicht benutzt habe - keine Ahnung, wie schnelle oder langsam das ist.

    Gibt es irgendeine Zeichensequenz, die deine Übertragung einleitet? Wenn ja solltest du darauf lauschen und beim Eintreffen dann agieren. Außerdem kennt das telnet Modul ja noch andere `read-Methoden - vielleicht passt eine andere besser für deinen Anwendungsfall?

    Gruß, noisefloor


  • ich würde eher sowas wie ein readline() nehmen. Wo halt ein festes terminierungszeichen kommt.

    worauf soll sich das Readline denn beziehen?

    in Python ist das kein Telnet Befehl.
    data = tn.readline()

    AttributeError: 'Telnet' object has no attribute 'readline'

  • Hallo d3v1,

    ein ähnliches Problem hatte ich letztens auch. Die Lösung habe ich hier beschrieben.

    Vielleicht kannst Du Dir dort eine Anregung holen. Das Stichwort heißt "Zeichenweises Auslesen asynchroner Dateneingänge mit Timeout"

    Die Ursache des Problems besteht darin, dass unregelmäßig Daten eintrudeln - der Lesebefehl liest soviel Daten ein, wie zum Zeitpunkt des Einlesens auf der Pipeline stehen - unabhängig, dass Daten vollständig übertragen wurden. Bei 9600 Baud beispielsweise bracuht die Übertragungung eines Zeichens rund eine Millisekunde - das Auslesen der Zeichen, die sich gerade im Puffer befinden, je nach Prozessortaktung / Qualität des Compilats im Bereich 10 bis 50 µs. Wenn Du die Daten zeichenweise einliest, einen Moment wartest, nach neuen Daten schaust, diese auch einliest und dies solange wiederholst, bis auch nach dem Warten erstmals keine neuen Daten anliegen, genau dann ist die Zeile vollständig.

    Dieser Algorithmus funktioniert unabhängig von Neue-Zeile- / Zeilenvorschub- / Wagenrücklauf-Zeichen, die oftmals auch gar nicht gesendet werden.

    Die in meinem Programmbeispiel enthaltenen Vorgaben für Wartezeiten [Parameter [font="Courier New"]timeout[/font] in der Prozedur [font="Courier New"]polling()[/font]] musst Du ggf. an die Baudrate des Senders anpassen. Dies kannst Du ausrechnen oder durch Ausprobieren lösen.


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    2 Mal editiert, zuletzt von Andreas (14. Oktober 2017 um 17:16)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!