Использовать сетевые последовательные порты RFC2217 с Twisted Python?

есть ли способ подключиться к сетевому последовательному порту RFC2217 с помощью Twisted Python?

Pyserial, кажется, поддерживает его через serial.serial_for_url("rfc2217://...") функции. И они указывают, что twisted использует pyserial для управления последовательными соединениями, однако twisted.internet.serialport.SerialPort кажется, ожидает имя порта или номер, который предполагает, что он просто передает это в serial.Serial конструктор.

Я могу использовать socat для создания PTY извне и передать имя dev в twisted, которое отлично работает, но мне было интересно, могу ли я обойти этот шаг, используя поддержку pyserial напрямую.

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

редактировать: элемент pyserial faq предлагает эту модификацию для создания экземпляров последовательных объектов:

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

не уверен, что это помогает...

1 ответов


Я пришел к выводу, что использование поддержки RFC2217 Pyserial с Twisted Python нетривиально. Реализация Pyserial RFC2217, кроме в настоящее время экспериментальные, использует потоки для управления соединением сокета, которое они заявляют как проблему для избранных приложений на основе:

текущая реализация запускает поток, который продолжает чтение из (внутреннего) сокета. Поток управляется автоматически rfc2217.Последовательный порт объект на open()/close () для. Однако это может быть проблемой для пользовательских приложений, которые любят использовать select вместо потоков.

это довольно прямо вперед к подклассу t.Я. serialport.SerialPort и перезаписать метод _serialFactory (который создает объект pyserial для доступа к последовательному порту)

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)

однако результирующему объекту не хватает файлового дескриптора, поэтому fileno() метод (используется внутри t.i._posixserialport) бросает исключение.

--- <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'

текущие обходные пути должны либо использовать socat как описано в вопросе, или для сетевого последовательного сервера, который я использую (Brainboxes ES-842), вы можете настроить его в режиме "Raw TCP" вместо режима "Telnet/RFC2217" и просто использовать существующий протокол через TCP-соединение (если вы не зависите от управления потоком или других последовательных линий управления и можете использовать предопределенную фиксированную скорость передачи данных).