# `transaction` — Transaction Controllers for Pymodbus

## API Documentation

Collection of transaction based abstractions

class `pymodbus.transaction.``DictTransactionManager`(client, **kwargs)

  Impelements a transaction for a manager where the results are keyed based on the supplied transaction id.

  `__init__`(client, **kwargs)

    Initializes an instance of the ModbusTransactionManager

    Parameters: | client – The client socket wrapper

  `__iter__`()

    Iterater over the current managed transactions

    Returns: | An iterator of the managed transactions

  `addTransaction`(request, tid=None)

    Adds a transaction to the handler

    This holds the requets in case it needs to be resent. After being sent, the request is removed.

    Parameters:

    - request – The request to hold on to
    - tid – The overloaded transaction id to use

  `getTransaction`(tid)

    Returns a transaction matching the referenced tid

    If the transaction does not exist, None is returned

    Parameters: | tid – The transaction to retrieve

  `delTransaction`(tid)

    Removes a transaction matching the referenced tid

    Parameters: | tid – The transaction to remove

class `pymodbus.transaction.``FifoTransactionManager`(client, **kwargs)

  Impelements a transaction for a manager where the results are returned in a FIFO manner.

  `__init__`(client, **kwargs)

    Initializes an instance of the ModbusTransactionManager

    Parameters: | client – The client socket wrapper

  `__iter__`()

    Iterater over the current managed transactions

    Returns: | An iterator of the managed transactions

  `addTransaction`(request, tid=None)

    Adds a transaction to the handler

    This holds the requets in case it needs to be resent. After being sent, the request is removed.

    Parameters:

    - request – The request to hold on to
    - tid – The overloaded transaction id to use

  `getTransaction`(tid)

    Returns a transaction matching the referenced tid

    If the transaction does not exist, None is returned

    Parameters: | tid – The transaction to retrieve

  `delTransaction`(tid)

    Removes a transaction matching the referenced tid

    Parameters: | tid – The transaction to remove

class `pymodbus.transaction.``ModbusSocketFramer`(decoder)

  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

  `__init__`(decoder)

    Initializes a new instance of the framer

    Parameters: | decoder – The decoder factory implementation to use

  `checkFrame`()

    Check and decode the next frame Return true if we were successful

  `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

  `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

  `addToFrame`(message)

    Adds new packet data to the current frame buffer

    Parameters: | message – The most recent packet

  `getFrame`()

    Return the next frame from the buffered data

    Returns: | The next full frame buffer

  `populateResult`(result)

    Populates the modbus result with the transport specific header information (pid, tid, uid, checksum, etc)

    Parameters: | result – The response packet

  `processIncomingPacket`(data, callback)

    The new packet processing 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

  `_process`(callback, error=False)

    Process incoming packets irrespective error condition

  `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).

  `getRawFrame`()

    Returns the complete buffer

  `buildPacket`(message)

    Creates a ready to send modbus packet

    Parameters: | message – The populated request/response to send

class `pymodbus.transaction.``ModbusRtuFramer`(decoder)

  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 transmist at least x many characters. In this case it is 3.5 characters. Also, if we recieve 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

  `__init__`(decoder)

    Initializes a new instance of the framer

    Parameters: | decoder – The decoder factory implementation to use

  `checkFrame`()

    Check if the next frame is available. Return True if we were successful.

  `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

  `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).

  `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

  `populateHeader`()

    Try to set the headers uid, len and crc.

    This method examines self.__buffer and writes meta information into self.__header. It calculates only the values for headers that are not already in the dictionary.

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

  `addToFrame`(message)

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

    Parameters: | message – The most recent packet

  `getFrame`()

    Get the next frame from the buffer

    Returns: | The frame data or ‘’

  `populateResult`(result)

    Populates the modbus result header

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

    Parameters: | result – The response packet

  `processIncomingPacket`(data, callback)

    The new packet processing 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

  `buildPacket`(message)

    Creates a ready to send modbus packet

    Parameters: | message – The populated request/response to send

  `_process`(callback, error=False)

    Process incoming packets irrespective error condition

  `getRawFrame`()

    Returns the complete buffer

class `pymodbus.transaction.``ModbusAsciiFramer`(decoder)

  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.

  `__init__`(decoder)

    Initializes a new instance of the framer

    Parameters: | decoder – The decoder implementation to use

  `checkFrame`()

    Check and decode the next frame

    Returns: | True if we successful, False otherwise

  `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

  `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

  `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

  `getFrame`()

    Get the next frame from the buffer

    Returns: | The frame data or ‘’

  `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).

  `populateResult`(result)

    Populates the modbus result header

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

    Parameters: | result – The response packet

  `processIncomingPacket`(data, callback)

    The new packet processing 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

  `buildPacket`(message)

    Creates a ready to send modbus packet Built off of a modbus request/response

    Parameters: | message – The request/response to send
    Returns: | The encoded packet

class `pymodbus.transaction.``ModbusBinaryFramer`(decoder)

  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.

  `__init__`(decoder)

    Initializes a new instance of the framer

    Parameters: | decoder – The decoder implementation to use

  `checkFrame`()

    Check and decode the next frame

    Returns: | True if we are successful, False otherwise

  `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

  `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

  `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

  `getFrame`()

    Get the next frame from the buffer

    Returns: | The frame data or ‘’

  `populateResult`(result)

    Populates the modbus result header

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

    Parameters: | result – The response packet

  `processIncomingPacket`(data, callback)

    The new packet processing 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

  `buildPacket`(message)

    Creates a ready to send modbus packet

    Parameters: | message – The request/response to send
    Returns: | The encoded packet

  `_preflight`(data)

    Preflight buffer test

    This basically scans the buffer for start and end tags and if found, escapes them.

    Parameters: | data – The message to escape
    Returns: | the escaped packet

  `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).