PyModbus Documentation

repository·dev·Indexed 25 days ago

https://github.com/pymodbus-dev/pymodbus

A fully featured Modbus protocol stack for Python providing clients, servers, and simulators. It supports synchronous and asynchronous APIs across TCP, UDP, TLS, and Serial (RS-485) communication layers. The library includes support for various framing types (ASCII, RTU, Socket, TLS), a NullModem transport for in-memory testing, and comprehensive tools for PDU and transaction management.

Tokens
12.1K
Snippets
20
Records
80
Agent score
82%

What's inside pymodbus

  1. Overview of the PyModbus Simulator (3.x)

    dev

    The PyModbus Simulator is a standard Modbus server that includes an additional HTTP interface. It is designed to provide flexible data definitions for both standard servers and simulation environments.

    Key capabilities include:

    • Data Modeling: Define devices using SimDevice architecture and manage data via SimData with specific DataType (e.g., Registers, Coils).
    • Error Testing: Test how clients handle Modbus exceptions, communication errors (like divided messages), or malicious responses.
    • Web Interface: Monitor requests/responses, inject errors, and change values online.
    • Automation: Use the REST API to automate end-to-end testing, such as spinning up servers with Unix domain sockets and setting expected responses.

    Warning: Beginning with v3.9.0 and ending with v4.0.0, this simulator will be replaced by a new version.

  2. Choose a Pymodbus server transport protocol

    dev

    Pymodbus servers support multiple transport protocols for communication. You can choose from the following:

    • Serial (RS-485): Typically used with a dongle. Note that current serial server implementation offers limited support for shared RS485 lines (multipoint).
    • TCP
    • TLS
    • UDP
    • Custom: You can implement and add your own custom transport protocol.

    Servers are available in two communication styles:

    1. Asynchronous server: Uses asyncio (the native implementation).
    2. Synchronous server: An interface layer that allows synchronous applications to use the server as if it were synchronous, though it is implemented using asyncio under the hood.
  3. Use NullModem transport for end-to-end testing without a network

    dev

    PyModbus provides a NullModem transport that allows you to perform end-to-end testing of Modbus clients and servers without requiring a physical network or serial connection. This transport substitutes the physical connection (TCP, TLS, UDP, or Serial/RS-485) with an in-memory connection.

    Requirements:

    • The server and the client(s) must run within the same Python instance.

    Activation: To activate the NullModem, set the host parameter (or port for serial transports) to NULLMODEM_HOST, which you can import from pymodbus.transport.

  4. Run simple asynchronous and synchronous client examples

    dev

    PyModbus provides basic, standalone scripts to demonstrate how a client communicates with a server. These can be copied and run directly after modifying them for your specific network parameters.

    • Simple asynchronous client: Found in examples/simple_async_client.py.
    • Simple synchronous client: Found in examples/simple_sync_client.py.
  5. Configure the Pymodbus Simulator JSON Layout

    dev

    The simulator is configured using a JSON file containing two main entries: server_list and device_list. Each entry contains a list of named servers and devices. When starting the simulator, you select one server and one device to simulate.

    If you are using the datastore_simulator programmatically, you can use a Python dictionary that follows the same structure as the device_list part of the JSON file.

    {
        "server_list": {
            "<name>": { ... },
            "..."
        },
        "device_list": {
            "<name>": { ... },
            "..."
        }
    }
  6. Install PyModbus for development from source

    dev

    If you want to contribute to PyModbus or work on the bleeding edge, clone the repository and set up a virtual environment.

    1. Clone the repository: git clone git://github.com/<your account>/pymodbus.git
    2. Create and activate a virtual environment: cd pymodbus python3 -m venv .venv source .venv/bin/activate
    3. Install in editable mode for development: pip install -e ".[development]" Or for all features: pip install -e ".[all]"
    4. Install git hooks to assist with commits: cp githooks/* .git/hooks
    git clone git://github.com/<your account>/pymodbus.git
    cd pymodbus
    python3 -m venv .venv
    source .venv/bin/activate
    pip install -e ".[development]"
  7. Configure a Datastore for a Pymodbus server

    dev

    Pymodbus servers require a datastore to manage Modbus data.

    Note for future migrations: The legacy datastores used in current versions will be replaced in v4.0.0 by SimData/SimDevice to provide more flexible data definitions. If you are starting a new project, be aware of this upcoming change in the data model.

  8. Handle Modbus Client Responses and Errors

    dev

    All simple request calls return a unified result. You should handle errors by checking both for internal ModbusException and device-reported errors using .isError().

    • Use try/except ModbusException to catch internal library or connection errors.
    • Use result.isError() to check if the Modbus device returned an error response.
    • For read requests, access data via:
      • result.bits for coils or input registers.
      • result.registers for other register types.

    Note: If you use no_response_expected=True, the result will be None if no response is received.

    try:
        rr = await client.read_coils(1, count=1, device_id=1)
    except ModbusException as exc:
        _logger.error(f"ERROR: exception in pymodbus {exc}")
        raise exc
    
    if rr.isError():
        _logger.error("ERROR: pymodbus returned an error!")
        raise ModbusException(txt)