diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py index 1f930d5e3..5481ffbea 100644 --- a/pymodbus/client/base.py +++ b/pymodbus/client/base.py @@ -22,7 +22,7 @@ class ModbusBaseClient(ModbusClientMixin[Awaitable[ModbusPDU]]): def __init__( self, - framer: FramerType, + framer: FramerType | type[FramerBase], retries: int, comm_params: CommParams, trace_packet: Callable[[bool, bytes], bytes] | None, @@ -35,9 +35,11 @@ def __init__( """ ModbusClientMixin.__init__(self) # type: ignore[arg-type] self.comm_params = comm_params + if not isinstance(framer, type) or not issubclass(framer, FramerBase): + framer = FRAMER_NAME_TO_CLASS[FramerType(framer)] self.ctx = TransactionManager( comm_params, - (FRAMER_NAME_TO_CLASS[framer])(DecodePDU(False)), + framer(DecodePDU(False)), retries, False, trace_packet, @@ -116,7 +118,7 @@ class ModbusBaseSyncClient(ModbusClientMixin[ModbusPDU]): def __init__( self, - framer: FramerType, + framer: FramerType | type[FramerBase], retries: int, comm_params: CommParams, trace_packet: Callable[[bool, bytes], bytes] | None, @@ -133,7 +135,9 @@ def __init__( self.slaves: list[int] = [] # Common variables. - self.framer: FramerBase = (FRAMER_NAME_TO_CLASS[framer])(DecodePDU(False)) + if not isinstance(framer, type) or not issubclass(framer, FramerBase): + framer = FRAMER_NAME_TO_CLASS[FramerType(framer)] + self.framer: FramerBase = framer(DecodePDU(False)) self.transaction = TransactionManager( self.comm_params, self.framer, diff --git a/pymodbus/pdu/__init__.py b/pymodbus/pdu/__init__.py index 952bd9ade..3d6838e7a 100644 --- a/pymodbus/pdu/__init__.py +++ b/pymodbus/pdu/__init__.py @@ -2,7 +2,6 @@ __all__ = [ "DecodePDU", "ExceptionResponse", - "ExceptionResponse", "FileRecord", "ModbusPDU", ] diff --git a/pymodbus/server/async_io.py b/pymodbus/server/async_io.py index 79e52a9b3..35039ea52 100644 --- a/pymodbus/server/async_io.py +++ b/pymodbus/server/async_io.py @@ -10,7 +10,7 @@ from pymodbus.datastore import ModbusServerContext from pymodbus.device import ModbusControlBlock, ModbusDeviceIdentification from pymodbus.exceptions import NoSuchSlaveException -from pymodbus.framer import FRAMER_NAME_TO_CLASS, FramerType +from pymodbus.framer import FRAMER_NAME_TO_CLASS, FramerBase, FramerType from pymodbus.logging import Log from pymodbus.pdu import DecodePDU, ModbusPDU from pymodbus.pdu.pdu import ExceptionResponse @@ -166,9 +166,10 @@ async def server_async_execute(self, request, *addr): response = await request.update_datastore(context) except NoSuchSlaveException: - Log.error("requested slave does not exist: {}", request.dev_id) if self.server.ignore_missing_slaves: + Log.debug("ignored slave that does not exist: {}", request.slave_id) return # the client will simply timeout waiting for a response + Log.error("requested slave does not exist: {}", request.slave_id) response = ExceptionResponse(0x00, ExceptionResponse.GATEWAY_NO_RESPONSE) except Exception as exc: # pylint: disable=broad-except Log.error( @@ -201,7 +202,7 @@ def __init__( ignore_missing_slaves: bool, broadcast_enable: bool, identity: ModbusDeviceIdentification | None, - framer: FramerType, + framer: FramerType | type[FramerBase], trace_packet: Callable[[bool, bytes], bytes] | None, trace_pdu: Callable[[bool, ModbusPDU], ModbusPDU] | None, trace_connect: Callable[[bool], None] | None, @@ -223,8 +224,10 @@ def __init__( self.handle_local_echo = False if isinstance(identity, ModbusDeviceIdentification): self.control.Identity.update(identity) - - self.framer = FRAMER_NAME_TO_CLASS[framer] + # Support mapping of FramerType to a Framer class, or a Framer class + if not isinstance(framer, type) or not issubclass(framer, FramerBase): + framer = FRAMER_NAME_TO_CLASS[FramerType(framer)] + self.framer = framer self.serving: asyncio.Future = asyncio.Future() def callback_new_connection(self): @@ -273,7 +276,7 @@ def __init__( self, context: ModbusServerContext, *, - framer=FramerType.SOCKET, + framer: FramerType | type[FramerBase] = FramerType.SOCKET, identity: ModbusDeviceIdentification | None = None, address: tuple[str, int] = ("", 502), ignore_missing_slaves: bool = False, @@ -336,7 +339,7 @@ def __init__( # pylint: disable=too-many-arguments self, context: ModbusServerContext, *, - framer=FramerType.TLS, + framer: FramerType | type[FramerBase] = FramerType.TLS, identity: ModbusDeviceIdentification | None = None, address: tuple[str, int] = ("", 502), sslctx=None, @@ -403,7 +406,7 @@ def __init__( self, context: ModbusServerContext, *, - framer=FramerType.SOCKET, + framer: FramerType | type[FramerBase] = FramerType.SOCKET, identity: ModbusDeviceIdentification | None = None, address: tuple[str, int] = ("", 502), ignore_missing_slaves: bool = False, @@ -463,7 +466,7 @@ def __init__( self, context: ModbusServerContext, *, - framer: FramerType = FramerType.RTU, + framer: FramerType | type[FramerBase] = FramerType.RTU, ignore_missing_slaves: bool = False, identity: ModbusDeviceIdentification | None = None, broadcast_enable: bool = False,