The Modbus Protocol

There are a number of good online resources describing the Modbus protocol. Thus we only cover the basics here, which are essential to understand this implementation. The reader is referred to the Modbus Homepage for detailed information.

Modbus is a binary protocol, which consists of messages passed between a server and a client. Several transport protocols are possible, but this implementation exclusively supports TCP/IP as transport layer. Each Modbus message is composed of three components:

  • A seven byte long Modbus Application Protocol Header (MBAP, see ApplicationProtocolHeader), which is actually eight bytes long in this implementation.
  • A message specific header called Protocol Data Unit (PDU)
  • An API specific payload of variable length

Each message sent to the client initiates the invocation of a function on the server. The result of this function is then returned to the client. The functions can be used to read or manipulate data on the server. The data is stored in so-called coils and registers. A coil is the equivalent to a bit, while a register contains 16-bits of data. The registers are addressed by decimal numbers. Modbus desriminates between Input Registers (read-only) and Holding Registers (read-write).

The organisation of data in registers and coils is API/vendor specific.

Protocol Implementation

Parser Functions

The following functions can be used to create requests in binary form and to parse binary response messages:

modbusclient.new_request(function, payload=b'', unit=255, transaction=0, **kwargs)[source]

Create a request message

Parameters:
  • function (int) – Function code
  • payload (bytes) – Data sent along with the request. Empty by default. Used only for writing functions.
  • unit (int) – Unit ID of device. Defaults to NO_UNIT
  • transaction (int) – Transaction ID. Defaults to 0.
  • kwargs (dict) – Keyword arguments passed verbatim to the request of the function
Returns:

Header of the request and the request in binary form.

Return type:

tuple(ApplicationProtocolHeader, bytes)

modbusclient.parse_response_header(buffer)[source]

Parse response header

Parameters:buffer (bytes) – Buffer containing the Application protocol header
Returns:Application protocol header
Return type:ApplicationProtocolHeader
Raise:
RuntimeError: if header.protocol does not match MODBUS_PROTOCOL_ID
modbusclient.parse_response_body(header, buffer)[source]

Parse response body

Parameters:
Returns:

Payload and error code

Return type:

tuple(object, int)

Modbus Application Protocol Header (MBAP)

The application protocol header is the first part of each modbus message.

class modbusclient.ApplicationProtocolHeader

Modbus Application Protocol Header (MBAP)

The application header in this implementation has a size of eight bytes. It is added to every request sent by a client. The server copies the MBAP into its response with a modified length field.

transaction

int – Transaction ID to uniquely identify the transaction in if several requests are sent in parallel

protocol

int – MODBUS protocol id (always 0)

length

int – following data bytes. For a request, this has to be set by the client, while the response length is set by the server

unit

int – Unit ID of the server. Defaults to NO_UNIT

function

int – Function code. In the MODBUS specification this is actually part of the PDU. Since the communication is simplified by including it in the MBAP instead. In case of errors, this variable assumes the error function code (0x80).

Read Request PDU

Protocol Data Unit (PDU) used by the client for read requests.

class modbusclient.ReadRequest

Modbus Read Request Protocol Data Unit (PDU)

start

int – Address of (first) register to read from

count

int – Number of coils/registers to read from

Note

A PDU usually starts with a single byte containing the function code, which is part of the ApplicationProtocolHeader in this implementation.

Read Response PDU

Protocol Data Unit (PDU) used by the server to ackknowledge read requests.

class modbusclient.ReadResponse

Modbus Response Protocol Data Unit (PDU)

size

int – Number of payload bytes

Note

A PDU usually starts with a single byte containing the function code, which is part of the ApplicationProtocolHeader in this implementation.

Write Request PDU

Protocol Data Unit (PDU) used by the client for write requests.

class modbusclient.WriteRequest

Modbus Write Request Protocol Data Unit (PDU)

start

int – Address of (first) register to write to

count

int – Number fo coils/registers to write to

size

int – Number of payload bytes to write

Note

A PDU usually starts with a single byte containing the function code, which is part of the ApplicationProtocolHeader in this implementation.

Write Response PDU

Protocol Data Unit (PDU) used by the server to acknowledge write requests.

class modbusclient.WriteResponse

Modbus Response Protocol Data Unit (PDU)

start

int – Address of (first) register to write to

count

int – Number of coils/registers which have been written

Note

A PDU usually starts with a single byte containing the function code, which is part of the ApplicationProtocolHeader in this implementation.

Helper Functions

modbusclient.protocol.create_header(name, format, attrs, defaults=None)[source]

Create a new header

Creates a header class based on namedtuple. The namedtuple components provide a convenient access to the data stored in the header. Additionally classes created by this function contain two methods to read from and write to a binary buffer:

  • static method from_buffer creates an object from a binary buffer
  • to_buffer: writes content of the header to a binary buffer
  • __len__ : Provides the length of the header (excluding payload) in bytes
Parameters:
  • name (str) – Name of class to create
  • format (str) – Format string. Refer to Struct documentation for format specification
  • attrs (str) – Attributes to add. Format as expected by namedtuple
  • defaults (tuple) – Default value for each attribute in attrs
Returns:

Class object capable of storing the header content with additional methods to parse and serialize the stored data in binary form.

Return type:

class