Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/source/library/pymodbus.client.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@


================
pymodbus\.client
================
Expand Down
34 changes: 24 additions & 10 deletions doc/source/library/pymodbus.server.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
================
pymodbus\.server
================

Pymodbus offers servers with transport protocols for

- *Serial* (RS-485) typically using a dongle
- *TCP*
- *TLS*
- *UDP*
- possibility to add a custom transport protocol

communication in 2 versions:

- :mod:`synchronous server`,
- :mod:`asynchronous server` using asyncio.

*Remark* All servers are implemented with asyncio, and the
synchronous servers are just an interface layer allowing synchronous
applications to use the server as if it was synchronous.


pymodbus\.server package
========================

Expand All @@ -9,18 +31,10 @@ pymodbus\.server package
Submodules
----------

pymodbus\.server\.asynchronous module
-------------------------------------
pymodbus\.server module
-----------------------

.. automodule:: pymodbus.server.async_io
:members:
:undoc-members:
:show-inheritance:

pymodbus\.server\.sync module
-----------------------------

.. automodule:: pymodbus.server.sync
:members:
:undoc-members:
:show-inheritance:
10 changes: 5 additions & 5 deletions examples/client_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@
)


def setup_client(args=None):
def setup_async_client(args=None):
"""Run client setup."""
if not args:
args = get_commandline()
if args.comm != "serial":
if args.comm != "serial" and args.port:
args.port = int(args.port)
_logger.info("### Create client object")

Expand Down Expand Up @@ -116,7 +116,7 @@ def setup_client(args=None):
return client


async def run_client(client, modbus_calls=None):
async def run_async_client(client, modbus_calls=None):
"""Run sync client."""
_logger.info("### Client starting")
await client.connect()
Expand Down Expand Up @@ -191,5 +191,5 @@ def get_commandline():

if __name__ == "__main__":
# Connect/disconnect no calls.
testclient = setup_client()
asyncio.run(run_client(testclient))
testclient = setup_async_client()
asyncio.run(run_async_client(testclient))
32 changes: 20 additions & 12 deletions examples/client_async_basic_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
python3 server_sync.py
"""
import asyncio
import logging

from examples.client_async import _logger, run_client, setup_client
from examples.client_async import run_async_client, setup_async_client


SLAVE = 0x01


async def handle_coils(client):
async def _handle_coils(client):
"""Read/Write coils."""
_logger.info("### Reading Coil")
rr = await client.read_coils(1, 1, slave=SLAVE)
Expand Down Expand Up @@ -58,7 +59,7 @@ async def handle_coils(client):
_logger.debug(txt)


async def handle_discrete_input(client):
async def _handle_discrete_input(client):
"""Read discrete inputs."""
_logger.info("### Reading discrete input, Read address:0-7")
rr = await client.read_discrete_inputs(0, 8, slave=SLAVE)
Expand All @@ -67,7 +68,7 @@ async def handle_discrete_input(client):
_logger.debug(txt)


async def handle_holding_registers(client):
async def _handle_holding_registers(client):
"""Read/write holding registers."""
_logger.info("### write holding register and read holding registers")
rq = await client.write_register(1, 10, slave=SLAVE)
Expand Down Expand Up @@ -101,7 +102,7 @@ async def handle_holding_registers(client):
_logger.debug(txt)


async def handle_input_registers(client):
async def _handle_input_registers(client):
"""Read input registers."""
_logger.info("### read input registers")
rr = await client.read_input_registers(1, 8, slave=SLAVE)
Expand All @@ -110,14 +111,21 @@ async def handle_input_registers(client):
_logger.debug(txt)


async def demonstrate_calls(client):
async def run_async_basic_calls(client):
"""Demonstrate basic read/write calls."""
await handle_coils(client)
await handle_discrete_input(client)
await handle_holding_registers(client)
await handle_input_registers(client)
await _handle_coils(client)
await _handle_discrete_input(client)
await _handle_holding_registers(client)
await _handle_input_registers(client)

# --------------------------------------------------------------------------- #
# Extra code, to allow commandline parameters instead of changing the code
# --------------------------------------------------------------------------- #
FORMAT = "%(asctime)-15s %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
logging.basicConfig(format=FORMAT)
_logger = logging.getLogger()


if __name__ == "__main__":
testclient = setup_client()
asyncio.run(run_client(testclient, modbus_calls=demonstrate_calls))
testclient = setup_async_client()
asyncio.run(run_async_client(testclient, modbus_calls=run_async_basic_calls))
24 changes: 16 additions & 8 deletions examples/client_async_extended_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@
python3 server_sync.py
"""
import asyncio
import logging

