Использовать сетевые последовательные порты 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-соединение (если вы не зависите от управления потоком или других последовательных линий управления и можете использовать предопределенную фиксированную скорость передачи данных).