[Twisted-Python] Wiring a new reactor/Client into Twisted

Hi, I'm using Twisted in an industrial application to replace a multi-threaded C++ driver which I developed some time ago to drive an array of serial ports (COM port expander) simultaneously. This is quite a typical application found in industrial control, building security/access control systems, etc. where an extended multi-drop serial protocol like RS485/422 is used together with a standard message format such as Modbus to do remote data aquisition and control of embedded devices. These kind of systems make use of what is refered to as a master/slave serial driver i.e. there is only one master (typically a PC) and a slave device may only respond to polls from the master. My aim is to create a new Twisted package - say twisted.industrial - which I hope contribute to the Twisted platform. I want to achieve this by extending Twisted without modifying any Twisted sources, reusing as much as possible of existing Twisted code and * doing things very much the "Twisted way" * :) The main problem is that most of Twisted's base classes seems to have TCP/UDP network connectivity in mind. I have managed to subclass SelectReactor in order to create SerialSelectReactor, base.BaseConnector to create SerialConnector, SerialPort to create ExtendedSerialPort and I have the following piece of code working. *********************************************************** if __name__=='__main__': from serialreactor import serialreactor factory = ModbusFactory() factory.protocol=Modbus() serialreactor.connectSerial('/dev/ttyS0',9600,factory) print "start reactor" serialreactor.run() print "exit reactor" *********************************************************** This is good but I want to run more than one serialport (or serial protocol) simultaneously - i.e I need to drive up to 64 serial ports at the same time. I believe I need to do something like: ************************************************************ if __name__=='__main__': from serialapplication import SerialClient,service application=service.Application('Serial',uid=1,gid=1) factory = ModbusFactory() factory.protocol=Modbus() print "start client" internet.SerialClient(79,factory).setServiceParent(service.IServiceCollection(app lication)) print "exit client" ************************************************************** But I'm finding difficulty in grasping the code in application.internet (do not understand why it was done like that) since I want to subclass _AbstractClient which is seems to be the product of some clever text manipulation and dynamic "class creation". Any comments, suggestions, recommendations and am I one the right track? regards, Eugene

Please take a look at twisted.internet.serial and see if it meets your needs?

Itamar Shtull-Trauring wrote:
Please take a look at twisted.internet.serial and see if it meets your needs?
twisted.internet.serial is a wrapper for pyserial. I'm already using SerialPort from twisted.internet.serial but I want to wire it so that it works like the rest of a typical Twisted app with a factory container and reactor like event loop. regards, Eugene

On Mon, 2004-07-26 at 18:05, Eugene Coetzee wrote:
1. It doesn't require a factory because that wouldn't make sense in the context, just like twisted's udp support doesn't require a factory. 2. It requires the reactor event loop to be running in order to work. -- Itamar Shtull-Trauring http://itamarst.org

Itamar Shtull-Trauring wrote:
Thanks for your feedback on this question. According to the howto's (www.twistedmatrix.com/documents/current/howto/tutorial/intro) the factory is useful because it allows you to separate the database code from the protocol implementation. In other words you are adding an abstraction layer to separate concerns - something that I would also like to do. In the scenario of a Modbus implementation - there is also a Modbus implementation for ethernet i.e. Modbus RTU versus Modbus serial (www.modbus.org).
2. It requires the reactor event loop to be running in order to work.
I would rephrase what I'm trying to do as follows : I want an application with a single event loop and abstraction layer so that I can handle TCP/UDP/serial/you-name-it type of protocols transparently. I also want a container into which I can plug multiple and different kind of protocols as described at www.twistedmatrix.com/documents/current/howto/tutorial/factory under the heading "using a single factory for multiple protocols" In order to achieve this I need to extend SerialProtocol from twisted.serial but it is clear that I need to do much more than just that. This is where I have difficulty in in extending the functionality of twisted.application.internet to build something which I can refer to as "SerialClient" (analogous to TCPClient,UDPClient) regards, Eugene -- -- =============================================== Web -> www.reedflute.com ===============================================