from examples.client_async import _logger, run_client, setup_client
from examples.client_async import run_async_client, setup_async_client

from pymodbus.diag_message import (
ChangeAsciiInputDelimiterRequest,
Expand Down Expand Up @@ -56,7 +57,7 @@
UNIT = 0x01


async def execute_information_requests(client):
async def _execute_information_requests(client):
"""Execute extended information requests."""
_logger.info("### Running ReadDeviceInformationRequest")
rr = await client.execute(ReadDeviceInformationRequest(unit=UNIT))
Expand Down Expand Up @@ -87,7 +88,7 @@ async def execute_information_requests(client):
assert not rr.events # test the number of events


async def execute_diagnostic_requests(client):
async def _execute_diagnostic_requests(client):
"""Execute extended diagnostic requests."""
_logger.info("### Running ReturnQueryDataRequest")
rr = await client.execute(ReturnQueryDataRequest(unit=UNIT))
Expand Down Expand Up @@ -160,12 +161,19 @@ async def execute_diagnostic_requests(client):
assert rr and not rr.isError() # test that calls was OK


async def demonstrate_calls(client):
async def run_async_ext_calls(client):
"""Demonstrate basic read/write calls."""
await execute_information_requests(client)
await execute_diagnostic_requests(client)
await _execute_information_requests(client)
await _execute_diagnostic_requests(client)

# --------------------------------------------------------------------------- #
# Extra code, to allow commandline parameters instead of changing the code
# --------------------------------------------------------------------------- #
FORMAT = "%(asctime)-15s %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
logging.basicConfig(format=FORMAT)
_logger = logging.getLogger()


if __name__ == "__main__":
testclient = setup_client()
asyncio.run(run_client(testclient, modbus_calls=demonstrate_calls))
testclient = setup_async_client()
asyncio.run(run_async_client(testclient, modbus_calls=run_async_ext_calls))
10 changes: 5 additions & 5 deletions examples/client_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@
)


def setup_client(args=None):
def setup_sync_client(args=None):
"""Run client setup."""
if not args:
args = get_commandline()
if args.comm != "serial":
if args.comm != "serial" and args.port:
args.port = int(args.port)
_logger.info("### Create client object")
if args.comm == "tcp":
Expand Down Expand Up @@ -114,7 +114,7 @@ def setup_client(args=None):
return client


def run_client(client, modbus_calls=None):
def run_sync_client(client, modbus_calls=None):
"""Run sync client."""
_logger.info("### Client starting")
client.connect()
Expand Down Expand Up @@ -188,5 +188,5 @@ def get_commandline():

