Examples
Examples are divided in 2 parts:
The first part are some simple client examples which can be copied and run directly. These examples show the basic functionality of the library.
The second part are more advanced examples, but in order to not duplicate code, this requires you to download the examples directory and run the examples in the directory.
Ready to run examples:
These examples are very basic examples, showing how a client can communicate with a server.
You need to modify the code to adapt it to your situation.
Simple asynchronous client
Source: examples/simple_async_client.py
#!/usr/bin/env python3
"""Pymodbus asynchronous client example.
An example of a single threaded synchronous client.
usage: simple_client_async.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 (
ExceptionResponse,
Framer,
ModbusException,
pymodbus_apply_logging_config,
)
async def run_async_simple_client(comm, host, port, framer=Framer.SOCKET):
"""Run async client."""
# activate debugging
pymodbus_apply_logging_config("DEBUG")
print("get client")
if comm == "tcp":
client = ModbusClient.AsyncModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.AsyncModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# source_address=None,
)
elif comm == "serial":
client = ModbusClient.AsyncModbusSerialClient(
port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
# handle_local_echo=False,
)
elif comm == "tls":
client = ModbusClient.AsyncModbusTlsClient(
host,
port=port,
framer=Framer.TLS,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# sslctx=sslctx,
certfile="../examples/certificates/pymodbus.crt",
keyfile="../examples/certificates/pymodbus.key",
# password="none",
server_hostname="localhost",
)
else:
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, 1, slave=1)
except ModbusException as exc:
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError():
print(f"Received Modbus library error({rr})")
client.close()
return
if isinstance(rr, ExceptionResponse):
print(f"Received Modbus library exception ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
print("close connection")
client.close()
if __name__ == "__main__":
asyncio.run(
run_async_simple_client("tcp", "127.0.0.1", 5020), debug=True
)
Simple synchronous client
Source: examples/simple_sync_client.py
#!/usr/bin/env python3
"""Pymodbus synchronous client example.
An example of a single threaded synchronous client.
usage: simple_client_async.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 (
ExceptionResponse,
Framer,
ModbusException,
pymodbus_apply_logging_config,
)
def run_sync_simple_client(comm, host, port, framer=Framer.SOCKET):
"""Run sync client."""
# activate debugging
pymodbus_apply_logging_config("DEBUG")
print("get client")
if comm == "tcp":
client = ModbusClient.ModbusTcpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,y
# close_comm_on_error=False,
# strict=True,
# source_address=("localhost", 0),
)
elif comm == "udp":
client = ModbusClient.ModbusUdpClient(
host,
port=port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# source_address=None,
)
elif comm == "serial":
client = ModbusClient.ModbusSerialClient(
port,
framer=framer,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,.
# strict=True,
baudrate=9600,
bytesize=8,
parity="N",
stopbits=1,
# handle_local_echo=False,
)
elif comm == "tls":
client = ModbusClient.ModbusTlsClient(
host,
port=port,
framer=Framer.TLS,
# timeout=10,
# retries=3,
# retry_on_empty=False,
# close_comm_on_error=False,
# strict=True,
# sslctx=None,
certfile="../examples/certificates/pymodbus.crt",
keyfile="../examples/certificates/pymodbus.key",
# password=None,
server_hostname="localhost",
)
else:
print(f"Unknown client {comm} selected")
return
print("connect to server")
client.connect()
print("get and verify data")
try:
rr = client.read_coils(1, 1, slave=1)
except ModbusException as exc:
print(f"Received ModbusException({exc}) from library")
client.close()
return
if rr.isError():
print(f"Received Modbus library error({rr})")
client.close()
return
if isinstance(rr, ExceptionResponse):
print(f"Received Modbus library exception ({rr})")
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
client.close()
print("close connection")
client.close()
if __name__ == "__main__":
run_sync_simple_client("tcp", "127.0.0.1", "5020")
Client performance sync vs async
Source: examples/client_performance.py
#!/usr/bin/env python3
"""Test performance of client: sync vs. async.
This example show how much faster the async version is.
example run:
(pymodbus) % ./client_performance.py
--- Testing sync client v3.4.1
running 1000 call (each 10 registers), took 114.10 seconds
Averages 114.10 ms pr call and 11.41 ms pr register.
--- Testing async client v3.4.1
running 1000 call (each 10 registers), took 0.33 seconds
Averages 0.33 ms pr call and 0.03 ms pr register.
"""
import asyncio
import time
from pymodbus import Framer
from pymodbus.client import AsyncModbusSerialClient, ModbusSerialClient
LOOP_COUNT = 1000
REGISTER_COUNT = 10
def run_sync_client_test():
"""Run sync client."""
print("--- Testing sync client v3.4.1")
client = ModbusSerialClient(
"/dev/ttys007",
framer_name=Framer.RTU,
baudrate=9600,
)
client.connect()
assert client.connected
start_time = time.time()
for _i in range(LOOP_COUNT):
rr = client.read_input_registers(1, REGISTER_COUNT, slave=1)
if rr.isError():
print(f"Received Modbus library error({rr})")
break
client.close()
run_time = time.time() - start_time
avg_call = (run_time / LOOP_COUNT) * 1000
avg_register = avg_call / REGISTER_COUNT
print(
f"running {LOOP_COUNT} call (each {REGISTER_COUNT} registers), took {run_time:.2f} seconds"
)
print(f"Averages {avg_call:.2f} ms pr call and {avg_register:.2f} ms pr register.")
async def run_async_client_test():
"""Run async client."""
print("--- Testing async client v3.4.1")
client = AsyncModbusSerialClient(
"/dev/ttys007",
framer_name=Framer.RTU,
baudrate=9600,
)
await client.connect()
assert client.connected
start_time = time.time()
for _i in range(LOOP_COUNT):
rr = await client.read_input_registers(1, REGISTER_COUNT, slave=1)
if rr.isError():
print(f"Received Modbus library error({rr})")
break
client.close()
run_time = time.time() - start_time
avg_call = (run_time / LOOP_COUNT) * 1000
avg_register = avg_call / REGISTER_COUNT
print(
f"running {LOOP_COUNT} call (each {REGISTER_COUNT} registers), took {run_time:.2f} seconds"
)
print(f"Averages {avg_call:.2f} ms pr call and {avg_register:.2f} ms pr register.")
if __name__ == "__main__":
run_sync_client_test()
asyncio.run(run_async_client_test())
Advanced examples
These examples are considered essential usage examples, and are guaranteed to work, because they are tested automatilly with each dev branch commit using CI.
Tip
The examples needs to be run from within the examples directory, unless you modify them. Most examples use helper.py and client_*.py or server_*.py. This is done to avoid maintaining the same code in multiple files.
Client asynchronous calls
Source: examples/client_async_calls.py
Pymodbus Client modbus async all calls example.
Please see method async_template_call for a template on how to make modbus calls and check for different error conditions.
The handle* functions each handle a set of modbus calls with the same register type (e.g. coils).
All available modbus calls are present.
If you are performing a request that is not available in the client mixin, you have to perform the request like this instead:
from pymodbus.diag_message import ClearCountersRequest
from pymodbus.diag_message import ClearCountersResponse
request = ClearCountersRequest()
response = client.execute(request)
if isinstance(response, ClearCountersResponse):
... do something with the response
This example uses client_async.py and client_sync.py to handle connection, and have the same options.
The corresponding server must be started before e.g. as:
./server_async.py
Client asynchronous
Source: examples/client_async.py
Pymodbus asynchronous client example.
usage:
client_async.py [-h] [-c {tcp,udp,serial,tls}]
[-f {ascii,binary,rtu,socket,tls}]
[-l {critical,error,warning,info,debug}] [-p PORT]
[--baudrate BAUDRATE] [--host HOST]
-h, --help
show this help message and exit
-c, -comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
--baudrate BAUDRATE
set serial device baud rate
--host HOST
set host, default is 127.0.0.1
- The corresponding server must be started before e.g. as:
python3 server_sync.py
Client calls
Source: examples/client_calls.py
Pymodbus Client modbus all calls example.
Please see method template_call for a template on how to make modbus calls and check for different error conditions.
The handle* functions each handle a set of modbus calls with the same register type (e.g. coils).
All available modbus calls are present.
If you are performing a request that is not available in the client mixin, you have to perform the request like this instead:
from pymodbus.diag_message import ClearCountersRequest
from pymodbus.diag_message import ClearCountersResponse
request = ClearCountersRequest()
response = client.execute(request)
if isinstance(response, ClearCountersResponse):
... do something with the response
This example uses client_async.py and client_sync.py to handle connection, and have the same options.
The corresponding server must be started before e.g. as:
./server_async.py
Client custom message
Source: examples/client_custom_msg.py
Pymodbus Synchronous Client Examples.
The following is an example of how to use the synchronous modbus client implementation from pymodbus:
with ModbusClient("127.0.0.1") as client:
result = client.read_coils(1,10)
print result
Client payload
Source: examples/client_payload.py
Pymodbus Client Payload Example.
This example shows how to build a client with a complicated memory layout using builder.
Works out of the box together with payload_server.py
Client synchronous
Source: examples/client_sync.py
Pymodbus Synchronous Client Example.
An example of a single threaded synchronous client.
usage:
client_sync.py [-h] [-c {tcp,udp,serial,tls}]
[-f {ascii,binary,rtu,socket,tls}]
[-l {critical,error,warning,info,debug}] [-p PORT]
[--baudrate BAUDRATE] [--host HOST]
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
--baudrate BAUDRATE
set serial device baud rate
--host HOST
set host, default is 127.0.0.1
The corresponding server must be started before e.g. as:
python3 server_sync.py
Server asynchronous
Source: examples/server_async.py
Pymodbus asynchronous Server Example.
An example of a multi threaded asynchronous server.
usage:
server_async.py [-h] [--comm {tcp,udp,serial,tls}]
[--framer {ascii,binary,rtu,socket,tls}]
[--log {critical,error,warning,info,debug}]
[--port PORT] [--store {sequential,sparse,factory,none}]
[--slaves SLAVES]
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--slaves SLAVES
set number of slaves to respond to
The corresponding client can be started as:
python3 client_sync.py
Server callback
Source: examples/server_callback.py
Pymodbus Server With Callbacks.
This is an example of adding callbacks to a running modbus server when a value is written to it.
Server tracer
Source: examples/server_hook.py
Pymodbus Server With request/response manipulator.
This is an example of using the builtin request/response tracer to manipulate the messages to/from the modbus server
Server payload
Source: examples/server_payload.py
Pymodbus Server Payload Example.
This example shows how to initialize a server with a complicated memory layout using builder.
Server synchronous
Source: examples/server_sync.py
Pymodbus Synchronous Server Example.
An example of a single threaded synchronous server.
usage:
server_sync.py [-h] [--comm {tcp,udp,serial,tls}]
[--framer {ascii,binary,rtu,socket,tls}]
[--log {critical,error,warning,info,debug}]
[--port PORT] [--store {sequential,sparse,factory,none}]
[--slaves SLAVES]
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--slaves SLAVES
set number of slaves to respond to
- The corresponding client can be started as:
python3 client_sync.py
REMARK It is recommended to use the async server! The sync server is just a thin cover on top of the async server and is in some aspects a lot slower.
Server updating
Source: examples/server_updating.py
Pymodbus asynchronous Server with updating task Example.
An example of an asynchronous server and a task that runs continuously alongside the server and updates values.
usage:
server_updating.py [-h] [--comm {tcp,udp,serial,tls}]
[--framer {ascii,binary,rtu,socket,tls}]
[--log {critical,error,warning,info,debug}]
[--port PORT] [--store {sequential,sparse,factory,none}]
[--slaves SLAVES]
-h, --help
show this help message and exit
-c, --comm {tcp,udp,serial,tls}
set communication, default is tcp
-f, --framer {ascii,binary,rtu,socket,tls}
set framer, default depends on --comm
-l, --log {critical,error,warning,info,debug}
set log level, default is info
-p, --port PORT
set port
set serial device baud rate
--store {sequential,sparse,factory,none}
set datastore type
--slaves SLAVES
set number of slaves to respond to
- The corresponding client can be started as:
python3 client_sync.py
Simulator example
Source: examples/simulator.py
Pymodbus simulator server/client Example.
An example of how to use the simulator (server) with a client.
for usage see documentation of simulator
Tip
pymodbus.simulator starts the server directly from the commandline
Message generator
Source: examples/message_generator.py
Modbus Message Generator.
Message Parser
Source: examples/message_parser.py
Modbus Message Parser.
The following is an example of how to parse modbus messages using the supplied framers.
Modbus forwarder
Source: examples/modbus_forwarder.py
Pymodbus synchronous forwarder.
This is a repeater or converter and an example of just how powerful datastore is.
It consist of a server (any comm) and a client (any comm), functionality:
server receives a read/write request from external client:
client sends a new read/write request to target server
client receives response and updates the datastore
server sends new response to external client
Both server and client are tcp based, but it can be easily modified to any server/client (see client_sync.py and server_sync.py for other communication types)
WARNING This example is a simple solution, that do only forward read requests.
Examples contributions
These examples are supplied by users of pymodbus. The pymodbus team thanks for sharing the examples.
Solar
Source: examples/contrib/solar.py
Pymodbus Synchronous Client Example.
Modified to test long term connection.
Redis datastore
Source: examples/contrib/redis_datastore.py
Datastore using redis.
Serial Forwarder
Source: examples/contrib/serial_forwarder.py
Pymodbus SerialRTU2TCP Forwarder
usage : python3 serial_forwarder.py –log DEBUG –port “/dev/ttyUSB0” –baudrate 9600 –server_ip “192.168.1.27” –server_port 5020 –slaves 1 2 3
Sqlalchemy datastore
Source: examples/contrib/sql_datastore.py
Datastore using SQL.