On Tue, 2004-07-27 at 16:35, Eugene Coetzee wrote:
You can do that without a factory. The factory is really there to *create* instances - which is not relevant e.g. for UDP and thus UDP has no factories, even though UDP may require an abstraction layer. There's nothing preventing you from writing your own layer.
UDPClient is very different from TCPClient (and deprecated, btw). A single UDPClient has one protocol instance and listens on one UDP port. Likewise, a SerialClient would only be connected to one serial port. If you want something beyond that you'd need to build another layer on top of that, and this layer probably would be specific to your application and not a generic one. -- Itamar Shtull-Trauring http://itamarst.org

Itamar Shtull-Trauring wrote:
This is exactly (what I think :) I want. I want a dedicated client for each SerialPort cause in accordance with the master/slave polling philosopy you can only address one device at a time on a specific port - and *have to* wait until you receive a response or timeout occurs. My multithreading driver allows you do do this on a bunch of ports concurrently. Thanx for the feedback though - I'm going to mess around with application.internet a little more (along the same lines of deprecated UDPClient) and see how far that gets me. regards, Eugene =============================================== Web -> www.reedflute.com ===============================================

Please take a look at twisted.internet.serial and see if it meets your needs?

Itamar Shtull-Trauring wrote:
Please take a look at twisted.internet.serial and see if it meets your needs?
twisted.internet.serial is a wrapper for pyserial. I'm already using SerialPort from twisted.internet.serial but I want to wire it so that it works like the rest of a typical Twisted app with a factory container and reactor like event loop. regards, Eugene

On Mon, 2004-07-26 at 18:05, Eugene Coetzee wrote:
1. It doesn't require a factory because that wouldn't make sense in the context, just like twisted's udp support doesn't require a factory. 2. It requires the reactor event loop to be running in order to work. -- Itamar Shtull-Trauring http://itamarst.org

Itamar Shtull-Trauring wrote:
Thanks for your feedback on this question. According to the howto's (www.twistedmatrix.com/documents/current/howto/tutorial/intro) the factory is useful because it allows you to separate the database code from the protocol implementation. In other words you are adding an abstraction layer to separate concerns - something that I would also like to do. In the scenario of a Modbus implementation - there is also a Modbus implementation for ethernet i.e. Modbus RTU versus Modbus serial (www.modbus.org).
2. It requires the reactor event loop to be running in order to work.
I would rephrase what I'm trying to do as follows : I want an application with a single event loop and abstraction layer so that I can handle TCP/UDP/serial/you-name-it type of protocols transparently. I also want a container into which I can plug multiple and different kind of protocols as described at www.twistedmatrix.com/documents/current/howto/tutorial/factory under the heading "using a single factory for multiple protocols" In order to achieve this I need to extend SerialProtocol from twisted.serial but it is clear that I need to do much more than just that. This is where I have difficulty in in extending the functionality of twisted.application.internet to build something which I can refer to as "SerialClient" (analogous to TCPClient,UDPClient) regards, Eugene -- -- =============================================== Web -> www.reedflute.com ===============================================

On Tue, 2004-07-27 at 16:35, Eugene Coetzee wrote:
You can do that without a factory. The factory is really there to *create* instances - which is not relevant e.g. for UDP and thus UDP has no factories, even though UDP may require an abstraction layer. There's nothing preventing you from writing your own layer.
UDPClient is very different from TCPClient (and deprecated, btw). A single UDPClient has one protocol instance and listens on one UDP port. Likewise, a SerialClient would only be connected to one serial port. If you want something beyond that you'd need to build another layer on top of that, and this layer probably would be specific to your application and not a generic one. -- Itamar Shtull-Trauring http://itamarst.org

Itamar Shtull-Trauring wrote:
This is exactly (what I think :) I want. I want a dedicated client for each SerialPort cause in accordance with the master/slave polling philosopy you can only address one device at a time on a specific port - and *have to* wait until you receive a response or timeout occurs. My multithreading driver allows you do do this on a bunch of ports concurrently. Thanx for the feedback though - I'm going to mess around with application.internet a little more (along the same lines of deprecated UDPClient) and see how far that gets me. regards, Eugene =============================================== Web -> www.reedflute.com ===============================================
participants (2)
-
Eugene Coetzee
-
Itamar Shtull-Trauring