diff --git a/doc/source/_static/examples.tgz b/doc/source/_static/examples.tgz index 722d25b18..be0a609ef 100644 Binary files a/doc/source/_static/examples.tgz and b/doc/source/_static/examples.tgz differ diff --git a/doc/source/_static/examples.zip b/doc/source/_static/examples.zip index 5da9c1f14..777f6fbec 100644 Binary files a/doc/source/_static/examples.zip and b/doc/source/_static/examples.zip differ diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 74b01b811..1ec97e8cf 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -177,15 +177,6 @@ Source: :github:`examples/datastore_simulator_share.py` :noindex: -Message generator -^^^^^^^^^^^^^^^^^ -Source: :github:`examples/message_generator.py` - -.. automodule:: examples.message_generator - :undoc-members: - :noindex: - - Message Parser ^^^^^^^^^^^^^^ Source: :github:`examples/message_parser.py` diff --git a/examples/client_async.py b/examples/client_async.py index 06da1c40e..081770e87 100755 --- a/examples/client_async.py +++ b/examples/client_async.py @@ -113,6 +113,8 @@ def setup_async_client(description=None, cmdline=None): ), server_hostname="localhost", ) + else: + raise RuntimeError(f"Unknown commtype {args.comm}") return client diff --git a/examples/client_custom_msg.py b/examples/client_custom_msg.py index e86f4793b..17b643c64 100755 --- a/examples/client_custom_msg.py +++ b/examples/client_custom_msg.py @@ -121,6 +121,9 @@ async def main(host="localhost", port=5020): async with ModbusClient(host=host, port=port, framer_name=FramerType.SOCKET) as client: await client.connect() + # create a response object to control it works + CustomModbusResponse() + # new modbus function code. client.register(CustomModbusResponse) request = CustomModbusRequest(32, slave=1) diff --git a/examples/helper.py b/examples/helper.py index af26468c8..d1d93b64d 100755 --- a/examples/helper.py +++ b/examples/helper.py @@ -20,7 +20,7 @@ def get_commandline(server=False, description=None, extras=None, cmdline=None): parser.add_argument( "-c", "--comm", - choices=["tcp", "udp", "serial", "tls"], + choices=["tcp", "udp", "serial", "tls", "unknown"], help="set communication, default is tcp", dest="comm", default="tcp", diff --git a/examples/message_generator.py b/examples/message_generator.py deleted file mode 100755 index cf885b36c..000000000 --- a/examples/message_generator.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python3 -"""Modbus Message Generator.""" -import argparse -import codecs as c -import logging - -import pymodbus.pdu.bit_read_message as modbus_bit -import pymodbus.pdu.bit_write_message as modbus_bit_write -import pymodbus.pdu.diag_message as modbus_diag -import pymodbus.pdu.file_message as modbus_file -import pymodbus.pdu.mei_message as modbus_mei -import pymodbus.pdu.other_message as modbus_other -import pymodbus.pdu.register_read_message as modbus_register -import pymodbus.pdu.register_write_message as modbus_register_write -from pymodbus.transaction import ( - ModbusAsciiFramer, - ModbusRtuFramer, - ModbusSocketFramer, -) - - -_logger = logging.getLogger(__file__) - - -# -------------------------------------------------------------------------- # -# enumerate all request/response messages -# -------------------------------------------------------------------------- # -messages = [ - ( - modbus_register.ReadHoldingRegistersRequest, - modbus_register.ReadHoldingRegistersResponse, - ), - (modbus_bit.ReadDiscreteInputsRequest, modbus_bit.ReadDiscreteInputsResponse), - ( - modbus_register.ReadInputRegistersRequest, - modbus_register.ReadInputRegistersResponse, - ), - (modbus_bit.ReadCoilsRequest, modbus_bit.ReadCoilsResponse), - ( - modbus_bit_write.WriteMultipleCoilsRequest, - modbus_bit_write.WriteMultipleCoilsResponse, - ), - ( - modbus_register_write.WriteMultipleRegistersRequest, - modbus_register_write.WriteMultipleRegistersResponse, - ), - ( - modbus_register_write.WriteSingleRegisterRequest, - modbus_register_write.WriteSingleRegisterResponse, - ), - (modbus_bit_write.WriteSingleCoilRequest, modbus_bit_write.WriteSingleCoilResponse), - ( - modbus_register.ReadWriteMultipleRegistersRequest, - modbus_register.ReadWriteMultipleRegistersResponse, - ), - (modbus_other.ReadExceptionStatusRequest, modbus_other.ReadExceptionStatusResponse), - (modbus_other.GetCommEventCounterRequest, modbus_other.GetCommEventCounterResponse), - (modbus_other.GetCommEventLogRequest, modbus_other.GetCommEventLogResponse), - (modbus_other.ReportSlaveIdRequest, modbus_other.ReportSlaveIdResponse), - (modbus_file.ReadFileRecordRequest, modbus_file.ReadFileRecordResponse), - (modbus_file.WriteFileRecordRequest, modbus_file.WriteFileRecordResponse), - ( - modbus_register_write.MaskWriteRegisterRequest, - modbus_register_write.MaskWriteRegisterResponse, - ), - (modbus_file.ReadFifoQueueRequest, modbus_file.ReadFifoQueueResponse), - (modbus_mei.ReadDeviceInformationRequest, modbus_mei.ReadDeviceInformationResponse), - (modbus_diag.ReturnQueryDataRequest, modbus_diag.ReturnQueryDataResponse), - ( - modbus_diag.RestartCommunicationsOptionRequest, - modbus_diag.RestartCommunicationsOptionResponse, - ), - ( - modbus_diag.ReturnDiagnosticRegisterRequest, - modbus_diag.ReturnDiagnosticRegisterResponse, - ), - ( - modbus_diag.ChangeAsciiInputDelimiterRequest, - modbus_diag.ChangeAsciiInputDelimiterResponse, - ), - (modbus_diag.ForceListenOnlyModeRequest, modbus_diag.ForceListenOnlyModeResponse), - (modbus_diag.ClearCountersRequest, modbus_diag.ClearCountersResponse), - ( - modbus_diag.ReturnBusMessageCountRequest, - modbus_diag.ReturnBusMessageCountResponse, - ), - ( - modbus_diag.ReturnBusCommunicationErrorCountRequest, - modbus_diag.ReturnBusCommunicationErrorCountResponse, - ), - ( - modbus_diag.ReturnBusExceptionErrorCountRequest, - modbus_diag.ReturnBusExceptionErrorCountResponse, - ), - ( - modbus_diag.ReturnSlaveMessageCountRequest, - modbus_diag.ReturnSlaveMessageCountResponse, - ), - ( - modbus_diag.ReturnSlaveNoResponseCountRequest, - modbus_diag.ReturnSlaveNoResponseCountResponse, - ), - (modbus_diag.ReturnSlaveNAKCountRequest, modbus_diag.ReturnSlaveNAKCountResponse), - (modbus_diag.ReturnSlaveBusyCountRequest, modbus_diag.ReturnSlaveBusyCountResponse), - ( - modbus_diag.ReturnSlaveBusCharacterOverrunCountRequest, - modbus_diag.ReturnSlaveBusCharacterOverrunCountResponse, - ), - ( - modbus_diag.ReturnIopOverrunCountRequest, - modbus_diag.ReturnIopOverrunCountResponse, - ), - (modbus_diag.ClearOverrunCountRequest, modbus_diag.ClearOverrunCountResponse), - (modbus_diag.GetClearModbusPlusRequest, modbus_diag.GetClearModbusPlusResponse), -] - - -def get_commandline(cmdline=None): - """Parse the command line options.""" - parser = argparse.ArgumentParser() - parser.add_argument( - "--framer", - choices=["ascii", "rtu", "socket"], - help="set framer, default is rtu", - dest="framer", - default="rtu", - type=str, - ) - parser.add_argument( - "-l", - "--log", - choices=["critical", "error", "warning", "info", "debug"], - help="set log level, default is info", - dest="log", - default="info", - type=str, - ) - parser.add_argument( - "-a", - "--address", - help="address to use", - dest="address", - default=32, - type=int, - ) - parser.add_argument( - "-c", - "--count", - help="count to use", - dest="count", - default=8, - type=int, - ) - parser.add_argument( - "-v", - "--value", - help="value to use", - dest="value", - default=1, - type=int, - ) - parser.add_argument( - "-t", - "--transaction", - help="transaction to use", - dest="transaction", - default=1, - type=int, - ) - parser.add_argument( - "-s", - "--slave", - help="slave to use", - dest="slave", - default=1, - type=int, - ) - args = parser.parse_args(cmdline) - return args - - -def generate_messages(cmdline=None): - """Parse the command line options.""" - args = get_commandline(cmdline=cmdline) - _logger.setLevel(args.log.upper()) - - arguments = { - "address": args.address, - "count": args.count, - "value": args.value, - "values": [args.value] * args.count, - "read_address": args.address, - "read_count": args.count, - "write_address": args.address, - "write_registers": [args.value] * args.count, - "transaction": args.transaction, - "slave": args.slave, - "protocol": 0x00, - } - framer = { - "ascii": ModbusAsciiFramer, - "rtu": ModbusRtuFramer, - "socket": ModbusSocketFramer, - }[args.framer](None) - - for entry in messages: - for inx in (0, 1): - message = entry[inx](**arguments) - raw_packet = framer.buildPacket(message) - packet = c.encode(raw_packet, "hex_codec").decode("utf-8") - print(f"{message.__class__.__name__:44} = {packet}") - print("") - - -if __name__ == "__main__": - generate_messages() diff --git a/test/sub_examples/test_client_server_async.py b/test/sub_examples/test_client_server_async.py index 674b4fa66..92446785d 100755 --- a/test/sub_examples/test_client_server_async.py +++ b/test/sub_examples/test_client_server_async.py @@ -56,6 +56,12 @@ async def test_client_exception(self, mock_server, mock_clc): ) await run_async_client(test_client, modbus_calls=run_a_few_calls) + async def test_client_no_calls(self, mock_server, mock_clc): + """Run async client and server.""" + assert mock_server + test_client = setup_async_client(cmdline=mock_clc) + await run_async_client(test_client, modbus_calls=None) + async def test_server_no_client(self, mock_server): """Run async server without client.""" assert mock_server @@ -76,3 +82,9 @@ async def test_client_no_server(self, mock_clc): test_client = setup_async_client(cmdline=mock_clc) with pytest.raises((AssertionError, asyncio.TimeoutError)): await run_async_client(test_client, modbus_calls=run_a_few_calls) + +async def test_illegal_commtype(): + """Run async client and server.""" + with pytest.raises(RuntimeError): + setup_async_client(cmdline=["--comm", "unknown", "--framer", "rtu", "--port", "5912"] +) diff --git a/test/sub_examples/test_examples.py b/test/sub_examples/test_examples.py index 1cf0ead7c..446190a75 100755 --- a/test/sub_examples/test_examples.py +++ b/test/sub_examples/test_examples.py @@ -18,7 +18,6 @@ from examples.client_custom_msg import main as main_custom_client from examples.client_payload import main as main_payload_calls from examples.datastore_simulator_share import main as main_datastore_simulator_share -from examples.message_generator import generate_messages from examples.message_parser import main as main_parse_messages from examples.server_async import setup_server from examples.server_callback import run_callback_server @@ -43,11 +42,6 @@ def get_port_in_class(base_ports): base_ports[__class__.__name__] += 1 return base_ports[__class__.__name__] - @pytest.mark.parametrize("framer", ["socket", "rtu", "ascii"]) - def test_message_generator(self, framer): - """Test all message generator.""" - generate_messages(cmdline=["--framer", framer]) - @pytest.mark.parametrize("framer", ["socket", "rtu", "ascii"]) def test_message_parser(self, framer): """Test message parser."""