2015-05-12 11 views
7

Gibt es eine Möglichkeit, mit Twisted Python eine Verbindung zu einem RFC2217-Netzwerkanschluss herzustellen?Verwenden Sie serielle RFC2217 Netzwerkports mit Twisted Python?

Pyserial scheint es über die serial.serial_for_url("rfc2217://...")function zu unterstützen. Und sie zeigen an, dass twisted verwendet pyserial für die Verwaltung von seriellen Verbindungen, aber twisted.internet.serialport.SerialPort scheint einen Port-Namen oder eine Nummer zu erwarten, die darauf hindeutet, dass es nur an den serial.Serial Konstruktor übergeben wird.

Ich kann Socat verwenden, um ein PTY extern zu erstellen und den Dev-Namen an verdreht zu übergeben, was gut funktioniert, aber ich frage mich, ob ich diesen Schritt umgehen kann, indem ich die pyseriale Unterstützung direkt benutze.

socat PTY,link=/dev/myport TCP:192.168.1.222:9001 

bearbeitet: Die pyserial faq schlägt diese Änderung serielle Objekte zum Instanziieren:

try: 
    s = serial.serial_for_url(...) 
except AttributeError: 
    s = serial.Serial(...) 

nicht sicher, ob dies allerdings hilft ...

+0

Ich habe keine Antwort für Sie Ich habe Angst; und ich vermute, die Antwort wird sein * Nein; noch nicht*; und du würdest wahrscheinlich ein Problem einreichen wollen :) - Wie auch immer, ich habe gedacht, dass wir auch eine solche Funktion zu [circuits.io.Serial] hinzufügen sollten (https://github.com/circuits/circuits/ blob/master/circuits/io/serial.py) –

+0

Danke James, ja, ich werde mich um eine Frage/Feature Anfrage kümmern, wenn es keine gute Antwort gibt. –

+0

WRT zu Ihrer Bearbeitung; Ich denke, du würdest "if": // "in'' machen wollen. d. h. Test für eine URI oder etwas. –

Antwort

2

Ich bin zu dem Schluss gekommen, dass pyserial der Verwendung von RFC2217-Unterstützung mit Twisted Python ist nicht trivial. Pyserial Implementierung von RFC2217 neben being currently experimental verwendet Threads die Socket-Verbindung zu verwalten, die sie angeben, als ein Problem für ausgewählte basierte Anwendungen ist durch:

Die aktuelle Implementierung startet einen Faden, der von der (internen) Buchse Lesen hält. Der Thread wird automatisch vom rfc2217.Serial-Port-Objekt bei open()/close() verwaltet. Es kann jedoch ein Problem für Benutzeranwendungen sein, die Select anstelle von Threads verwenden möchten.

Es recht geradlinig ist tiserialport.SerialPort zu Unterklasse und die _serialFactory Methode überschreiben (die die pyserial Objekt erstellt die serielle Schnittstelle verwendet werden soll für den Zugriff)

class SerialPort(serialport.SerialPort): 
    def _serialFactory(self, dev, *args, **kwargs): 
     " pyserial recommends the following for supporting serial urls " 
     try: 
      return serial.serial_for_url(dev) 
     except AttributeError: 
      return serial.Serial(dev, *args, **kwargs) 

jedoch das resultierende Objekt fehlt ein Dateideskriptor und so die fileno() Methode (intern von t.i._posixserialport verwendet) löst eine Ausnahme aus.

--- <exception caught here> --- 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/base.py", line 1204, in mainLoop 
    self.doIteration(t) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/selectreactor.py", line 105, in doSelect 
    [], timeout) 
    File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/twisted/internet/_posixserialport.py", line 48, in fileno 
    return self._serial.fd 
exceptions.AttributeError: 'Serial' object has no attribute 'fd' 

Die aktuellen Abhilfen sind entweder socat zu verwenden, wie in der Frage beschrieben, oder für das Netzwerk seriellen Server ich verwende (Brain ES-842) Sie es in „Raw TCP“ Modus konfigurieren können statt " Telnet/RFC2217 "Modus und verwenden Sie einfach Ihr vorhandenes Protokoll über eine TCP-Verbindung (solange Sie nicht von der Flusskontrolle oder anderen seriellen Steuerleitungen abhängig sind und eine vordefinierte feste Baudrate verwenden können).