использовать витой каркас Python для подключения к нескольким последовательным сокетам - PullRequest
3 голосов
/ 19 мая 2011

В настоящее время я использую Twisted для подключения к имеющемуся у меня последовательному устройству, используя код, подобный следующему.

from twisted.internet import reactor
SerialPort(Handler(), "/dev/ttyACM1", reactor, baudrate='9600')
reactor.run()

Однако я знаю, что необходимо расширить приложение, чтобы отслеживать добавление (и удаление) новых последовательных устройств. В настоящее время я использую pyinotify для поиска новых устройств, добавляемых / удаляемых, и это, кажется, работает хорошо.

class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        ... connect to serial device
        ...

В данный момент у меня, кажется, есть несколько проблем. Самое большое, что я думаю, это то, что я просто недостаточно знаю Twisted, чтобы знать, каков «правильный» способ сделать это.

В настоящее время, как я понял, обработчик событий pyinotify запускается в отдельном потоке, что означает, что реактор не работает в основном потоке. Это проблема?

Как только первое устройство подключено, я изо всех сил стараюсь добавить второе - не в последнюю очередь реактор уже работает к моменту добавления второго устройства. Даже если я защищу это с помощью

if not reactor.running: 

второе соединение не добавляет к реактору должным образом (по крайней мере, connectionMade, полученные методы приема данных не запускаются).

Если я сначала запустил реактор, то позвольте событиям пииноинформации попробовать и добавить к работающему реактору, это тоже не похоже - устройство подключается, но метод dataReceived никогда не вызывается.

В принципе, я уверен, что есть хороший рецепт, чтобы заставить это работать, я просто не смог найти его ни через Google, ни методом проб и ошибок. Кто-нибудь может подсказать мне, как я мог бы заставить это работать?

Заранее благодарим за любую помощь, которую вы можете предложить,

Simon

1 Ответ

7 голосов
/ 19 мая 2011

Каждый раз, когда вы хотите использовать Twisted API, но ваш код не работает в том же потоке, что и реактор, вы можете использовать reactor.callFromThread, чтобы реактор вызывал часть вашего кода в своем потоке. Так, например, вы можете сделать что-то вроде этого:

def process_IN_CREATE(self, event):
    reactor.callFromThread(
        SerialPort, Handler(), "/dev/ttyACM1", reactor, baudrate='9600')

Однако вам также не нужно иметь никаких дополнительных потоков, чтобы делать то, что вы описали. Вместо использования pyinotify используйте twisted.internet.inotify:

from twisted.python.filepath import FilePath
from twisted.internet.inotify import IN_CREATE, INotify
from twisted.internet import reactor

def created(ignored, path, mask):
    SerialPort(
        Handler(),
        "/dev/ttyACM1", # Or... use `path` here?
        reactor, baudrate='9600')

notifier = INotify()
notifier.watch(FilePath("/some/directory"), IN_CREATE, callbacks=[created])
notifier.startReading()

reactor.run()
...