pymodbus.framer package

Submodules

pymodbus.framer.ascii_framer module

Ascii_framer.

class pymodbus.framer.ascii_framer.ModbusAsciiFramer(decoder, client=None)

Bases: pymodbus.framer.ModbusFramer

Modbus ASCII Frame Controller.

[ Start ][Address ][ Function ][ Data ][ LRC ][ End ]

1c 2c 2c Nc 2c 2c

  • data can be 0 - 2x252 chars

  • end is “\r\n” (Carriage return line feed), however the line feed character can be changed via a special command

  • start is “:”

This framer is used for serial transmission. Unlike the RTU protocol, the data in this framer is transferred in plain text ascii.

addToFrame(message)

Add the next message to the frame buffer.

This should be used before the decoding while loop to add the received data to the buffer handle.

Parameters

message – The most recent packet

advanceFrame()

Skip over the current framed message.

This allows us to skip over the current message after we have processed it or determined that it contains an error. It also has to reset the current frame header handle

buildPacket(message)

Create a ready to send modbus packet.

Built off of a modbus request/response

Parameters

message – The request/response to send

Returns

The encoded packet

checkFrame()

Check and decode the next frame.

Returns

True if we successful, False otherwise

decode_data(data)

Decode data.

getFrame()

Get the next frame from the buffer.

Returns

The frame data or “”

isFrameReady()

Check if we should continue decode logic.

This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data in the buffer.

Returns

True if ready, False otherwise

method = 'ascii'
populateResult(result)

Populate the modbus result header.

The serial packets do not have any header information that is copied.

Parameters

result – The response packet

processIncomingPacket(data, callback, unit, **kwargs)

Process new packet pattern.

This takes in a new request packet, adds it to the current packet stream, and performs framing on it. That is, checks for complete messages, and once found, will process all that exist. This handles the case when we read N + 1 or 1 // N messages at a time instead of 1.

The processed and decoded messages are pushed to the callback function to process and send.

Parameters
  • data – The new packet data

  • callback – The function to send results to

  • unit – Process if unit id matches, ignore otherwise (could be a list of unit ids (server) or single unit id(client/server))

  • kwargs

Raises

ModbusIOException

resetFrame()

Reset the entire message frame.

This allows us to skip ovver errors that may be in the stream. It is hard to know if we are simply out of sync or if there is an error in the stream as we have no way to check the start or end of the message (python just doesn”t have the resolution to check for millisecond delays).

pymodbus.framer.binary_framer module

Binary framer.

class pymodbus.framer.binary_framer.ModbusBinaryFramer(decoder, client=None)

Bases: pymodbus.framer.ModbusFramer

Modbus Binary Frame Controller.

[ Start ][Address ][ Function ][ Data ][ CRC ][ End ]

