### Install Documentation Tools
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Install the necessary tools for building project documentation.
```bash
pip install ".[documentation]"
```
--------------------------------
### Install Documentation Tools
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Installs the necessary tools for building the project documentation. This is a prerequisite for generating the documentation.
```bash
pip install "'.[documentation]'"
```
--------------------------------
### Device Setup Configuration - Alternative
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Alternative device setup configuration with different default actions for data types. Note the null values for actions.
```json
{
"device_list": {
"device_try": {
"setup": {
"co size": 63000,
"di size": 63000,
"hr size": 63000,
"ir size": 63000,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": null,
"uint32": null,
"float32": null,
"string": null
}
}
}
}
}
}
```
--------------------------------
### Start Pymodbus Simulator
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Use this command to start the Pymodbus simulator. Ensure you specify the correct modbus device.
```bash
pymodbus.simulator --modbus_device device_try
```
--------------------------------
### Install Development Tools
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Install required development tools in editable mode. Use the '.[development]' option for development tools or '.[all]' for all extras including documentation.
```bash
pip install -e ".[development]"
```
```bash
pip install -e ".[all]"
```
--------------------------------
### Device Setup Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure device setup parameters including data sizes for different register types and default values for various data types.
```json
{
"device_list": {
"device": {
"setup": {
"co size": 63000,
"di size": 63000,
"hr size": 63000,
"ir size": 63000,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": "increment",
"uint32": "increment",
"float32": "increment",
"string": null
}
}
}
}
}
}
```
--------------------------------
### Install Pymodbus with Pip
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Install the pymodbus library using pip. For serial communication, install with the 'serial' extra.
```bash
pip install pymodbus
```
```bash
pip install pymodbus[serial]
```
--------------------------------
### Install pymodbus with pip
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Install the core pymodbus library using pip. This is the standard method for applications that use the library.
```bash
pip install pymodbus
```
--------------------------------
### Basic Modbus TCP Client Example
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
A simple example demonstrating how to connect to a Modbus TCP device, write a coil, read coils, and close the connection.
```python
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('MyDevice.lan')
client.connect()
client.write_coil(1, True)
result = client.read_coils(1,1)
print(result.bits[0])
client.close()
```
--------------------------------
### Install Pymodbus with Pip Options
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Install pymodbus with specific options or all options using pip. The 'all' option includes extras for documentation and development.
```bash
pip install pymodbus[,...]
```
```bash
pip install pymodbus[all]
```
--------------------------------
### Synchronous Modbus Client Example
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/examples.md
This example demonstrates how to set up and use a synchronous Modbus client for TCP, UDP, or serial communication. It includes connecting to a server, reading coils and holding registers, converting register data, and closing the connection. Ensure the corresponding server is running before executing.
```python
#!/usr/bin/env python3
"""Pymodbus synchronous client example.
An example of a single threaded synchronous client.
usage: simple_sync_client.py
All options must be adapted in the code
The corresponding server must be started before e.g. as:
python3 server_sync.py
"""
# --------------------------------------------------------------------------- #
# import the various client implementations
# --------------------------------------------------------------------------- #
import pymodbus.client as ModbusClient
from pymodbus import (
FramerType,
ModbusException,
pymodbus_apply_logging_config,
)
def run_sync_simple_client(comm, host, port, framer=FramerType.SOCKET):
"""Run sync client."""
# activate debugging
pymodbus_apply_logging_config("DEBUG")
print("get client")
client: ModbusClient.ModbusBaseSyncClient
if comm == "tcp":
client = ModbusClient.ModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.ModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# source_address=None,
)
elif comm == "serial": # pragma: no cover
client = ModbusClient.ModbusSerialClient(
port,
framer=framer,
# timeout=10,
# retries=3,
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
# handle_local_echo=False,
)
else: # pragma: no cover
print(f"Unknown client {comm} selected")
return
print("connect to server")
client.connect()
print("get and verify data")
try:
rr = client.read_coils(1, count=1, device_id=1)
except ModbusException as exc: # pragma: no cover
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError(): # pragma: no cover
print(f"Received exception from device ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
return
try:
# See all calls in client_calls.py
rr = client.read_holding_registers(10, count=2, device_id=1)
except ModbusException as exc: # pragma: no cover
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError(): # pragma: no cover
print(f"Received exception from device ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
return
value_int32 = client.convert_from_registers(
rr.registers, data_type=client.DATATYPE.INT32
)
print(f"Got int32: {value_int32}")
print("close connection")
client.close()
if __name__ == "__main__":
run_sync_simple_client("tcp", "127.0.0.1", "5020")
```
--------------------------------
### Install all pymodbus development tools in editable mode
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Install all available pymodbus extras, including documentation and development tools, in editable mode. This provides a full development environment.
```bash
pip install -e ".[all]"
```
--------------------------------
### Install Git Hooks
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Copy git hooks from the repository to the .git/hooks directory to help control commits and prevent errors.
```bash
cp githooks/* .git/hooks
```
--------------------------------
### Install pymodbus with specific options via pip
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Install pymodbus with a comma-separated list of extra options. Options include serial, simulator, documentation, development, and all.
```bash
pip install pymodbus[ ,...]
```
--------------------------------
### Simulator Setup Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Defines the size of data blocks (coils, discrete inputs, holding registers, input registers) and options for shared blocks and type exceptions. It also specifies default values and actions for unconfigured registers.
```default
"setup": {
"co size": 10,
"di size": 20,
"hr size": 15,
"ir size": 25,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": "register",
"uint32": "register",
"float32": "register",
"string": null
}
}
}
```
--------------------------------
### Asynchronous Modbus TCP Client Example
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/client.md
Demonstrates creating an asynchronous Modbus TCP client, connecting to a device, writing to a coil, reading coils, and closing the connection. Ensure the asyncio loop is running when executing this code.
```python
from pymodbus.client import AsyncModbusTcpClient
client = AsyncModbusTcpClient('MyDevice.lan') # Create client object
await client.connect() # connect to device, reconnect automatically
await client.write_coil(1, True, device_id=1) # set information in device
result = await client.read_coils(2, count=3, device_id=1) # get information from device
print(result.bits[0]) # use information
client.close() # Disconnect device
```
--------------------------------
### Bit Handling Example (3.10.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Demonstrates the bit handling order change in version 3.10.0, where LSB->MSB is applied across bytes, differing from older versions' per-byte ordering.
```text
Hex bytes: 0x00 0x01
Older versions would deliver False * 8 True False * 7
V3.10 deliver True False * 15
Hex bytes: 0x01 0x03
Older versions would deliver True False * 7 True True False * 6
V3.10 deliver True True False * 6 True False * 7
```
--------------------------------
### Bit Handling Example (3.11.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Illustrates the logical bit order returned by bit functions in version 3.11.0 and later, which changed from byte order to LSB->MSB for each byte.
```text
Hex bytes: 0x00 0x01
delivers False * 8 True False * 7
Hex bytes: 0x01 0x03
delivers True False * 7 True True False * 6
```
--------------------------------
### Convert ModbusSequentialDataBlock to SimDevice
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/upgrade_40.md
This example shows the conversion from ModbusSequentialDataBlock to the new SimDevice structure for sequential registers. Device ID 0 acts as a catch-all for undefined devices.
```python
dev = ModbusDeviceContext(
co=ModbusSequentialDataBlock(0x01, 15),
di=ModbusSequentialDataBlock(0x01, [16]),
hr=ModbusSequentialDataBlock(0x01, [17]),
ir=ModbusSequentialDataBlock(0x01, [18])
)
server_context = ModbusServerContext(
devices={1: dev,
0: dev
})
await StartAsync**Server(context=server_context)
```
```python
from pymodbus.simulator import SimData, SimDevice, DataType
devices = [SimDevice(1, simdata=(
SimData(0x01, values=15, datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS)
)
),
SimDevice(1, simdata=(
SimData(0x01, values=15, datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS)
)
)
]
await StartAsync**Server(context=devices)
```
--------------------------------
### Install pymodbus with serial support via pip
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Install pymodbus with the necessary dependencies for serial communication. This includes the pyserial package.
```bash
pip install pymodbus[serial]
```
--------------------------------
### Minimal TCP Server Entry Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
An example of a minimal server entry in the 'server_list' for a TCP server, specifying communication type, host, port, and framer.
```json
{
"server_list": {
"server": {
"comm": "tcp",
"host": "0.0.0.0",
"port": 5020,
"framer": "socket",
}
}
"device_list": {
...
}
}
```
--------------------------------
### Default Actions for Registers
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Examples of configuring 'random' and 'increment' actions for registers, including optional minimum and maximum parameters. The 'increment' action resets to the minimum if the maximum is crossed.
```default
{"addr": 9, "value": 7, "action": "random", "parameters": {"minval": 0, "maxval": 12} },
{"addr": 10, "value": 100, "action": "increment", "parameters": {"minval": 50} }
```
--------------------------------
### Define Simulator Data Model
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/simulator/datamodel.md
This example demonstrates how to define register groups (SimData) and device configurations (SimDevice) for the pymodbus simulator. It covers different data types like BITS, REGISTERS, FLOAT32, INT64, and STRING, and shows instantiation with positional and optional parameters.
```python
# SimData can be instantiated with positional or optional parameters:
assert SimData(5, 10, 17, DataType.REGISTERS) == SimData(
address=5, values=17, count=10, datatype=DataType.REGISTERS
)
# Define a group of coils/discrete inputs non-shared (address=15..31 each 1 bit)
# block1 = SimData(address=15, count=16, values=True, datatype=DataType.BITS)
# Define a group of coils/discrete inputs shared (address=15..31 each 16 bit)
# block2 = SimData(address=15, count=16, values=0xFFFF, datatype=DataType.BITS)
# Define a group of holding/input registers (remark NO difference between shared and non-shared)
# block3 = SimData(10, 1, 123.4, datatype=DataType.FLOAT32)
# block4 = SimData(17, count=5, values=123, datatype=DataType.INT64)
block5 = SimData(1027, 1, "Hello ", datatype=DataType.STRING)
block_def = SimData(0, count=1000, datatype=DataType.REGISTERS)
# SimDevice can be instantiated with positional or optional parameters:
assert SimDevice(
5,
[block_def, block5],
) == SimDevice(id=5, simdata=[block_def, block5])
# SimDevice can define either a shared or a non-shared register model
SimDevice(id=1, simdata=[block_def, block5])
# SimDevice(2, False,
# block_coil=[block1],
# block_discrete=[block1],
# block_holding=[block2],
# block_input=[block3, block4])
# Remark: it is legal to reuse SimData, the object is only used for configuration,
# not for runtime.
# id=0 in a SimDevice act as a "catch all". Requests to an unknown id is executed in this SimDevice.
# SimDevice(0, block_shared=[block2])
```
--------------------------------
### Install pymodbus in editable mode for development
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Install the pymodbus library in editable mode using pip, along with development tools. This is recommended for making changes to the core library.
```bash
pip install -e ".[development]"
```
--------------------------------
### Convert ModbusSparseDataBlock to SimDevice
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/upgrade_40.md
This example demonstrates converting ModbusSparseDataBlock, which handles registers with missing addresses, to the SimData/SimDevice structure. Device ID 0 is a catch-all for undefined devices.
```python
dev = ModbusDeviceContext(
co=ModbusSparseDataBlock([1, 2, 3]),
di=ModbusSequentialDataBlock({
1: 6720,
30: 130
}),
hr=ModbusSparseDataBlock([4, 5, 6]),
ir=ModbusSparseDataBlock([7, 8, 9])
)
server_context = ModbusServerContext(
devices={1: dev,
0: dev
})
await StartAsync**Server(context=server_context)
```
```python
from pymodbus.simulator import SimData, SimDevice, DataType
devices = [SimDevice(1, simdata=(
SimData(1, values=[1,2,3], datatype=DataType.REGISTERS),
[SimData(1, values=6720, datatype=DataType.REGISTERS),
SimData(30, values=130, datatype=DataType.REGISTERS)
],
SimData(0x01, values=[4,5,6], datatype=DataType.REGISTERS),
SimData(0x01, values=[7,8,9], datatype=DataType.REGISTERS)
)
),
SimDevice(1, simdata=(
SimData(0x01, values=15, datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS),
SimData(0x01, values=[17], datatype=DataType.REGISTERS)
)
)
]
await StartAsync**Server(context=devices)
```
--------------------------------
### Install git hooks for pymodbus development
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Copy git hooks from the repository to the .git/hooks directory. These hooks help control commits and prevent errors during Pull Request submissions.
```bash
: cp githooks/* .git/hooks
```
--------------------------------
### Build HTML Documentation
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Navigate to the doc directory and run the build script to generate HTML documentation.
```bash
cd doc
./build_html
```
--------------------------------
### Install Old Pymodbus Release
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Install a specific older version of pymodbus using pip by specifying the version number.
```bash
pip install pymodbus==3.5.4
```
--------------------------------
### Set up a virtual environment for pymodbus development
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Create and activate a Python virtual environment after cloning the pymodbus repository. This isolates project dependencies.
```bash
cd pymodbus
python3 -m venv .venv
source .venv/bin/activate
```
--------------------------------
### Binary Framer Removal (3.7.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
The binary framer is no longer supported starting in version 3.7.0.
```text
binary framer no longer supported
```
--------------------------------
### Modbus Response Simulation Status
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/restapi.md
This is an example of a response from the simulation endpoint, indicating the active simulation state and configuration.
```json
{
"simulation_action": "ACTIVE",
"range_start": null,
"range_stop": null,
"function_codes": [
{
"value": 3,
"text": "read_holding_registers",
"selected": false
},
{
"value": 2,
"text": "read_discrete_input",
"selected": false
},
{
"value": 4,
"text": "read_input_registers",
"selected": false
},
{
"value": 1,
"text": "read_coils",
"selected": false
},
{
"value": 15,
"text": "write_coils",
"selected": false
},
{
"value": 16,
"text": "write_registers",
"selected": false
},
{
"value": 6,
"text": "write_register",
"selected": false
},
{
"value": 5,
"text": "write_coil",
"selected": false
},
{
"value": 23,
"text": "read_write_multiple_registers",
"selected": false
},
{
"value": 8,
"text": "diagnostic_status",
"selected": false
},
{
"value": 7,
"text": "read_exception_status",
"selected": false
},
{
"value": 11,
"text": "get_event_counter",
"selected": false
},
{
"value": 12,
"text": "get_event_log",
"selected": false
},
{
"value": 17,
"text": "report_device_id",
"selected": false
},
{
"value": 20,
"text": "read_file_record",
"selected": false
},
{
"value": 21,
"text": "write_file_record",
"selected": false
},
{
"value": 22,
"text": "mask_write_register",
"selected": false
},
{
"value": 24,
"text": "read_fifo_queue",
"selected": false
},
{
"value": 43,
"text": "read_device_information",
"selected": false
}
],
"function_show_hex_checked": false,
"function_show_decoded_checked": false,
"function_response_normal_checked": true,
"function_response_error_checked": false,
"function_response_empty_checked": false,
"function_response_junk_checked": false,
"function_response_split_checked": true,
"function_response_split_delay": 1,
"function_response_cr_checked": false,
"function_response_cr_pct": 0,
"function_response_delay": 0,
"function_response_junk": 0,
"function_error": [
{
"value": 1,
"text": "ILLEGAL_FUNCTION",
"selected": false
},
{
"value": 2,
```
--------------------------------
### TLS Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a TLS server with host, port, certificate, and key file paths. Requires 'certfile' and 'keyfile' for secure communication.
```json
{
"server_list": {
"server_try_tls": {
"comm": "tls",
"host": "0.0.0.0",
"port": 5020,
"certfile": "certificates/pymodbus_tls.crt",
"keyfile": "certificates/pymodbus_tls.key",
"ignore_missing_devices": false,
"framer": "tls",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
}
```
--------------------------------
### Server Parameter Changes (3.4.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Starting from version 3.4.0, several parameters are no longer accepted by Modbus server handlers.
```text
ModbueServer handler=, allow_reuse_addr=, backlog= are no longer accepted
ModbusTlsServer reqclicert= is no longer accepted
ModbusSerialServer auto_connect= is no longer accepted
```
--------------------------------
### Read/Write Registers Response
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/restapi.md
This is an example of a successful response when interacting with the registers endpoint. It includes the result, status, and details of the affected registers.
```json
{
"result": "ok",
"footer": "Operation completed successfully",
"register_types": {
"bits": 1,
"uint16": 2,
"uint32": 3,
"float32": 4,
"string": 5,
"next": 6,
"invalid": 0
},
"register_actions": {
"null": 0,
"increment": 1,
"random": 2,
"reset": 3,
"timestamp": 4,
"uptime": 5
},
"register_rows": [
{
"index": "16",
"type": "uint16",
"access": "True",
"action": "none",
"value": "3124",
"count_read": "0",
"count_write": "0"
}
]
}
```
--------------------------------
### Build and Upload Release to PyPI
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/MAKE_RELEASE.rst
After checking out a specific release tag, this command builds the distribution packages and uploads them to the Python Package Index (PyPI).
```bash
rm -rf build/* dist/*
python3 -m build
twine upload dist/*
```
--------------------------------
### Prepare for Pull Request
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Commands to switch to the development branch, pull the latest changes, and create a new feature branch for your pull request.
```bash
git checkout dev
git pull
git checkout -b feature
```
--------------------------------
### Removed Server Classes (3.4.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Version 3.4.0 removed `StartAsyncUnixServer` and `ModbusUnixServer` as they were not functional on Windows.
```text
StartAsyncUnixServer / ModbusUnixServer removed (never worked on Windows)
```
--------------------------------
### Simulator Server Serve Forever (3.4.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Version 3.4.0 adds the `only_start=False` parameter to `ModbusSimulatorServer.serve_forever()` to allow the method to return.
```text
ModbusSimulatorServer.serve_forever(only_start=False) added to allow return
```
--------------------------------
### UDP Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a UDP server with host, port, and framer settings. Suitable for UDP communication protocols.
```json
{
"server_list": {
"server_test_try_udp": {
"comm": "udp",
"host": "0.0.0.0",
"port": 5020,
"ignore_missing_devices": false,
"framer": "socket",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
}
```
--------------------------------
### Device Data Configuration - UInt32 and Float32
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure simulation data for 'uint32' and 'float32' registers. Allows specifying addresses as single numbers or lists, with optional actions.
```json
{
"device_list": {
"device": {
"uint32": [
{"addr": [4, 5], "value": 617001, "action": null},
[3037, 3038]
],
"float32": [
{"addr": [6, 7], "value": 404.17},
[4100, 4101]
]
}
}
}
```
--------------------------------
### Build Distribution Packages
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/MAKE_RELEASE.rst
Removes old build artifacts and then builds new source and wheel distribution packages for the project using the 'build' package.
```bash
rm -rf build/* dist/*
python3 -m build
```
--------------------------------
### UDP Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a UDP server with host and port. The framer is set to socket.
```json
{
"server_test_try_udp": {
"comm": "udp",
"host": "0.0.0.0",
"port": 5020,
"ignore_missing_devices": false,
"framer": "socket",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
}
```
--------------------------------
### Simple Asynchronous Modbus TCP Client
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/examples.md
Demonstrates connecting to a Modbus TCP server, reading coils and holding registers, and converting register data to an integer. Ensure a Modbus server is running before execution.
```python
#!/usr/bin/env python3
"""Pymodbus asynchronous client example.
An example of a single threaded synchronous client.
usage: simple_async_client.py
All options must be adapted in the code
The corresponding server must be started before e.g. as:
python3 server_sync.py
"""
import asyncio
import pymodbus.client as ModbusClient
from pymodbus import (
FramerType,
ModbusException,
pymodbus_apply_logging_config,
)
async def run_async_simple_client(comm, host, port, framer=FramerType.SOCKET):
"""Run async client."""
# activate debugging
pymodbus_apply_logging_config("DEBUG")
print("get client")
client: ModbusClient.ModbusBaseClient
if comm == "tcp":
client = ModbusClient.AsyncModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.AsyncModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# source_address=None,
)
elif comm == "serial": # pragma: no cover
client = ModbusClient.AsyncModbusSerialClient(
port,
framer=framer,
# timeout=10,
# retries=3,
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
# handle_local_echo=False,
)
else: # pragma: no cover
print(f"Unknown client {comm} selected")
return
print("connect to server")
await client.connect()
# test client is connected
assert client.connected
print("get and verify data")
try:
# See all calls in client_calls.py
rr = await client.read_coils(1, count=1, device_id=1)
except ModbusException as exc: # pragma: no cover
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError(): # pragma: no cover
print(f"Received exception from device ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
return
try:
# See all calls in client_calls.py
rr = await client.read_holding_registers(10, count=2, device_id=1)
except ModbusException as exc: # pragma: no cover
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError(): # pragma: no cover
print(f"Received exception from device ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
return
value_int32 = client.convert_from_registers(
rr.registers,
data_type=client.DATATYPE.INT32
)
print(f"Got int32: {value_int32}")
print("close connection")
client.close()
if __name__ == "__main__":
asyncio.run(run_async_simple_client("tcp", "127.0.0.1", 5020), debug=True)
```
--------------------------------
### TCP Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a TCP server with host, port, and framer settings. Includes identity details for the server.
```json
{
"server_list": {
"server": {
"comm": "tcp",
"host": "0.0.0.0",
"port": 5020,
"ignore_missing_devices": false,
"framer": "socket",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
}
```
--------------------------------
### Device Data Configuration - Bits and UInt16
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure simulation data for 'bits' and 'uint16' registers. Supports single values and lists of values with optional actions.
```json
{
"device_list": {
"device": {
"invalid": [
1
],
"write": [
3
],
"bits": [
{"addr": 2, "value": 7}
],
"uint16": [
{"addr": 3, "value": 17001, "action": null},
2100
]
}
}
}
```
--------------------------------
### Check Distribution Packages
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/MAKE_RELEASE.rst
Verifies the integrity and metadata of the built distribution packages before uploading them to PyPI.
```bash
twine check dist/*
```
--------------------------------
### TLS Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a TLS server specifying certificate and key files. This ensures secure communication.
```json
{
"server_try_tls": {
"comm": "tls",
"host": "0.0.0.0",
"port": 5020,
"certfile": "certificates/pymodbus_tls.crt",
"keyfile": "certificates/pymodbus_tls.key",
"ignore_missing_devices": false,
"framer": "tls",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
```
--------------------------------
### Default Device Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
This snippet shows the default configuration for a device, including register sizes and default values for different data types.
```json
{
"server_list": {
...
},
"device_list": {
"device": {
"setup": {
"co size": 63000,
"di size": 63000,
"hr size": 63000,
"ir size": 63000,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": "register",
"uint32": "register",
"float32": "register",
"string": null
}
}
},
"invalid": [
1
],
"write": [
5
],
"bits": [
{"addr": 2, "value": 7}
],
"uint16": [
{"addr": 3, "value": 17001},
2100
],
"uint32": [
{"addr": 4, "value": 617001},
[3037, 3038]
],
"float32": [
{"addr": 6, "value": 404.17},
[4100, 4101]
],
"string": [
5047,
{"addr": [16, 20], "value": "A_B_C_D_E_"}
],
"repeat": [
]
},
"device_try": {
"setup": {
"co size": 63000,
"di size": 63000,
"hr size": 63000,
"ir size": 63000,
"shared blocks": true,
"type exception": true,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": "register",
"uint32": "register",
"float32": "register",
"string": null
}
}
},
"invalid": [
[0, 5],
77
],
"write": [
10,
[61, 76]
],
"bits": [
10,
1009,
[1116, 1119],
{"addr": 1144, "value": 1},
{"addr": [1148,1149], "value": 32117},
{"addr": [1208, 1306], "action": "random"}
],
"uint16": [
11,
2027,
[2126, 2129],
{"addr": 2164, "value": 1},
{"addr": [2168,2169], "value": 32117},
{"addr": [2208, 2306], "action": null}
],
"uint32": [
12,
3037,
[3136, 3139],
{"addr": 3174, "value": 1},
{"addr": [3188,3189], "value": 32514},
{"addr": [3308, 3406], "action": null},
{"addr": [3688, 3878], "value": 115, "action": "increment"}
],
"float32": [
14,
4047,
[4146, 4149],
{"addr": 4184, "value": 1},
{"addr": [4198,4191], "value": 32514.1},
{"addr": [4308, 4406], "action": null},
{"addr": [4688, 4878], "value": 115.7, "action": "increment"}
],
"string": [
{"addr": [16, 20], "value": "A_B_C_D_E_"},
5047,
[5146, 5149],
{"addr": [529, 544], "value": "Brand name, 32 bytes...........X"}
],
"repeat": [
{"addr": [0, 999], "to": [10000, 10999]},
{"addr": [10, 1999], "to": [11000, 11999]}
]
}
},
"device_minimum": {
"setup": {
"co size": 10,
"di size": 10,
"hr size": 10,
"ir size": 10,
"shared blocks": true,
"type exception": false,
"defaults": {
"value": {
"bits": 0,
"uint16": 0,
"uint32": 0,
"float32": 0.0,
"string": " "
},
"action": {
"bits": null,
"uint16": null,
"uint32": null,
"float32": null,
```
--------------------------------
### Generate Coverage Report
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Run tests with coverage enabled to generate an HTML report in the build/html directory.
```bash
pytest --cov
```
--------------------------------
### Checkout the development branch from GitHub
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/index.md
Switch to the 'dev' branch of the pymodbus repository to access the latest development code. Use with caution as it may be unstable.
```bash
git checkout dev
```
--------------------------------
### Serial Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a serial server with port, baud rate, parity, and framer settings. Supports serial-specific parameters like stopbits and bytesize.
```json
{
"server_list": {
"server_try_serial": {
"comm": "serial",
"port": "/dev/tty0",
"stopbits": 1,
"bytesize": 8,
"parity": "N",
"baudrate": 9600,
"timeout": 3,
"reconnect_delay": 2,
"framer": "rtu",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
}
```
--------------------------------
### Basic JSON Configuration Layout
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
This is the fundamental structure for a pymodbus simulator configuration file, defining lists for servers and devices.
```json
{
"server_list": {
"": { ... },
...
},
"device_list": {
"": { ... },
...
}
}
```
--------------------------------
### Run Tests
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Execute the test suite for Pymodbus. This command also generates coverage files.
```bash
cd test
pytest
```
--------------------------------
### Generate Profile Report
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/README.rst
Run tests with profiling enabled to generate a call profile report.
```bash
pytest --profile
```
--------------------------------
### Datastore Method Removal (3.13.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
In version 3.13.0, `datastore.get/setValues` have been removed. Use `server.async_get/setValues` instead.
```text
datastore get/setValues is removed,
please use server.async_get/setValues instead.
```
--------------------------------
### Serial Server Configuration
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/library/simulator/config.md
Configure a serial server with communication parameters like port, baudrate, and parity. The framer is set to RTU.
```json
{
"server_try_serial": {
"comm": "serial",
"port": "/dev/tty0",
"stopbits": 1,
"bytesize": 8,
"parity": "N",
"baudrate": 9600,
"timeout": 3,
"reconnect_delay": 2,
"framer": "rtu",
"identity": {
"VendorName": "pymodbus",
"ProductCode": "PM",
"VendorUrl": "https://github.com/pymodbus-dev/pymodbus",
"ProductName": "pymodbus Server",
"ModelName": "pymodbus Server",
"MajorMinorRevision": "3.1.0"
}
}
}
```
--------------------------------
### TLS Client SSL Generation (3.7.0)
Source: https://github.com/pymodbus-dev/pymodbus/blob/dev/doc/source/api_changes.md
Introduces the class method generate_ssl() for TLS clients (sync/async) in version 3.7.0, replacing direct certfile, keyfile, and password parameters.
```text
class method generate_ssl() added to TLS client (sync/async).
removed certfile, keyfile, password from TLS client, please use generate_ssl()
```