diff --git a/pymodbus/client/mixin.py b/pymodbus/client/mixin.py index 176e55e43..4588d07af 100644 --- a/pymodbus/client/mixin.py +++ b/pymodbus/client/mixin.py @@ -13,7 +13,8 @@ from ..pdu import mei_message as pdu_mei from ..pdu import other_message as pdu_other_msg from ..pdu import register_message as pdu_reg -from ..pdu.pdu import ModbusPDU, pack_bitstring, unpack_bitstring +from ..pdu.pdu import ModbusPDU +from ..pdu.utils import pack_bitstring, unpack_bitstring T = TypeVar("T", covariant=False) diff --git a/pymodbus/datastore/context.py b/pymodbus/datastore/context.py index 013dbd328..9e3b0ed9e 100644 --- a/pymodbus/datastore/context.py +++ b/pymodbus/datastore/context.py @@ -5,13 +5,14 @@ from ..constants import ExcCodes from ..exceptions import NoSuchIdException from ..logging import Log +from ..simulator.simdata import DataType +from ..simulator.simdevice import SimDevice from .sequential import ModbusSequentialDataBlock +from .simulator import ModbusSimulatorContext from .sparse import ModbusSparseDataBlock -# pylint: disable=missing-type-doc - -class ModbusDeviceContext: +class ModbusDeviceContext: # pylint: disable=too-few-public-methods """Create a modbus data model with data stored in a block. :param di: discrete inputs initializer ModbusDataBlock @@ -37,33 +38,27 @@ def __init__(self, *_args, "i": ir, "h": hr, } - - async def async_OLD_getValues(self, func_code, address, count=1) -> list[int] | list[bool] | ExcCodes: - """Get `count` values from datastore. - - :param func_code: The function we are working with - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - """ - address += 1 - Log.debug("getValues: fc-[{}] address-{}: count-{}", func_code, address, count) - if dt := self.store[self._fx_mapper.get(func_code, "x")]: - return await dt.async_OLD_getValues(address, count) - return ExcCodes.ILLEGAL_ADDRESS - - async def async_OLD_setValues(self, func_code, address, values) -> None | ExcCodes: - """Set the datastore with the supplied values. - - :param func_code: The function we are working with - :param address: The starting address - :param values: The new values to be set - """ - address += 1 - Log.debug("setValues[{}] address-{}: count-{}", func_code, address, len(values)) - if dt := self.store[self._fx_mapper.get(func_code, "x")]: - return await dt.async_OLD_setValues(address, values) - return ExcCodes.ILLEGAL_ADDRESS + if not di: + di = ModbusSequentialDataBlock(0, values=0) + if not co: + co = ModbusSequentialDataBlock(0, values=0) + if not ir: + ir = ModbusSequentialDataBlock(0, values=0) + if not hr: + hr = ModbusSequentialDataBlock(0, values=0) + for entry in di.simdata: + entry.datatype = DataType.BITS + for entry in co.simdata: + entry.datatype = DataType.BITS + self.simdevice = SimDevice(0, simdata=( + di.simdata, + co.simdata, + ir.simdata, + hr.simdata)) + Log.warning("ModbusDeviceContext is depreacated " + "and will be removed in v4.\n" + "Please convert to SimData/SimDevice.\n" + "Please read https://pymodbus.readthedocs.io/en/dev/source/upgrade_40.html#convert-to-simdata-simdevice") class ModbusServerContext: @@ -79,12 +74,30 @@ def __init__(self, devices=None, single=True): """Initialize a new instance of a modbus server context. :param devices: A dictionary of client contexts - :param single: Set to true to treat this as a single context + :param single: Deprecated + + dev_id=0 is automatically used when devices= is a ModbusDeviceContext + and not a dict. """ - self.single = single - self._devices: dict = devices or {} - if self.single: - self._devices = {0: self._devices} + _ = single + if not devices: + raise TypeError("devices= cannot be None") + self._devices: dict[int, ModbusDeviceContext] + self.simdevices: list[SimDevice] = [] + if isinstance(devices, dict): + self._devices = devices + for dev_id, entry in devices.items(): + if not isinstance(entry, ModbusSimulatorContext): + entry.id = dev_id + self.simdevices.append(entry) + else: + self._devices = {0: devices} + if not isinstance(devices, ModbusSimulatorContext): + self.simdevices = [devices.simdevice] + Log.warning("ModbusServerContext is depreacated " + "and will be removed in v4.\n" + "Please convert to SimData/SimDevice.\n" + "Please read https://pymodbus.readthedocs.io/en/dev/source/upgrade_40.html#convert-to-simdata-simdevice") def __get_device(self, device_id: int) -> ModbusDeviceContext: """Return device object.""" @@ -106,7 +119,9 @@ async def async_getValues(self, device_id: int, func_code: int, address: int, co :returns: The requested values from a:a+c """ dev = self.__get_device(device_id) - return await dev.async_OLD_getValues(func_code, address, count) + if isinstance(dev, ModbusSimulatorContext): + return await dev.async_OLD_getValues(func_code, address, count) + return ExcCodes.DEVICE_BUSY async def async_setValues(self, device_id: int, func_code: int, address: int, values: list[int] | list[bool] ) -> None | ExcCodes: """Set the datastore with the supplied values. @@ -117,7 +132,9 @@ async def async_setValues(self, device_id: int, func_code: int, address: int, va :param values: The new values to be set """ dev = self.__get_device(device_id) - return await dev.async_OLD_setValues(func_code, address, values) + if isinstance(dev, ModbusSimulatorContext): # pragma: no cover + return await dev.async_OLD_setValues(func_code, address, values) + return ExcCodes.DEVICE_BUSY def device_ids(self): """Get the configured device ids.""" diff --git a/pymodbus/datastore/sequential.py b/pymodbus/datastore/sequential.py index 638e3b5c3..611773c3b 100644 --- a/pymodbus/datastore/sequential.py +++ b/pymodbus/datastore/sequential.py @@ -1,11 +1,11 @@ """Modbus Sequential Datastore.""" -# pylint: disable=missing-type-doc from __future__ import annotations -from ..constants import ExcCodes +from ..logging import Log +from ..simulator.simdata import DataType, SimData -class ModbusSequentialDataBlock: +class ModbusSequentialDataBlock: # pylint: disable=too-few-public-methods """Creates a sequential modbus datastore.""" def __init__(self, address, values): @@ -14,35 +14,8 @@ def __init__(self, address, values): :param address: The starting address of the datastore :param values: Either a list or a dictionary of values """ - self.address = address - if hasattr(values, "__iter__"): - self.values = list(values) - else: - self.values = [values] - - async def async_OLD_getValues(self, address, count=1) -> list[int] | list[bool] | ExcCodes: - """Return the requested values of the datastore. - - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - """ - start = address - self.address - if start < 0 or len(self.values) < start+count: - return ExcCodes.ILLEGAL_ADDRESS - return self.values[start : start + count] - - async def async_OLD_setValues(self, address, values) -> None | ExcCodes: - """Set the requested values of the datastore. - - :param address: The starting address - :param values: The new values to be set - """ - if not isinstance(values, list): - values = [values] - start = address - self.address - if start < 0 or len(self.values) < start+len(values): - return ExcCodes.ILLEGAL_ADDRESS - self.values[start : start + len(values)] = values - return None - + Log.warning("ModbusSequentialDataBlock is depreacated " + "and will be removed in v4.\n" + "Please convert to SimData/SimDevice.\n" + "Please read https://pymodbus.readthedocs.io/en/dev/source/upgrade_40.html#convert-to-simdata-simdevice") + self.simdata = [SimData(address, values=values, datatype=DataType.REGISTERS)] diff --git a/pymodbus/datastore/simulator.py b/pymodbus/datastore/simulator.py index c97467ea4..4c8c356f5 100644 --- a/pymodbus/datastore/simulator.py +++ b/pymodbus/datastore/simulator.py @@ -9,6 +9,7 @@ from typing import Any from ..constants import ExcCodes +from ..logging import Log WORD_SIZE = 16 @@ -487,6 +488,10 @@ def __init__( self.registerType_id_to_name: list[str] = [] if config: Setup(self).setup(config, custom_actions) + Log.warning("ModbusSimulatorContext is depreacated " + "and will be removed in v4.\n" + "Please convert to SimData/SimDevice.\n" + "Please read https://pymodbus.readthedocs.io/en/dev/source/upgrade_40.html#convert-to-simdata-simdevice") # -------------------------------------------- # Simulator server interface diff --git a/pymodbus/datastore/sparse.py b/pymodbus/datastore/sparse.py index 94b0c002c..dfb1eef2a 100644 --- a/pymodbus/datastore/sparse.py +++ b/pymodbus/datastore/sparse.py @@ -1,43 +1,30 @@ """Modbus Sparse Datastore.""" -# pylint: disable=missing-type-doc from __future__ import annotations -from ..constants import ExcCodes from ..exceptions import ParameterException +from ..logging import Log +from ..simulator.simdata import DataType, SimData -class ModbusSparseDataBlock: +class ModbusSparseDataBlock: # pylint: disable=too-few-public-methods """A sparse modbus datastore, silently redirected to ModbusSequentialBlock.""" def __init__(self, values=None, mutable=True): """Initialize a sparse datastore.""" - self.values: dict[int, list[int]] = {} + _ = mutable + self.simdata: list[SimData] = [] self._process_values(values) - self.mutable = mutable - - async def async_OLD_getValues(self, address, count=1) -> list[int] | list[bool] | ExcCodes: - """Return the requested values of the datastore. - - :param address: The starting address - :param count: The number of values to retrieve - :returns: The requested values from a:a+c - """ - try: - values = [self.values[i] for i in range(address, address + count)] - except KeyError: - return ExcCodes.ILLEGAL_ADDRESS - return values # type: ignore[return-value] + Log.warning("ModbusSparseDataBlock is depreacated " + "and will be removed in v4.\n" + "Please convert to SimData/SimDevice.\n" + "Please read https://pymodbus.readthedocs.io/en/dev/source/upgrade_40.html#convert-to-simdata-simdevice") def _process_values(self, values): """Process values.""" def _process_as_dict(values): for idx, val in iter(values.items()): - if isinstance(val, (list, tuple)): - for i, v_item in enumerate(val): - self.values[idx + i] = v_item - else: - self.values[idx] = int(val) # type: ignore[assignment] + self.simdata.append(SimData(idx, values=val, datatype=DataType.REGISTERS)) if isinstance(values, dict): _process_as_dict(values) @@ -52,33 +39,3 @@ def _process_as_dict(values): ) _process_as_dict(values) - async def async_OLD_setValues(self, address, values) -> None | ExcCodes: - """Set the requested values of the datastore. - - :param address: The register starting address - :param values: The new values to be set. - - Values can be given in different formats: - - a single register value or - - a list or tuple of contiguous register values, starting at - given starting register address or - - a dictionary of address:value(s) pairs, where value can be a - single register or a list or tuple of contiguous registers. - """ - try: - if isinstance(values, dict): - new_offsets = list(set(values.keys()) - set(self.values.keys())) - if new_offsets and not self.mutable: - raise ParameterException(f"Offsets {new_offsets} not in range") - self._process_values(values) - else: - if not isinstance(values, (list, tuple)): - values = [values] - for idx, val in enumerate(values): - if address + idx not in self.values and not self.mutable: - raise ParameterException("Offset {address+idx} not in range") - self.values[address + idx] = val - except KeyError: - return ExcCodes.ILLEGAL_ADDRESS - return None - diff --git a/pymodbus/pdu/bit_message.py b/pymodbus/pdu/bit_message.py index 5ac59478b..909f2f8aa 100644 --- a/pymodbus/pdu/bit_message.py +++ b/pymodbus/pdu/bit_message.py @@ -7,7 +7,8 @@ from ..datastore import ModbusServerContext from .decoders import DecodePDU from .exceptionresponse import ExceptionResponse -from .pdu import ModbusPDU, pack_bitstring, unpack_bitstring +from .pdu import ModbusPDU +from .utils import pack_bitstring, unpack_bitstring class ReadCoilsRequest(ModbusPDU): diff --git a/pymodbus/pdu/diag_message.py b/pymodbus/pdu/diag_message.py index 0d2cf8c7e..5ac1068a8 100644 --- a/pymodbus/pdu/diag_message.py +++ b/pymodbus/pdu/diag_message.py @@ -8,7 +8,8 @@ from ..datastore import ModbusServerContext from .decoders import DecodePDU from .device import ModbusControlBlock -from .pdu import ModbusPDU, pack_bitstring +from .pdu import ModbusPDU +from .utils import pack_bitstring _MCB = ModbusControlBlock() diff --git a/pymodbus/pdu/events.py b/pymodbus/pdu/events.py index cc971e2e1..15ccd1855 100644 --- a/pymodbus/pdu/events.py +++ b/pymodbus/pdu/events.py @@ -8,7 +8,7 @@ from abc import ABC, abstractmethod from ..exceptions import ParameterException -from .pdu import pack_bitstring, unpack_bitstring +from .utils import pack_bitstring, unpack_bitstring class ModbusEvent(ABC): diff --git a/pymodbus/pdu/pdu.py b/pymodbus/pdu/pdu.py index 419c7c56a..8c4252add 100644 --- a/pymodbus/pdu/pdu.py +++ b/pymodbus/pdu/pdu.py @@ -2,7 +2,6 @@ from __future__ import annotations import asyncio -import struct from ..datastore import ModbusServerContext from ..exceptions import ModbusIOException, NotImplementedException @@ -107,51 +106,3 @@ def calculateRtuFrameSize(cls, data: bytes) -> int: raise NotImplementedException( f"Cannot determine RTU frame size for {cls.__name__}" ) - - -def pack_bitstring(bits: list[bool], align_byte=True) -> bytes: - """Create a bytestring out of a list of bits. - - example:: - - bits = [True, False, False, False] + - [False, False, False, True] + - [True, False, True, False] + - [False, False, False, False] - result = pack_bitstring(bits) - bytes 0x05 0x81 - """ - ret = b"" - i = packed = 0 - t_bits = bits - bits_extra = 8 if align_byte else 16 - if (extra := len(bits) % bits_extra): - t_bits += [False] * (bits_extra - extra) - for byte_inx in range(0, len(t_bits), 8): - for bit in reversed(t_bits[byte_inx:byte_inx+8]): - packed <<= 1 - if bit: - packed += 1 - i += 1 - if i == 8: - ret += struct.pack(">B", packed) - i = packed = 0 - return ret - - -def unpack_bitstring(data: bytes) -> list[bool]: - """Create bit list out of a bytestring. - - example:: - - bytes 0x05 0x81 - result = unpack_bitstring(bytes) - - [True, False, True, False] + [False, False, False, False] - [True, False, False, False] + [False, False, False, True] - """ - res = [] - for _, t_byte in enumerate(data): - for bit in (1, 2, 4, 8, 16, 32, 64, 128): - res.append(bool(t_byte & bit)) - return res diff --git a/pymodbus/pdu/utils.py b/pymodbus/pdu/utils.py new file mode 100644 index 000000000..b523fa372 --- /dev/null +++ b/pymodbus/pdu/utils.py @@ -0,0 +1,52 @@ +"""Contains base classes for modbus request/response/error packets.""" +from __future__ import annotations + +import struct + + +def pack_bitstring(bits: list[bool], align_byte=True) -> bytes: + """Create a bytestring out of a list of bits. + + example:: + + bits = [True, False, False, False] + + [False, False, False, True] + + [True, False, True, False] + + [False, False, False, False] + result = pack_bitstring(bits) + bytes 0x05 0x81 + """ + ret = b"" + i = packed = 0 + t_bits = bits + bits_extra = 8 if align_byte else 16 + if (extra := len(bits) % bits_extra): + t_bits += [False] * (bits_extra - extra) + for byte_inx in range(0, len(t_bits), 8): + for bit in reversed(t_bits[byte_inx:byte_inx+8]): + packed <<= 1 + if bit: + packed += 1 + i += 1 + if i == 8: + ret += struct.pack(">B", packed) + i = packed = 0 + return ret + + +def unpack_bitstring(data: bytes) -> list[bool]: + """Create bit list out of a bytestring. + + example:: + + bytes 0x05 0x81 + result = unpack_bitstring(bytes) + + [True, False, True, False] + [False, False, False, False] + [True, False, False, False] + [False, False, False, True] + """ + res = [] + for _, t_byte in enumerate(data): + for bit in (1, 2, 4, 8, 16, 32, 64, 128): + res.append(bool(t_byte & bit)) + return res diff --git a/pymodbus/server/base.py b/pymodbus/server/base.py index be8981626..740522897 100644 --- a/pymodbus/server/base.py +++ b/pymodbus/server/base.py @@ -45,10 +45,12 @@ def __init__( # pylint: disable=too-many-arguments for func in custom_pdu: self.decoder.register(func) self.context: ModbusServerContext | SimCore - if isinstance(context, ModbusServerContext): - self.context = context - else: + if not isinstance(context, ModbusServerContext): self.context = SimCore(context) + elif context.simdevices: + self.context = SimCore(context.simdevices) + else: + self.context = context self.control = ModbusControlBlock() self.ignore_missing_devices = ignore_missing_devices self.broadcast_enable = broadcast_enable diff --git a/pymodbus/simulator/simdata.py b/pymodbus/simulator/simdata.py index 634ec9a1f..cf196a01a 100644 --- a/pymodbus/simulator/simdata.py +++ b/pymodbus/simulator/simdata.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from typing import TypeAlias, cast -from ..pdu.pdu import pack_bitstring, unpack_bitstring +from ..pdu.utils import pack_bitstring, unpack_bitstring from .simutils import DataType, SimUtils diff --git a/pymodbus/simulator/simruntime.py b/pymodbus/simulator/simruntime.py index d4908c7c3..a85411b75 100644 --- a/pymodbus/simulator/simruntime.py +++ b/pymodbus/simulator/simruntime.py @@ -5,7 +5,7 @@ from __future__ import annotations from ..constants import ExcCodes -from ..pdu.pdu import unpack_bitstring +from ..pdu.utils import unpack_bitstring from .simdevice import SimDevice, SimRegs from .simutils import DataType, SimUtils diff --git a/test/conftest.py b/test/conftest.py index b4a848dd5..965c4d0ed 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -4,12 +4,13 @@ import sys from collections import deque from threading import enumerate as thread_enumerate +from typing import cast import pytest import pytest_asyncio from pymodbus.constants import ExcCodes -from pymodbus.datastore import ModbusServerContext +from pymodbus.datastore import ModbusDeviceContext, ModbusServerContext from pymodbus.server import ServerAsyncStop from pymodbus.transport import NULLMODEM_HOST, CommParams, CommType from pymodbus.transport.transport import NullModem @@ -180,6 +181,8 @@ async def _check_system_health(): start_tasks = {task.get_name(): task for task in asyncio.all_tasks()} yield await asyncio.sleep(0.1) + all_clean = True + error_text = "" for count in range(10): all_clean = True error_text = f"ERROR tasks/threads hanging after {count} retries:\n" @@ -206,14 +209,14 @@ async def _check_system_health(): assert not NullModem.is_dirty() @pytest.fixture(name="mock_server_context") -def define_mock_servercontext(): +def define_mock_servercontext() -> ModbusServerContext: """Define context class.""" class MockServerContext(ModbusServerContext): """Mock context.""" def __init__(self, valid=False, default=True): """Initialize.""" - super().__init__() + super().__init__(devices=ModbusDeviceContext()) self.valid = valid self.default = default @@ -227,14 +230,14 @@ async def async_getValues(self, device_id, func_code, address, count=0): async def async_setValues(self, device_id, func_code, address, values): """Set values.""" - return MockServerContext + return cast(ModbusServerContext, MockServerContext) class MockLastValuesContext(ModbusServerContext): """Mock context.""" def __init__(self, valid=False, default=True): """Initialize.""" - super().__init__() + super().__init__(devices=ModbusDeviceContext()) self.valid = valid self.default = default self.last_values: list = [] diff --git a/test/datastore/test_context.py b/test/datastore/test_context.py index b0d38e0e8..5a9f6bd9d 100644 --- a/test/datastore/test_context.py +++ b/test/datastore/test_context.py @@ -1,6 +1,7 @@ """Test datastore context.""" import pytest +from pymodbus.constants import ExcCodes from pymodbus.datastore import ( ModbusDeviceContext, ModbusSequentialDataBlock, @@ -14,28 +15,26 @@ class TestContextDataStore: async def test_datastore_device_Values(self): """Test ModbusDeviceContext.""" - dev = ModbusDeviceContext() - await dev.async_OLD_getValues(0x01, 0x05) - await dev.async_OLD_setValues(0x05, 0x05, [17]) + ModbusDeviceContext() 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]) + ModbusDeviceContext(di=block, co=block, hr=block, ir=block) def test_datastore_server(self): """Test ModbusServerContext.""" - dev = ModbusServerContext() + dev = ModbusServerContext(devices=ModbusDeviceContext()) str(dev) - dev = ModbusServerContext(devices={}) - dev = ModbusServerContext(single=False) - dev = ModbusServerContext(devices={1: {}}, single=False) + dev = ModbusServerContext(devices=ModbusDeviceContext()) + dev = ModbusServerContext(devices=ModbusDeviceContext(), single=False) + dev = ModbusServerContext(devices={1: ModbusDeviceContext()}, single=False) + with pytest.raises(TypeError): + ModbusServerContext() def test_datastore_server_ids(self): """Test ModbusServerContext.""" - srv = ModbusServerContext() + srv = ModbusServerContext(devices=ModbusDeviceContext()) assert isinstance(srv.device_ids(), list) async def test_datastore_server_device_id(self): @@ -45,6 +44,14 @@ async def test_datastore_server_device_id(self): 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] + assert await srv.async_getValues(1, 0x03, 0) == ExcCodes.DEVICE_BUSY with pytest.raises(NoSuchIdException): await srv.async_getValues(15, 0, 0) + + + async def test_datastore_server_device_id_0(self): + """Test ModbusServerContext.""" + block = ModbusSequentialDataBlock(1, [17] * 8) + dev = ModbusDeviceContext(di=block, co=block, hr=block, ir=block) + srv = ModbusServerContext(devices={0: dev}, single=False) + await srv.async_getValues(15, 0x03, 0) diff --git a/test/datastore/test_sequential.py b/test/datastore/test_sequential.py index c82650ff0..7ef45eb05 100644 --- a/test/datastore/test_sequential.py +++ b/test/datastore/test_sequential.py @@ -1,6 +1,5 @@ """Test framers.""" -from pymodbus.constants import ExcCodes from pymodbus.datastore import ModbusSequentialDataBlock @@ -11,20 +10,3 @@ def test_datastore_Sequential(self): """Test ModbusDeviceContext.""" 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]) - assert await block.async_OLD_getValues(13) == ExcCodes.ILLEGAL_ADDRESS - - async def test_datastore_Sequential_set(self): - """Test ModbusDeviceContext.""" - block = ModbusSequentialDataBlock(0x01, [17]) - await block.async_OLD_setValues(1, [19]) - await block.async_OLD_setValues(1, 19) - assert await block.async_OLD_setValues(13, [17]) == ExcCodes.ILLEGAL_ADDRESS diff --git a/test/datastore/test_sparse_datastore.py b/test/datastore/test_sparse_datastore.py index 2508dfd40..871afbcd7 100644 --- a/test/datastore/test_sparse_datastore.py +++ b/test/datastore/test_sparse_datastore.py @@ -1,9 +1,7 @@ """Test framers.""" -from unittest import mock import pytest -from pymodbus.constants import ExcCodes from pymodbus.datastore import ModbusSparseDataBlock from pymodbus.exceptions import ParameterException @@ -28,51 +26,3 @@ def test_sparse_datastore(self): ModbusSparseDataBlock() with pytest.raises(ParameterException): ModbusSparseDataBlock(1) - - async def test_sparse_datastore_async(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock(self.data_in_block) - for key, entry in self.data_in_block.items(): - if isinstance(entry, int): - entry = [entry] - for value in entry: - assert await datablock.async_OLD_getValues(key, 1) == [value] - key += 1 - - async def test_sparse_datastore_check(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock(self.data_in_block) - for key, entry in self.data_in_block.items(): - if isinstance(entry, int): - entry = [entry] - for value in entry: - assert await datablock.async_OLD_getValues(key, 1) == [value] - key += 1 - - async def test_sparse_datastore_get(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock() - assert await datablock.async_OLD_getValues(117) == ExcCodes.ILLEGAL_ADDRESS - - async def test_sparse_datastore_set(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock(self.data_in_block) - assert not await datablock.async_OLD_setValues(1, {1: 5}) - assert not await datablock.async_OLD_setValues(1, [5]) - assert not await datablock.async_OLD_setValues(1, 5) - - async def test_sparse_datastore_async_set(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock(self.data_in_block) - assert not await datablock.async_OLD_setValues(1, [5]) - - async def test_sparse_datastore_set_not_ok(self): - """Test check frame.""" - datablock = ModbusSparseDataBlock(self.data_in_block, mutable=False) - with pytest.raises(ParameterException): - await datablock.async_OLD_setValues(1, {7: 5}) - with pytest.raises(ParameterException): - await datablock.async_OLD_setValues(1, [2, 3, 4]) - datablock = ModbusSparseDataBlock(self.data_in_block) - datablock._process_values = mock.Mock(side_effect=KeyError) # type: ignore[method-assign] - assert await datablock.async_OLD_setValues(30, {17: 0}) == ExcCodes.ILLEGAL_ADDRESS diff --git a/test/pdu/test_pdu.py b/test/pdu/test_pdu.py index 12e9e6b32..ae54ad272 100644 --- a/test/pdu/test_pdu.py +++ b/test/pdu/test_pdu.py @@ -15,7 +15,7 @@ ExceptionResponse, ModbusPDU, ) -from pymodbus.pdu.pdu import pack_bitstring, unpack_bitstring +from pymodbus.pdu.utils import pack_bitstring, unpack_bitstring class TestPdu: diff --git a/test/server/test_base.py b/test/server/test_base.py index 3849dc872..3c3f86774 100755 --- a/test/server/test_base.py +++ b/test/server/test_base.py @@ -3,7 +3,7 @@ import pytest -from pymodbus.datastore import ModbusServerContext +from pymodbus.datastore import ModbusDeviceContext, ModbusServerContext from pymodbus.framer import FramerType from pymodbus.pdu import ReadHoldingRegistersRequest from pymodbus.server import ModbusBaseServer @@ -25,7 +25,7 @@ async def baseserver(self): reconnect_delay_max=0.0, timeout_connect=0.0, ), - ModbusServerContext(), + ModbusServerContext(devices=ModbusDeviceContext()), False, False, None,