1b 1b 1b Nb 2b 1b

  • data can be 0 - 2x252 chars

  • end is “}”

  • start is “{“

The idea here is that we implement the RTU protocol, however, instead of using timing for message delimiting, we use start and end of message characters (in this case { and }). Basically, this is a binary framer.

The only case we have to watch out for is when a message contains the { or } characters. If we encounter these characters, we simply duplicate them. Hopefully we will not encounter those characters that often and will save a little bit of bandwitch without a real-time system.

Protocol defined by jamod.sourceforge.net.

addToFrame(message)

Add the next message to the frame buffer.

This should be used before the decoding while loop to add the received data to the buffer handle.

Parameters

message – The most recent packet

advanceFrame()

Skip over the current framed message.

This allows us to skip over the current message after we have processed it or determined that it contains an error. It also has to reset the current frame header handle

buildPacket(message)

Create a ready to send modbus packet.

Parameters

message – The request/response to send

Returns

The encoded packet

checkFrame()

Check and decode the next frame.

Returns

True if we are successful, False otherwise

decode_data(data)

Decode data.

getFrame()

Get the next frame from the buffer.

Returns

The frame data or “”

isFrameReady()

Check if we should continue decode logic.

This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data in the buffer.

Returns

True if ready, False otherwise

method = 'binary'
populateResult(result)

Populate the modbus result header.

The serial packets do not have any header information that is copied.

Parameters

result – The response packet

processIncomingPacket(data, callback, unit, **kwargs)

Process new packet pattern.

This takes in a new request packet, adds it to the current packet stream, and performs framing on it. That is, checks for complete messages, and once found, will process all that exist. This handles the case when we read N + 1 or 1 // N messages at a time instead of 1.

The processed and decoded messages are pushed to the callback function to process and send.

Parameters
  • data – The new packet data

  • callback – The function to send results to

  • unit – Process if unit id matches, ignore otherwise (could be a list of unit ids (server) or single unit id(client/server)

  • kwargs

Raises

ModbusIOException

resetFrame()

Reset the entire message frame.

This allows us to skip ovver errors that may be in the stream. It is hard to know if we are simply out of sync or if there is an error in the stream as we have no way to check the start or end of the message (python just doesn”t have the resolution to check for millisecond delays).

pymodbus.framer.rtu_framer module

RTU framer.

class pymodbus.framer.rtu_framer.ModbusRtuFramer(decoder, client=None)

Bases: pymodbus.framer.ModbusFramer

Modbus RTU Frame controller.

[ Start Wait ] [Address ][ Function Code] [ Data ][ CRC ][ End Wait ]

3.5 chars 1b 1b Nb 2b 3.5 chars

Wait refers to the amount of time required to transmit at least x many characters. In this case it is 3.5 characters. Also, if we receive a wait of 1.5 characters at any point, we must trigger an error message. Also, it appears as though this message is little endian. The logic is simplified as the following:

block-on-read:
    read until 3.5 delay
    check for errors
    decode

The following table is a listing of the baud wait times for the specified baud rates:

------------------------------------------------------------------
 Baud  1.5c (18 bits)   3.5c (38 bits)
------------------------------------------------------------------
 1200   13333.3 us       31666.7 us
 4800    3333.3 us        7916.7 us
 9600    1666.7 us        3958.3 us
19200     833.3 us        1979.2 us
38400     416.7 us         989.6 us
------------------------------------------------------------------
1 Byte = start + 8 bits + parity + stop = 11 bits
(1/Baud)(bits) = delay seconds
addToFrame(message)

Add the received data to the buffer handle.

Parameters

message – The most recent packet

advanceFrame()

Skip over the current framed message.

This allows us to skip over the current message after we have processed it or determined that it contains an error. It also has to reset the current frame header handle

buildPacket(message)

Create a ready to send modbus packet.

Parameters

message – The populated request/response to send

checkFrame()

Check if the next frame is available.

Return True if we were successful.

  1. Populate header

  2. Discard frame if UID does not match

decode_data(data)

Decode data.

getFrame()

Get the next frame from the buffer.

Returns

The frame data or “”

getRawFrame()

Return the complete buffer.

get_expected_response_length(data)

Get the expected response length.

Parameters

data – Message data read so far

Raises

IndexError – If not enough data to read byte count

Returns

Total frame size

isFrameReady()

Check if we should continue decode logic.

This is meant to be used in a while loop in the decoding phase to let the decoder know that there is still data in the buffer.

Returns

True if ready, False otherwise

method = 'rtu'
populateHeader(data=None)

Try to set the headers uid, len and crc.

This method examines self._buffer and writes meta information into self._header.

Beware that this method will raise an IndexError if self._buffer is not yet long enough.

populateResult(result)

Populate the modbus result header.

The serial packets do not have any header information that is copied.

Parameters

result – The response packet

processIncomingPacket(data, callback, unit, **kwargs)

Process new packet pattern.

This takes in a new request packet, adds it to the current packet stream, and performs framing on it. That is, checks for complete messages, and once found, will process all that exist. This handles the case when we read N + 1 or 1 // N messages at a time instead of 1.

The processed and decoded messages are pushed to the callback function to process and send.

Parameters
  • data – The new packet data

  • callback – The function to send results to

  • unit – Process if unit id matches, ignore otherwise (could be a list of unit ids (server) or single unit id(client/server)

  • kwargs

recvPacket(size)

Receive packet from the bus with specified len.

Parameters

size – Number of bytes to read

Returns

resetFrame()

Reset the entire message frame.

This allows us to skip over errors that may be in the stream. It is hard to know if we are simply out of sync or if there is an error in the stream as we have no way to check the start or end of the message (python just doesn”t have the resolution to check for millisecond delays).

sendPacket(message)

Send packets on the bus with 3.5char delay between frames.

Parameters

message – Message to be sent over the bus

Returns

pymodbus.framer.socket_framer module

Socket framer.

class pymodbus.framer.socket_framer.ModbusSocketFramer(decoder, client=None)

Bases: pymodbus.framer.ModbusFramer

Modbus Socket Frame controller.

Before each modbus TCP message is an MBAP header which is used as a message frame. It allows us to easily separate messages as follows:

[         MBAP Header         ] [ Function Code] [ Data ]         [ tid ][ pid ][ length ][ uid ]
  2b     2b     2b        1b           1b           Nb

while len(message) > 0:
    tid, pid, length`, uid = struct.unpack(">HHHB", message)
    request = message[0:7 + length - 1`]
    message = [7 + length - 1:]

* length = uid + function code + data
* The -1 is to account for the uid byte
addToFrame(message)

Add new packet data to the current frame buffer.

Parameters

message – The most recent packet

advanceFrame()

Skip over the current framed message.

This allows us to skip over the current message after we have processed it or determined that it contains an error. It also has to reset the current frame header handle

buildPacket(message)

Create a ready to send modbus packet.

Parameters

message – The populated request/response to send

checkFrame()

Check and decode the next frame.

Return true if we were successful.

decode_data(data)

Decode data.

getFrame()

Return the next frame from the buffered data.

Returns

The next full frame buffer

getRawFrame()

Return the complete buffer.

isFrameReady()

Check if we should continue decode logic.

This is meant to be used in a while loop in the decoding phase to let the decoder factory know that there is still data in the buffer.

Returns

True if ready, False otherwise

method = 'socket'
populateResult(result)

Populate the modbus result.

With the transport specific header information (pid, tid, uid, checksum, etc)

Parameters

result – The response packet

processIncomingPacket(data, callback, unit, **kwargs)

Process new packet pattern.

This takes in a new request packet, adds it to the current packet stream, and performs framing on it. That is, checks for complete messages, and once found, will process all that exist. This handles the case when we read N + 1 or 1 // N messages at a time instead of 1.

The processed and decoded messages are pushed to the callback function to process and send.

Parameters
  • data – The new packet data

  • callback – The function to send results to

  • unit – Process if unit id matches, ignore otherwise (could be a list of unit ids (server) or single unit id(client/server)

  • kwargs

resetFrame()

Reset the entire message frame.

This allows us to skip ovver errors that may be in the stream. It is hard to know if we are simply out of sync or if there is an error in the stream as we have no way to check the start or end of the message (python just doesn”t have the resolution to check for millisecond delays).

Module contents

Framer start.

class pymodbus.framer.ModbusFramer

Bases: pymodbus.interfaces.IModbusFramer

Base Framer class.

name = ''
recvPacket(size)

Receive packet from the bus.

With specified len :param size: Number of bytes to read :return:

sendPacket(message)

Send packets on the bus.

With 3.5char delay between frames :param message: Message to be sent over the bus :return: