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
12 changes: 0 additions & 12 deletions doc/source/library/pymodbus.client.calls.rst

This file was deleted.

61 changes: 57 additions & 4 deletions doc/source/library/pymodbus.client.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
================
pymodbus\.client
================

Expand Down Expand Up @@ -37,11 +38,63 @@ or asynchronous example::
# disconnect device
await async_client.close()

Pymodbus offers Serial/TCP/TLS/UDP as transport protocols, with the option to add
custom protocols. Each transport protocol is implemented as
a :mod:`synchronous client` and a :mod:`asynchronous client`

Large parts of the actual implementation are shared between the different classes,
to ensure a higher stability and more efficient maintenance.

Client setup.
-------------

Common parameters/methods.
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: pymodbus.client.base.ModbusBaseClient
:members:
:member-order: bysource

Serial RS-485 transport.
~~~~~~~~~~~~~~~~~~~~~~~~

.. autoclass:: pymodbus.client.async_serial.AsyncModbusSerialClient

.. autoclass:: pymodbus.client.sync_serial.ModbusSerialClient

TCP transport.
~~~~~~~~~~~~~~

.. autoclass:: pymodbus.client.async_tcp.AsyncModbusTcpClient

.. autoclass:: pymodbus.client.sync_tcp.ModbusTcpClient

TLS transport.
~~~~~~~~~~~~~~

.. autoclass:: pymodbus.client.async_tls.AsyncModbusTlsClient

.. autoclass:: pymodbus.client.sync_tls.ModbusTlsClient

UDP transport.
~~~~~~~~~~~~~~

.. autoclass:: pymodbus.client.async_udp.AsyncModbusUdpClient
:members:

.. autoclass:: pymodbus.client.sync_udp.ModbusUdpClient
:members:


Client device calls.
--------------------

.. toctree::
Pymodbus makes a all standard modbus requests/responses available as simple calls.

pymodbus.client.setup
All calls are available as synchronous and asynchronous (asyncio based).

.. toctree::
Using Modbus<transport>Client.register() custom messagees can be added to pymodbus,
and handled automatically.

pymodbus.client.calls
.. autoclass:: pymodbus.client.mixin.ModbusClientMixin
:members:
63 changes: 0 additions & 63 deletions doc/source/library/pymodbus.client.setup.rst

This file was deleted.

3 changes: 1 addition & 2 deletions doc/source/library/pymodbus.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Subpackages
-----------

.. toctree::
:maxdepth: 4

pymodbus.client
pymodbus.constants
Expand Down Expand Up @@ -166,5 +167,3 @@ pymodbus\.version module
:members:
:undoc-members:
:show-inheritance:


34 changes: 17 additions & 17 deletions examples/client_async_basic_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,34 @@

from examples.client_async import _logger, run_client, setup_client

UNIT = 0x01
SLAVE = 0x01


