diff --git a/check_ci.sh b/check_ci.sh index 177a3d4f5..14b72be8d 100755 --- a/check_ci.sh +++ b/check_ci.sh @@ -9,5 +9,8 @@ codespell ruff check --fix --exit-non-zero-on-fix . pylint --recursive=y examples pymodbus test zuban check pymodbus examples test +if [ $1 ]; then + exit 1 +fi pytest -x --cov --numprocesses auto echo "Ready to push" diff --git a/examples/client_async.py b/examples/client_async.py index 951d43326..b8fd24b55 100755 --- a/examples/client_async.py +++ b/examples/client_async.py @@ -36,7 +36,7 @@ try: import helper # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) diff --git a/examples/client_async_calls.py b/examples/client_async_calls.py index b91ef9a0a..641796e54 100755 --- a/examples/client_async_calls.py +++ b/examples/client_async_calls.py @@ -41,7 +41,7 @@ try: import client_async # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) diff --git a/examples/client_calls.py b/examples/client_calls.py index 52fb8d905..077411598 100755 --- a/examples/client_calls.py +++ b/examples/client_calls.py @@ -38,7 +38,7 @@ try: import client_sync # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) diff --git a/examples/client_sync.py b/examples/client_sync.py index 6dc7b8a6b..4bf770f1f 100755 --- a/examples/client_sync.py +++ b/examples/client_sync.py @@ -39,7 +39,7 @@ try: import helper # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) diff --git a/examples/custom_msg.py b/examples/custom_msg.py index 2b042c994..fc1983e52 100755 --- a/examples/custom_msg.py +++ b/examples/custom_msg.py @@ -15,22 +15,19 @@ from pymodbus import FramerType from pymodbus.client import AsyncModbusTcpClient as ModbusClient -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) +from pymodbus.datastore import ModbusServerContext from pymodbus.exceptions import ModbusIOException from pymodbus.pdu import ModbusPDU from pymodbus.pdu.bit_message import ReadCoilsRequest from pymodbus.server import ServerAsyncStop, StartAsyncTcpServer +from pymodbus.simulator import DataType, SimData, SimDevice # --------------------------------------------------------------------------- # # create your custom message # --------------------------------------------------------------------------- # # The following is simply a read coil request that always reads 16 coils. -# Since the function code is already registered with the decoder factory, +# Since the function code is already registered with the decoder, # this will be decoded as a read coil response. If you implement a new # method that is not currently implemented, you must register the request # and response with the active DecodePDU object. @@ -121,16 +118,8 @@ def __init__(self, address, device_id=1, transaction=0): async def main(host="localhost", port=5020): """Run versions of read coil.""" - store = ModbusServerContext(devices=ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ), - single=True - ) task = asyncio.create_task(StartAsyncTcpServer( - context=store, + context=SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), address=(host, port), custom_pdu=[CustomRequest]) ) diff --git a/examples/helper.py b/examples/helper.py index 4dd7f5902..ea3ac6503 100755 --- a/examples/helper.py +++ b/examples/helper.py @@ -67,13 +67,6 @@ def get_commandline(server: bool = False, description: str | None = None, extras type=str, ) if server: - parser.add_argument( - "--store", - choices=["sequential", "sparse", "factory", "none"], - help="set type of datastore", - default="sequential", - type=str, - ) parser.add_argument( "--device_ids", help="set number of device_ids, default is 0 (any)", diff --git a/examples/package_test_tool.py b/examples/package_test_tool.py index 6e6eb88d6..24c6085fb 100755 --- a/examples/package_test_tool.py +++ b/examples/package_test_tool.py @@ -55,12 +55,8 @@ ModbusException, pymodbus_apply_logging_config, ) -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) from pymodbus.logging import Log +from pymodbus.simulator import DataType, SimData, SimDevice from pymodbus.transport import NULLMODEM_HOST, CommParams, CommType, ModbusProtocol @@ -149,13 +145,7 @@ class ServerTester: # pylint: disable=too-few-public-methods def __init__(self, comm: CommType): """Initialize runtime tester.""" self.comm = comm - self.store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) - self.context = ModbusServerContext(devices=self.store, single=True) + self.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)) self.identity = ModbusDeviceIdentification( info_name={"VendorName": "VendorName"} ) diff --git a/examples/server_async.py b/examples/server_async.py index 907ef9556..71114d286 100755 --- a/examples/server_async.py +++ b/examples/server_async.py @@ -8,7 +8,7 @@ server_async.py [-h] [--comm {tcp,udp,serial,tls}] [--framer {ascii,rtu,socket,tls}] [--log {critical,error,warning,info,debug}] - [--port PORT] [--store {sequential,sparse,factory,none}] + [--port PORT] [--device_ids DEVICE_IDS] -h, --help @@ -22,8 +22,6 @@ -p, --port PORT set port set serial device baud rate - --store {sequential,sparse,factory,none} - set datastore type --device_ids DEVICE IDs set list of devices to respond to @@ -35,32 +33,25 @@ import asyncio import logging import sys -from collections.abc import Callable -from typing import Any try: import helper # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) from pymodbus import ModbusDeviceIdentification from pymodbus import __version__ as pymodbus_version -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, - ModbusSparseDataBlock, -) from pymodbus.server import ( StartAsyncSerialServer, StartAsyncTcpServer, StartAsyncTlsServer, StartAsyncUdpServer, ) +from pymodbus.simulator import DataType, SimData, SimDevice _logger = logging.getLogger(__file__) @@ -70,53 +61,17 @@ def setup_server(description=None, context=None, cmdline=None): """Run server setup.""" args = helper.get_commandline(server=True, description=description, cmdline=cmdline) - if context: + if context: # pragma: no cover args.context = context - datablock: Callable[[], Any] - if not args.context: + if not args.context: # pragma: no cover _logger.info("### Create datastore") - # The datastores only respond to the addresses that are initialized - # If you initialize a DataBlock to addresses of 0x00 to 0xFF, a request to - # 0x100 will respond with an invalid address exception. - # This is because many devices exhibit this kind of behavior (but not all) - if args.store == "sequential": # pragma: no cover - # Continuing, use a sequential block without gaps. - datablock = lambda : ModbusSequentialDataBlock(0x00, [17] * 100) # pylint: disable=unnecessary-lambda-assignment - elif args.store == "sparse": # pragma: no cover - # Continuing, or use a sparse DataBlock which can have gaps - datablock = lambda : ModbusSparseDataBlock({0x00: 0, 0x05: 1}) # pylint: disable=unnecessary-lambda-assignment - elif args.store == "factory" or True: # pragma: no cover # pylint: disable=condition-evals-to-constant - # Alternately, use the factory methods to initialize the DataBlocks - # or simply do not pass them to have them initialized to 0x00 on the - # full address range:: - datablock = lambda : ModbusSequentialDataBlock(0x00, [0x00] * 65536) # pylint: disable=unnecessary-lambda-assignment + # Build data storage if args.device_ids > 1: # pragma: no cover - # The server then makes use of a server context that allows the server - # to respond with different device contexts for different device ids. - # By default it will return the same context for every device id supplied - # (broadcast mode). - # However, this can be overloaded by setting the single flag to False and - # then supplying a dictionary of device id to context mapping:: - context = { - device_id : ModbusDeviceContext( - di=datablock(), - co=datablock(), - hr=datablock(), - ir=datablock(), - ) - for device_id in range(args.device_ids) - } - - single = False + args.context = [SimDevice(device_id, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)) + for device_id in range(args.device_ids)] else: - context = ModbusDeviceContext( - di=datablock(), co=datablock(), hr=datablock(), ir=datablock() - ) - single = True - - # Build data storage - args.context = ModbusServerContext(devices=context, single=single) + args.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)) # ----------------------------------------------------------------------- # # initialize the server information diff --git a/examples/server_hook.py b/examples/server_hook.py index 7b14bd7db..82ab388ae 100755 --- a/examples/server_hook.py +++ b/examples/server_hook.py @@ -11,19 +11,15 @@ import sys from pymodbus import FramerType, pymodbus_apply_logging_config -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) from pymodbus.pdu import ModbusPDU from pymodbus.server import ModbusTcpServer +from pymodbus.simulator import DataType, SimData, SimDevice try: import helper # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) @@ -57,16 +53,9 @@ async def setup(self, cmdline): """Prepare server.""" args = helper.get_commandline(server=True, description="server hooks", cmdline=cmdline) pymodbus_apply_logging_config(logging.DEBUG) - datablock = ModbusSequentialDataBlock(0x00, [17] * 100) - context = ModbusServerContext( - devices=ModbusDeviceContext( - di=datablock, co=datablock, hr=datablock, ir=datablock - ), - single=True, - ) address: tuple[str, int] = (args.host if args.host else "", args.port if args.port else 0) self.server = ModbusTcpServer( - context, + SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), framer=FramerType.SOCKET, identity=None, address=address, diff --git a/examples/server_sync.py b/examples/server_sync.py index 5d2ef7843..d975b55f2 100755 --- a/examples/server_sync.py +++ b/examples/server_sync.py @@ -8,7 +8,7 @@ server_sync.py [-h] [--comm {tcp,udp,serial,tls}] [--framer {ascii,rtu,socket,tls}] [--log {critical,error,warning,info,debug}] - [--port PORT] [--store {sequential,sparse,factory,none}] + [--port PORT] [--device_ids DEVICE_IDS] -h, --help @@ -22,8 +22,6 @@ -p, --port PORT set port set serial device baud rate - --store {sequential,sparse,factory,none} - set datastore type --device_ids DEVICE_IDS set list of devices to respond to @@ -42,7 +40,7 @@ import helper # type: ignore[import-not-found] import server_async # type: ignore[import-not-found] except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ + print("*** ERROR --> THIS EXAMPLE needs to be run in the example directory, please see \n\ https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ for more information.") sys.exit(-1) diff --git a/examples/server_updating.py b/examples/server_updating.py index 280d55a2e..83f1eb906 100755 --- a/examples/server_updating.py +++ b/examples/server_updating.py @@ -6,55 +6,70 @@ usage:: - server_updating.py [-h] [--comm {tcp,udp,serial,tls}] - [--framer {ascii,rtu,socket,tls}] + server_updating.py [-h] [--log {critical,error,warning,info,debug}] - [--port PORT] [--store {sequential,sparse,factory,none}] - [--device_ids DEVICE_IDS] + [--port PORT] + [--host HOST] -h, --help show this help message and exit - -c, --comm {tcp,udp,serial,tls} - set communication, default is tcp - -f, --framer {ascii,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 - --device_ids DEVICE_IDS - set number of devices to respond to + --host HOST + set HOST The corresponding client can be started as: python3 client_sync.py """ +import argparse import asyncio import logging -import sys +from pymodbus import pymodbus_apply_logging_config +from pymodbus.server import ModbusTcpServer +from pymodbus.simulator import DataType, SimData, SimDevice -try: - import server_async # type: ignore[import-not-found] -except ImportError: - print("*** ERROR --> THIS EXAMPLE needs the example directory, please see \n\ - https://pymodbus.readthedocs.io/en/latest/source/examples.html\n\ - for more information.") - sys.exit(-1) -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) +_logger = logging.getLogger(__name__) +def get_commandline(cmdline: list[str] | None = None): + """Read and check command line arguments.""" + parser = argparse.ArgumentParser(description="server_update") + 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( + "-p", + "--port", + help="set port", + dest="port", + type=str, + ) + parser.add_argument( + "--host", + help="set host, default is 127.0.0.1", + dest="host", + default=None, + type=str, + ) + args = parser.parse_args(cmdline) + pymodbus_apply_logging_config(args.log.upper()) + _logger.setLevel(args.log.upper()) + args.port = args.port or 5020 + return args -_logger = logging.getLogger(__name__) -async def updating_task(context): +async def updating_task(server): """Update values in server. This task runs continuously beside the server @@ -64,14 +79,14 @@ async def updating_task(context): against concurrent use. """ func_code = 3 - device_id = 0x00 + device_id = 0x01 address = 0x10 count = 6 # set values to zero - values = await context.async_getValues(device_id, func_code, address, count=count) + values = await server.async_getValues(device_id, func_code, address, count=count) values = [0 for v in values] - await context.async_setValues(device_id, func_code, address, values) + await server.async_setValues(device_id, func_code, address, values) txt = ( f"updating_task: started: initialised values: {values!s} at address {address!s}" @@ -83,9 +98,9 @@ async def updating_task(context): while True: await asyncio.sleep(2) - values = await context.async_getValues(device_id, func_code, address, count=count) + values = await server.async_getValues(device_id, func_code, address, count=count) values = [v + 1 for v in values] - await context.async_setValues(device_id, func_code, address, values) + await server.async_setValues(device_id, func_code, address, values) txt = f"updating_task: incremented values: {values!s} at address {address!s}" print(txt) @@ -98,28 +113,26 @@ def setup_updating_server(cmdline=None): # If you initialize a DataBlock to addresses of 0x00 to 0xFF, a request to # 0x100 will respond with an invalid address exception. # This is because many devices exhibit this kind of behavior (but not all) - - # Continuing, use a sequential block without gaps. - datablock = ModbusSequentialDataBlock(0x00, [17] * 100) - device_context = ModbusDeviceContext(di=datablock, co=datablock, hr=datablock, ir=datablock) - context = ModbusServerContext(devices=device_context, single=True) - return server_async.setup_server( - description="Run asynchronous server.", context=context, cmdline=cmdline + args = get_commandline(cmdline=cmdline) + server = ModbusTcpServer( + SimDevice(1, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), + address=(args.host if args.host else "", args.port if args.port else 0) ) + return server -async def run_updating_server(args): +async def run_updating_server(server): """Start updating_task concurrently with the current task.""" - task = asyncio.create_task(updating_task(args.context)) + task = asyncio.create_task(updating_task(server)) task.set_name("example updating task") - await server_async.run_async_server(args) # start the server + await server.serve_forever() # start the server task.cancel() async def main(cmdline=None): """Combine setup and run.""" - run_args = setup_updating_server(cmdline=cmdline) - await run_updating_server(run_args) + server = setup_updating_server(cmdline=cmdline) + await run_updating_server(server) if __name__ == "__main__": diff --git a/pymodbus/simulator/simcore.py b/pymodbus/simulator/simcore.py index ae8e717b0..399ff5fee 100644 --- a/pymodbus/simulator/simcore.py +++ b/pymodbus/simulator/simcore.py @@ -30,6 +30,13 @@ def __get_device(self, device_id: int) -> SimRuntime: """Return device object.""" return self.devices[device_id] if device_id in self.devices else self.devices[0] + def device_ids(self) -> list[int]: + """Return list of device ids.""" + dev_ids: list[int] = [] + for dev_id in self.devices: + dev_ids.append(dev_id) + return dev_ids + async def async_getValues(self,device_id: int, func_code: int, address: int, count: int = 1) -> list[int] | list[bool] | ExcCodes: """Get `count` values from datastore.""" return await self.__get_device(device_id).async_getValues(func_code, address, count) diff --git a/test/datastore/test_context.py b/test/datastore/test_context.py index 74b1e35d1..b0d38e0e8 100644 --- a/test/datastore/test_context.py +++ b/test/datastore/test_context.py @@ -1,9 +1,12 @@ """Test datastore context.""" +import pytest from pymodbus.datastore import ( ModbusDeviceContext, + ModbusSequentialDataBlock, ModbusServerContext, ) +from pymodbus.datastore.context import NoSuchIdException class TestContextDataStore: @@ -15,6 +18,13 @@ async def test_datastore_device_Values(self): await dev.async_OLD_getValues(0x01, 0x05) await dev.async_OLD_setValues(0x05, 0x05, [17]) + async def test_datastore_device_not_ok(self): + """Test ModbusDeviceContext.""" + block = ModbusSequentialDataBlock(1, [17] * 8) + dev = ModbusDeviceContext(di=block, co=block, hr=block, ir=block) + await dev.async_OLD_getValues(0x03, 0x05) + await dev.async_OLD_setValues(0x05, 0x05, [17]) + def test_datastore_server(self): """Test ModbusServerContext.""" dev = ModbusServerContext() @@ -28,3 +38,13 @@ def test_datastore_server_ids(self): srv = ModbusServerContext() assert isinstance(srv.device_ids(), list) + async def test_datastore_server_device_id(self): + """Test ModbusServerContext.""" + block = ModbusSequentialDataBlock(1, [17] * 8) + dev = ModbusDeviceContext(di=block, co=block, hr=block, ir=block) + srv = ModbusServerContext(devices={1: dev}, single=False) + assert srv.device_ids() == [1] + await srv.async_setValues(1, 0x05, 0, [1]) + assert await srv.async_getValues(1, 0x03, 0) == [1] + with pytest.raises(NoSuchIdException): + await srv.async_getValues(15, 0, 0) diff --git a/test/datastore/test_sequential.py b/test/datastore/test_sequential.py index 61b933dbb..c82650ff0 100644 --- a/test/datastore/test_sequential.py +++ b/test/datastore/test_sequential.py @@ -12,6 +12,11 @@ def test_datastore_Sequential(self): ModbusSequentialDataBlock(0x01, [17]) ModbusSequentialDataBlock(0x01, 17) + async def test_datastore_Sequential_get_0K(self): + """Test ModbusDeviceContext.""" + block = ModbusSequentialDataBlock(0x01, [17]) + assert await block.async_OLD_getValues(1) == [17] + async def test_datastore_Sequential_get(self): """Test ModbusDeviceContext.""" block = ModbusSequentialDataBlock(0x01, [17]) diff --git a/test/datastore/test_sparse_datastore.py b/test/datastore/test_sparse_datastore.py index e1b66d291..2508dfd40 100644 --- a/test/datastore/test_sparse_datastore.py +++ b/test/datastore/test_sparse_datastore.py @@ -8,7 +8,7 @@ from pymodbus.exceptions import ParameterException -class TestRemoteDataStore: +class TestSparseDataStore: """Unittest for the pymodbus.datastore.remote module.""" data_in_block: dict[int, int | list[int]] = { diff --git a/test/examples/test_helper.py b/test/examples/test_helper.py index 7573d87e6..d6cfc84ae 100644 --- a/test/examples/test_helper.py +++ b/test/examples/test_helper.py @@ -17,7 +17,6 @@ def test_commandline_server_defaults(self): assert args.baudrate == 9600 assert args.framer assert args.port - assert args.store assert not args.device_ids assert not args.context diff --git a/test/pdu/test_decoders.py b/test/pdu/test_decoders.py index 4d1e382de..13201d05d 100644 --- a/test/pdu/test_decoders.py +++ b/test/pdu/test_decoders.py @@ -1,4 +1,4 @@ -"""Test factory.""" +"""Test decoders.""" import pytest from pymodbus.exceptions import MessageRegisterException diff --git a/test/server/test_requesthandler.py b/test/server/test_requesthandler.py index f87932cba..a7e0463f6 100755 --- a/test/server/test_requesthandler.py +++ b/test/server/test_requesthandler.py @@ -3,15 +3,11 @@ import pytest -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) from pymodbus.exceptions import ModbusIOException, NoSuchIdException from pymodbus.framer import FramerType from pymodbus.pdu import ExceptionResponse from pymodbus.server import ModbusBaseServer, ModbusSerialServer +from pymodbus.simulator import DataType, SimData, SimDevice from pymodbus.transport import CommParams, CommType @@ -21,12 +17,6 @@ class TestRequesthandler: @pytest.fixture async def requesthandler(self): """Fixture to provide base_server.""" - store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) server = ModbusBaseServer( CommParams( comm_type=CommType.TCP, @@ -36,7 +26,7 @@ async def requesthandler(self): timeout_connect=0.0, source_address=("0", 0), ), - ModbusServerContext(devices=store, single=True), + SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), False, False, None, @@ -83,14 +73,8 @@ async def test_rh_server_send(self, requesthandler): async def test_serial_server_allow_multiple(self): """Test __init__.""" - store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) server = ModbusSerialServer( - ModbusServerContext(devices=store, single=True), + SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), framer=FramerType.RTU, baudrate=19200, port="/dev/tty01", diff --git a/test/server/test_server_asyncio.py b/test/server/test_server_asyncio.py index 8df331aef..ac71785d1 100755 --- a/test/server/test_server_asyncio.py +++ b/test/server/test_server_asyncio.py @@ -10,11 +10,6 @@ import pytest from pymodbus import FramerType, ModbusDeviceIdentification -from pymodbus.datastore import ( - ModbusDeviceContext, - ModbusSequentialDataBlock, - ModbusServerContext, -) from pymodbus.exceptions import NoSuchIdException from pymodbus.server import ( ModbusBaseServer, @@ -23,6 +18,7 @@ ModbusTlsServer, ModbusUdpServer, ) +from pymodbus.simulator import DataType, SimData, SimDevice _logger = logging.getLogger() @@ -108,7 +104,7 @@ class TestAsyncioServer: server: ModbusBaseServer | None = None task: Task | None = None loop: asyncio.AbstractEventLoop | None = None - store: ModbusDeviceContext | None = None + store: SimDevice | None = None context: Any = None identity: ModbusDeviceIdentification | None = None @@ -116,13 +112,7 @@ class TestAsyncioServer: async def _setup_teardown(self): """Initialize the test environment by setting up a dummy store and context.""" self.loop = asyncio.get_running_loop() - self.store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) - self.context = ModbusServerContext(devices=self.store, single=True) + self.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)) self.identity = ModbusDeviceIdentification( info_name={"VendorName": "VendorName"} ) @@ -287,9 +277,7 @@ async def test_async_tcp_server_shutdown_connection(self): async def test_async_tcp_server_no_device(self): """Test unknown device exception.""" - self.context = ModbusServerContext( - devices={0x01: self.store, 0x02: self.store}, single=False - ) + self.context = SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)) BasicClient.data = b"\x01\x00\x00\x00\x00\x06\x05\x03\x00\x00\x00\x01" await self.start_server() await self.connect_server() @@ -395,15 +383,9 @@ async def test_async_serial_server_multipoint(self): async def test_serial_server_multipoint_baudrate(self): """Test __init__.""" - store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) with pytest.raises(TypeError): ModbusSerialServer( - ModbusServerContext(devices=store, single=True), + SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), framer=FramerType.RTU, baudrate=64200, port="/dev/tty01", @@ -413,15 +395,9 @@ async def test_serial_server_multipoint_baudrate(self): async def test_serial_server_multipoint_framer(self): """Test __init__.""" - store = ModbusDeviceContext( - di=ModbusSequentialDataBlock(0, [17] * 100), - co=ModbusSequentialDataBlock(0, [17] * 100), - hr=ModbusSequentialDataBlock(0, [17] * 100), - ir=ModbusSequentialDataBlock(0, [17] * 100), - ) with pytest.raises(TypeError): ModbusSerialServer( - ModbusServerContext(devices=store, single=True), + SimDevice(0, SimData(0, datatype=DataType.REGISTERS, values=[17]*100)), framer=FramerType.ASCII, baudrate=19200, port="/dev/tty01", diff --git a/test/simulator/test_simcore.py b/test/simulator/test_simcore.py index 62605fb28..d139a254c 100644 --- a/test/simulator/test_simcore.py +++ b/test/simulator/test_simcore.py @@ -47,3 +47,8 @@ async def test_simcore_set(self, kwargs): """Test that simdata can be objects.""" core = SimCore(devices=SimDevice(0, simdata=self.simdata2)) await core.async_setValues(**kwargs) + + def test_simcore_device_ids(self): + """Test that simdata can be objects.""" + core = SimCore(devices=SimDevice(1, simdata=self.simdata2)) + assert core.device_ids() == [1]