On Feb 2, 2011, at 7:42 AM, Michael Thompson wrote:

On 2 February 2011 10:11, Jason Heeris <jason.heeris@gmail.com> wrote:
On 2 February 2011 17:53, Albert Brandl <albert.brandl@weiermayer.com> wrote:
"string" could be interpreted as "complete message". It might e.g. happen
that a message arrives in three chunks. Each time a chunk is read, the
dataReceived method is called. When it detects that the message is
complete, it calls stringReceived with the content of the message.

Okay, but I don't see how to use that to solve my particular problem.
I'm not waiting passively to receive a complete string, I have to
react to whatever's sent back, character by character, either by
reporting completion, an error or sending more data. In effect, I
guess, each character is a "complete message" anyway. I don't think
the t.i.protocols offer much for that.

Yep you have a pretty simple protocol there so even the basic examples
are probably more than you need.

Something like this might get you started.

class MyProtocol(Protocol):
   def send(self, byte):
         self.transport.write(byte)
         self.response = Deferred()
         return self.response

   def dataReceived(self, byte):
          self.response.callback(byte)

Not quite.  You mean:

class MyProtocol(Protocol):
  # ...
  def dataReceived(self, data):
    for octet in data:
      self.process(octet)

If the device outputs multiple bytes it might show up to Twisted as strings of arbitrary length (this depends on timings of the serial port which are basically impossible to control), so if you want to process a byte at a time, you need to specifically iterate through the string that is passed, even if it's usually one byte long.  (Some of the protocol examples showed multibyte sequences as messages.  I don't understand the framing well enough to provide a better example though, sorry.)