async def handle_coils(client):
"""Read/Write coils."""
_logger.info("### Reading Coil")
rr = await client.read_coils(1, 1, unit=UNIT)
rr = await client.read_coils(1, 1, slave=SLAVE)
assert not rr.isError() # test that call was OK
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Reading Coils to get bit 5")
rr = await client.read_coils(1, 5, unit=UNIT)
rr = await client.read_coils(1, 5, slave=SLAVE)
assert not rr.isError() # test that call was OK
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Write true to coil bit 0 and read to verify")
rq = await client.write_coil(0, True, unit=UNIT)
rr = await client.read_coils(0, 1, unit=UNIT)
rq = await client.write_coil(0, True, slave=SLAVE)
rr = await client.read_coils(0, 1, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.bits[0] # test the expected value
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Write true to multiple coils 1-8")
rq = await client.write_coils(1, [True] * 21, unit=UNIT)
rr = await client.read_coils(1, 21, unit=UNIT)
rq = await client.write_coils(1, [True] * 21, slave=SLAVE)
rr = await client.read_coils(1, 21, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
resp = [True] * 21
# If the returned output quantity is not a multiple of eight,
Expand All @@ -49,8 +49,8 @@ async def handle_coils(client):
_logger.debug(txt)

_logger.info("### Write False to address 1-8 coils")
rq = await client.write_coils(1, [False] * 8, unit=UNIT)
rr = await client.read_coils(1, 8, unit=UNIT)
rq = await client.write_coils(1, [False] * 8, slave=SLAVE)
rr = await client.read_coils(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.bits == [False] * 8 # test the expected value
txt = f"### coils response: {str(rr.bits)}"
Expand All @@ -60,7 +60,7 @@ async def handle_coils(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, unit=UNIT)
rr = await client.read_discrete_inputs(0, 8, slave=SLAVE)
assert not rr.isError() # nosec test that we are not an error
txt = f"### address 0-7 is: {str(rr.bits)}"
_logger.debug(txt)
Expand All @@ -69,16 +69,16 @@ async def handle_discrete_input(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, unit=UNIT)
rr = await client.read_holding_registers(1, 1, unit=UNIT)
rq = await client.write_register(1, 10, slave=SLAVE)
rr = await client.read_holding_registers(1, 1, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.registers[0] == 10 # nosec test the expected value
txt = f"### address 1 is: {str(rr.registers[0])}"
_logger.debug(txt)

_logger.info("### write holding registers and read holding registers")
rq = await client.write_registers(1, [10] * 8, unit=UNIT)
rr = await client.read_holding_registers(1, 8, unit=UNIT)
rq = await client.write_registers(1, [10] * 8, slave=SLAVE)
rr = await client.read_holding_registers(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.registers == [10] * 8 # nosec test the expected value
txt = f"### address 1-8 is: {str(rr.registers)}"
Expand All @@ -91,8 +91,8 @@ async def handle_holding_registers(client):
"write_address": 1,
"write_registers": [256, 128, 100, 50, 25, 10, 5, 1],
}
rq = await client.readwrite_registers(unit=UNIT, **arguments)
rr = await client.read_holding_registers(1, 8, unit=UNIT)
rq = await client.readwrite_registers(unit=SLAVE, **arguments)
rr = await client.read_holding_registers(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rq.registers == arguments["write_registers"]
assert rr.registers == arguments["write_registers"]
Expand All @@ -103,7 +103,7 @@ async def handle_holding_registers(client):
async def handle_input_registers(client):
"""Read input registers."""
_logger.info("### read input registers")
rr = await client.read_input_registers(1, 8, unit=UNIT)
rr = await client.read_input_registers(1, 8, slave=SLAVE)
assert not rr.isError() # nosec test that we are not an error
txt = f"### address 1 is: {str(rr.registers[0])}"
_logger.debug(txt)
Expand Down
34 changes: 17 additions & 17 deletions examples/client_sync_basic_calls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,34 @@
"""
from examples.client_sync import _logger, run_client, setup_client

UNIT = 0x01
SLAVE = 0x01


def handle_coils(client):
"""Read/Write coils."""
_logger.info("### Reading Coil")
rr = client.read_coils(1, 1, unit=UNIT)
rr = client.read_coils(1, 1, slave=SLAVE)
assert not rr.isError() # test that call was OK
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Reading Coils to get bit 5")
rr = client.read_coils(1, 5, unit=UNIT)
rr = client.read_coils(1, 5, slave=SLAVE)
assert not rr.isError() # test that call was OK
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Write true to coil bit 0 and read to verify")
rq = client.write_coil(0, True, unit=UNIT)
rr = client.read_coils(0, 1, unit=UNIT)
rq = client.write_coil(0, True, slave=SLAVE)
rr = client.read_coils(0, 1, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.bits[0] # test the expected value
txt = f"### coils response: {str(rr.bits)}"
_logger.debug(txt)

_logger.info("### Write true to multiple coils 1-8")
rq = client.write_coils(1, [True] * 21, unit=UNIT)
rr = client.read_coils(1, 21, unit=UNIT)
rq = client.write_coils(1, [True] * 21, slave=SLAVE)
rr = client.read_coils(1, 21, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
resp = [True] * 21
# If the returned output quantity is not a multiple of eight,
Expand All @@ -47,8 +47,8 @@ def handle_coils(client):
_logger.debug(txt)

_logger.info("### Write False to address 1-8 coils")
rq = client.write_coils(1, [False] * 8, unit=UNIT)
rr = client.read_coils(1, 8, unit=UNIT)
rq = client.write_coils(1, [False] * 8, slave=SLAVE)
rr = client.read_coils(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.bits == [False] * 8 # test the expected value
txt = f"### coils response: {str(rr.bits)}"
Expand All @@ -58,7 +58,7 @@ def handle_coils(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, unit=UNIT)
rr = client.read_discrete_inputs(0, 8, slave=SLAVE)
assert not rr.isError() # nosec test that we are not an error
txt = f"### address 0-7 is: {str(rr.bits)}"
_logger.debug(txt)
Expand All @@ -67,16 +67,16 @@ def handle_discrete_input(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, unit=UNIT)
rr = client.read_holding_registers(1, 1, unit=UNIT)
rq = client.write_register(1, 10, slave=SLAVE)
rr = client.read_holding_registers(1, 1, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.registers[0] == 10 # nosec test the expected value
txt = f"### address 1 is: {str(rr.registers[0])}"
_logger.debug(txt)

_logger.info("### write holding registers and read holding registers")
rq = client.write_registers(1, [10] * 8, unit=UNIT)
rr = client.read_holding_registers(1, 8, unit=UNIT)
rq = client.write_registers(1, [10] * 8, slave=SLAVE)
rr = client.read_holding_registers(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rr.registers == [10] * 8 # nosec test the expected value
txt = f"### address 1-8 is: {str(rr.registers)}"
Expand All @@ -89,8 +89,8 @@ def handle_holding_registers(client):
"write_address": 1,
"write_registers": [256, 128, 100, 50, 25, 10, 5, 1],
}
rq = client.readwrite_registers(unit=UNIT, **arguments)
rr = client.read_holding_registers(1, 8, unit=UNIT)
rq = client.readwrite_registers(unit=SLAVE, **arguments)
rr = client.read_holding_registers(1, 8, slave=SLAVE)
assert not rq.isError() and not rr.isError() # test that calls was OK
assert rq.registers == arguments["write_registers"]
assert rr.registers == arguments["write_registers"]
Expand All @@ -101,7 +101,7 @@ def handle_holding_registers(client):
def handle_input_registers(client):
"""Read input registers."""
_logger.info("### read input registers")
rr = client.read_input_registers(1, 8, unit=UNIT)
rr = client.read_input_registers(1, 8, slave=SLAVE)
assert not rr.isError() # nosec test that we are not an error
txt = f"### address 1 is: {str(rr.registers[0])}"
_logger.debug(txt)
Expand Down
2 changes: 1 addition & 1 deletion examples/common/payload_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def run_binary_payload_client():
print("Reading Registers:")
address = 0x0
count = len(payload)
result = client.read_holding_registers(address, count, unit=1)
result = client.read_holding_registers(address, count, slave=1)
print(result.registers)
print("\n")
decoder = BinaryPayloadDecoder.fromRegisters(
Expand Down
2 changes: 1 addition & 1 deletion examples/common/performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def single_client_test(n_host, n_cycles):
count = 0
client = ModbusTcpClient(n_host, port=5020)
while count < n_cycles:
client.read_holding_registers(10, 123, unit=1)
client.read_holding_registers(10, 123, slave=1)
count += 1
except Exception: # pylint: disable=broad-except
logger.exception("failed to run test successfully")
Expand Down
2 changes: 1 addition & 1 deletion examples/contrib/libmodbus_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def __init__(self, my_client):
:param client: The underlying client instance to operate with.
"""
self.client = my_client
self.slave = Defaults.UnitId
self.slave = Defaults.Slave

def set_slave(self, slave):
"""Set the current slave to operate against.
Expand Down
Loading