Serial Troubleshooting
In serial communication, the message sender and the receiver structure their messages to each other with defined envelopes. Whenever either communication partner sends a message, the other partner listens until it hears the defined terminating sequence which tells the listener that the message is over, think "over" when using walkie-talkies.
Because all messages sent must include the message terminator and all listening actions will continue until a message terminator is encountered, we can encapsulate this behavior into a reusable Command
that ensures these rules are consistently followed.
Take a look at SerialCommand
to see what customizing this behavior looks like in action.
SerialCommand
allows the configuration of a _read_terminator
, which defines the message envelope expected from the device, a _write_terminator
, which defines the message envelope expected by the device, and an encoding
which is used to convert between bytes and strings.
Problem
In an ideal world the SerialCommand
works for all interactions with a serial device. The messages returned by the device, however were encoded by humans and it is very possible that in communicating with the device, messages are prematurely terminated by our Protocol
because the full message from the device is malformatted and contains multiple terminators.
Solution
To handle this behavior, the Command
can be modified with the multiline
decorator on the _validate_response
method.
from unitelabs.bus import CommandBuilder
builder = CommandBuilder(SerialCommand).with_multiline(0.001)
cmd = builder.build("request")
with_multiline
takes as an optional argument a callable function to replace the default super() call within _validate_response
.
multiline
takes a timeout argument which sets the amount of time in seconds to wait for more data before calling the _validate_response
method. The timeout
should be as short a time as possible and is specific to the device's data transfer speeds.
super
from within the multiline wrapped method must use the old style super which specifies the base class, i.e. super(SelfClass, self)