if __name__ == "__main__":
# Connect/disconnect no calls.
testclient = setup_client()
run_client(testclient)
testclient = setup_sync_client()
run_sync_client(testclient)
34 changes: 22 additions & 12 deletions examples/client_sync_basic_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
The corresponding server must be started before e.g. as:
python3 server_sync.py
"""
from examples.client_sync import _logger, run_client, setup_client
import logging

from examples.client_sync import run_sync_client, setup_sync_client


SLAVE = 0x01


def handle_coils(client):
def _handle_coils(client):
"""Read/Write coils."""
_logger.info("### Reading Coil")
rr = client.read_coils(1, 1, slave=SLAVE)
Expand Down Expand Up @@ -56,7 +58,7 @@ def handle_coils(client):
_logger.debug(txt)


def handle_discrete_input(client):
def _handle_discrete_input(client):
"""Read discrete inputs."""
_logger.info("### Reading discrete input, Read address:0-7")
rr = client.read_discrete_inputs(0, 8, slave=SLAVE)
Expand All @@ -65,7 +67,7 @@ def handle_discrete_input(client):
_logger.debug(txt)


def handle_holding_registers(client):
def _handle_holding_registers(client):
"""Read/write holding registers."""
_logger.info("### write holding register and read holding registers")
rq = client.write_register(1, 10, slave=SLAVE)
Expand Down Expand Up @@ -99,7 +101,7 @@ def handle_holding_registers(client):
_logger.debug(txt)


def handle_input_registers(client):
def _handle_input_registers(client):
"""Read input registers."""
_logger.info("### read input registers")
rr = client.read_input_registers(1, 8, slave=SLAVE)
Expand All @@ -108,14 +110,22 @@ def handle_input_registers(client):
_logger.debug(txt)


def demonstrate_calls(client):
def run_sync_basic_calls(client):
"""Demonstrate basic read/write calls."""
handle_coils(client)
handle_discrete_input(client)
handle_holding_registers(client)
handle_input_registers(client)
_handle_coils(client)
_handle_discrete_input(client)
_handle_holding_registers(client)
_handle_input_registers(client)


# --------------------------------------------------------------------------- #
# Extra code, to allow commandline parameters instead of changing the code
# --------------------------------------------------------------------------- #
FORMAT = "%(asctime)-15s %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
logging.basicConfig(format=FORMAT)
_logger = logging.getLogger()


if __name__ == "__main__":
testclient = setup_client()
run_client(testclient, modbus_calls=demonstrate_calls)
testclient = setup_sync_client()
run_sync_client(testclient, modbus_calls=run_sync_basic_calls)
26 changes: 18 additions & 8 deletions examples/client_sync_extended_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
The corresponding server must be started before e.g. as:
python3 server_sync.py
"""
from examples.client_sync import _logger, run_client, setup_client
import logging

from examples.client_sync import run_sync_client, setup_sync_client

from pymodbus.diag_message import (
ChangeAsciiInputDelimiterRequest,
Expand Down Expand Up @@ -54,7 +56,7 @@
UNIT = 0x01


def execute_information_requests(client):
def _execute_information_requests(client):
"""Execute extended information requests."""
_logger.info("### Running ReadDeviceInformationRequest")
rr = client.execute(ReadDeviceInformationRequest(unit=UNIT))
Expand Down Expand Up @@ -85,7 +87,7 @@ def execute_information_requests(client):
assert not rr.events # test the number of events


def execute_diagnostic_requests(client):
def _execute_diagnostic_requests(client):
"""Execute extended diagnostic requests."""
_logger.info("### Running ReturnQueryDataRequest")
rr = client.execute(ReturnQueryDataRequest(unit=UNIT))
Expand Down Expand Up @@ -158,12 +160,20 @@ def execute_diagnostic_requests(client):
assert rr and not rr.isError() # test that calls was OK


def demonstrate_calls(client):
def run_sync_ext_calls(client):
"""Demonstrate basic read/write calls."""
execute_information_requests(client)
execute_diagnostic_requests(client)
_execute_information_requests(client)
_execute_diagnostic_requests(client)


# --------------------------------------------------------------------------- #
# Extra code, to allow commandline parameters instead of changing the code
# --------------------------------------------------------------------------- #
FORMAT = "%(asctime)-15s %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s"
logging.basicConfig(format=FORMAT)
_logger = logging.getLogger()


if __name__ == "__main__":
testclient = setup_client()
run_client(testclient, modbus_calls=demonstrate_calls)
testclient = setup_sync_client()
run_sync_client(testclient, modbus_calls=run_sync_ext_calls)
2 changes: 1 addition & 1 deletion examples/common/callback_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
ModbusSparseDataBlock,
)
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.server.async_io import StartTcpServer
from pymodbus.server import StartTcpServer

# --------------------------------------------------------------------------- #
# import the modbus libraries we need
Expand Down
2 changes: 1 addition & 1 deletion examples/common/custom_datablock.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
ModbusSparseDataBlock,
)
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.server.async_io import StartTcpServer
from pymodbus.server import StartTcpServer

# --------------------------------------------------------------------------- #
# import the modbus libraries we need
Expand Down
2 changes: 1 addition & 1 deletion examples/common/custom_synchronous_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def decode(self, data):
ModbusSlaveContext,
)
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.server.sync import StartTcpServer
from pymodbus.server import StartTcpServer
from pymodbus.version import version


Expand Down
Loading