diff --git a/pymodbus/client/base.py b/pymodbus/client/base.py index 95dcaf1a4..90cbecc2d 100644 --- a/pymodbus/client/base.py +++ b/pymodbus/client/base.py @@ -3,6 +3,7 @@ import asyncio import socket +from abc import abstractmethod from collections.abc import Awaitable, Callable from dataclasses import dataclass from typing import Any, cast @@ -14,7 +15,7 @@ from pymodbus.framer import FRAMER_NAME_TO_CLASS, FramerType, ModbusFramer from pymodbus.logging import Log from pymodbus.pdu import ModbusRequest, ModbusResponse -from pymodbus.transaction import ModbusTransactionManager +from pymodbus.transaction import SyncModbusTransactionManager from pymodbus.transport import CommParams from pymodbus.utilities import ModbusTransactionState @@ -53,7 +54,6 @@ def __init__( framer: FramerType, timeout: float = 3, retries: int = 3, - retry_on_empty: bool = False, broadcast_enable: bool = False, reconnect_delay: float = 0.1, reconnect_delay_max: float = 300, @@ -81,8 +81,6 @@ def __init__( stopbits=kwargs.get("stopbits", None), handle_local_echo=kwargs.get("handle_local_echo", False), ), - retries, - retry_on_empty, on_connect_callback, ) self.no_resend_on_retry = no_resend_on_retry @@ -143,7 +141,7 @@ def idle_time(self) -> float: return 0 return self.last_frame_end + self.silent_interval - def execute(self, request: ModbusRequest | None = None): + def execute(self, request: ModbusRequest): """Execute request and get response (call **sync/async**). :param request: The request to process @@ -165,7 +163,7 @@ async def async_execute(self, request) -> ModbusResponse: count = 0 while count <= self.retries: async with self._lock: - req = self.build_response(request.transaction_id) + req = self.build_response(request) if not count or not self.no_resend_on_retry: self.ctx.framer.resetFrame() self.ctx.send(packet) @@ -187,25 +185,17 @@ async def async_execute(self, request) -> ModbusResponse: return resp # type: ignore[return-value] - def build_response(self, tid): + def build_response(self, request: ModbusRequest): """Return a deferred response for the current request.""" my_future: asyncio.Future = asyncio.Future() + request.fut = my_future if not self.ctx.transport: if not my_future.done(): my_future.set_exception(ConnectionException("Client is not connected")) else: - self.ctx.transaction.addTransaction(my_future, tid) + self.ctx.transaction.addTransaction(request) return my_future - # ----------------------------------------------------------------------- # - # Internal methods - # ----------------------------------------------------------------------- # - def recv(self, size): - """Receive data. - - :meta private: - """ - # ----------------------------------------------------------------------- # # The magic methods # ----------------------------------------------------------------------- # @@ -309,10 +299,10 @@ def __init__( self.slaves: list[int] = [] # Common variables. - self.framer = FRAMER_NAME_TO_CLASS.get( + self.framer: ModbusFramer = FRAMER_NAME_TO_CLASS.get( framer, cast(type[ModbusFramer], framer) )(ClientDecoder(), self) - self.transaction = ModbusTransactionManager( + self.transaction = SyncModbusTransactionManager( self, retries=retries, retry_on_empty=retry_on_empty, **kwargs ) self.reconnect_delay_current = self.params.reconnect_delay or 0 @@ -346,7 +336,7 @@ def idle_time(self) -> float: return 0 return self.last_frame_end + self.silent_interval - def execute(self, request: ModbusRequest | None = None) -> ModbusResponse: + def execute(self, request: ModbusRequest) -> ModbusResponse: """Execute request and get response (call **sync/async**). :param request: The request to process @@ -360,7 +350,7 @@ def execute(self, request: ModbusRequest | None = None) -> ModbusResponse: # ----------------------------------------------------------------------- # # Internal methods # ----------------------------------------------------------------------- # - def send(self, request): + def _start_send(self): """Send request. :meta private: @@ -368,14 +358,20 @@ def send(self, request): if self.state != ModbusTransactionState.RETRYING: Log.debug('New Transaction state "SENDING"') self.state = ModbusTransactionState.SENDING - return request - def recv(self, size): + @abstractmethod + def send(self, request: bytes) -> int: + """Send request. + + :meta private: + """ + + @abstractmethod + def recv(self, size: int | None) -> bytes: """Receive data. :meta private: """ - return size @classmethod def get_address_family(cls, address): diff --git a/pymodbus/client/modbusclientprotocol.py b/pymodbus/client/modbusclientprotocol.py index f95fff75d..c5d935076 100644 --- a/pymodbus/client/modbusclientprotocol.py +++ b/pymodbus/client/modbusclientprotocol.py @@ -29,8 +29,6 @@ def __init__( self, framer: FramerType, params: CommParams, - retries: int, - retry_on_empty: bool, on_connect_callback: Callable[[bool], None] | None = None, ) -> None: """Initialize a client instance.""" @@ -45,17 +43,16 @@ def __init__( self.framer = FRAMER_NAME_TO_CLASS.get( framer, cast(type[ModbusFramer], framer) )(ClientDecoder(), self) - self.transaction = ModbusTransactionManager( - self, retries=retries, retry_on_empty=retry_on_empty - ) + self.transaction = ModbusTransactionManager() def _handle_response(self, reply, **_kwargs): """Handle the processed response and link to correct deferred.""" if reply is not None: tid = reply.transaction_id if handler := self.transaction.getTransaction(tid): - if not handler.done(): - handler.set_result(reply) + reply.request = handler + if not handler.fut.done(): + handler.fut.set_result(reply) else: Log.debug("Unrequested message: {}", reply, ":str") diff --git a/pymodbus/client/serial.py b/pymodbus/client/serial.py index 0fb4c6034..2872b7d57 100644 --- a/pymodbus/client/serial.py +++ b/pymodbus/client/serial.py @@ -193,7 +193,7 @@ def connected(self): """Connect internal.""" return self.connect() - def connect(self): + def connect(self) -> bool: """Connect to the modbus serial server.""" if self.socket: return True @@ -227,25 +227,26 @@ def _in_waiting(self): """Return waiting bytes.""" return getattr(self.socket, "in_waiting") if hasattr(self.socket, "in_waiting") else getattr(self.socket, "inWaiting")() - def send(self, request): + def send(self, request: bytes) -> int: """Send data on the underlying socket. If receive buffer still holds some data then flush it. Sleep if last send finished less than 3.5 character times ago. """ - super().send(request) + super()._start_send() if not self.socket: raise ConnectionException(str(self)) if request: if waitingbytes := self._in_waiting(): result = self.socket.read(waitingbytes) Log.warning("Cleanup recv buffer before send: {}", result, ":hex") - size = self.socket.write(request) + if (size := self.socket.write(request)) is None: + size = 0 return size return 0 - def _wait_for_data(self): + def _wait_for_data(self) -> int: """Wait for data.""" size = 0 more_data = False @@ -264,9 +265,8 @@ def _wait_for_data(self): time.sleep(self._recv_interval) return size - def recv(self, size): + def recv(self, size: int | None) -> bytes: """Read data from the underlying descriptor.""" - super().recv(size) if not self.socket: raise ConnectionException(str(self)) if size is None: @@ -276,7 +276,7 @@ def recv(self, size): result = self.socket.read(size) return result - def is_socket_open(self): + def is_socket_open(self) -> bool: """Check if socket is open.""" if self.socket: return self.socket.is_open diff --git a/pymodbus/client/tcp.py b/pymodbus/client/tcp.py index aa71c9e40..d975482eb 100644 --- a/pymodbus/client/tcp.py +++ b/pymodbus/client/tcp.py @@ -180,16 +180,15 @@ def close(self): def send(self, request): """Send data on the underlying socket.""" - super().send(request) + super()._start_send() if not self.socket: raise ConnectionException(str(self)) if request: return self.socket.send(request) return 0 - def recv(self, size): + def recv(self, size: int | None) -> bytes: """Read data from the underlying descriptor.""" - super().recv(size) if not self.socket: raise ConnectionException(str(self)) @@ -241,7 +240,7 @@ def recv(self, size): return b"".join(data) - def _handle_abrupt_socket_close(self, size, data, duration): + def _handle_abrupt_socket_close(self, size: int | None, data: list[bytes], duration: float) -> bytes: """Handle unexpected socket close by remote end. Intended to be invoked after determining that the remote end @@ -271,7 +270,7 @@ def _handle_abrupt_socket_close(self, size, data, duration): msg += " without response from slave before it closed connection" raise ConnectionException(msg) - def is_socket_open(self): + def is_socket_open(self) -> bool: """Check if socket is open.""" return self.socket is not None diff --git a/pymodbus/client/udp.py b/pymodbus/client/udp.py index 4f2f3d2df..acadf1ab5 100644 --- a/pymodbus/client/udp.py +++ b/pymodbus/client/udp.py @@ -169,12 +169,12 @@ def close(self): """ self.socket = None - def send(self, request): + def send(self, request: bytes) -> int: """Send data on the underlying socket. :meta private: """ - super().send(request) + super()._start_send() if not self.socket: raise ConnectionException(str(self)) if request: @@ -183,14 +183,15 @@ def send(self, request): ) return 0 - def recv(self, size): + def recv(self, size: int | None) -> bytes: """Read data from the underlying descriptor. :meta private: """ - super().recv(size) if not self.socket: raise ConnectionException(str(self)) + if size is None: + size = 0 return self.socket.recvfrom(size)[0] def is_socket_open(self): diff --git a/pymodbus/framer/old_framer_base.py b/pymodbus/framer/old_framer_base.py index 4922be1c4..8f5a9be2a 100644 --- a/pymodbus/framer/old_framer_base.py +++ b/pymodbus/framer/old_framer_base.py @@ -3,13 +3,17 @@ from __future__ import annotations import time -from typing import Any +from typing import TYPE_CHECKING, Any from pymodbus.factory import ClientDecoder, ServerDecoder from pymodbus.framer.base import FramerBase from pymodbus.logging import Log +from pymodbus.pdu import ModbusRequest +if TYPE_CHECKING: + from pymodbus.client.base import ModbusBaseSyncClient + # Unit ID, Function Code BYTE_ORDER = ">" FRAME_HEADER = "BB" @@ -29,7 +33,7 @@ class ModbusFramer: def __init__( self, decoder: ClientDecoder | ServerDecoder, - client, + client: ModbusBaseSyncClient, ) -> None: """Initialize a new instance of the framer. @@ -37,7 +41,13 @@ def __init__( """ self.decoder = decoder self.client = client - self._header: dict[str, Any] = { + self._header: dict[str, Any] + self._reset_header() + self._buffer = b"" + self.message_handler: FramerBase + + def _reset_header(self) -> None: + self._header = { "lrc": "0000", "len": 0, "uid": 0x00, @@ -45,8 +55,6 @@ def __init__( "pid": 0, "crc": b"\x00\x00", } - self._buffer = b"" - self.message_handler: FramerBase def _validate_slave_id(self, slaves: list, single: bool) -> bool: """Validate if the received data is valid for the client. @@ -63,7 +71,7 @@ def _validate_slave_id(self, slaves: list, single: bool) -> bool: return True return self._header["uid"] in slaves - def sendPacket(self, message): + def sendPacket(self, message: bytes): """Send packets on the bus. With 3.5char delay between frames @@ -72,7 +80,7 @@ def sendPacket(self, message): """ return self.client.send(message) - def recvPacket(self, size): + def recvPacket(self, size: int) -> bytes: """Receive packet from the bus. With specified len @@ -117,7 +125,7 @@ def populateResult(self, result): result.transaction_id = self._header.get("tid", 0) result.protocol_id = self._header.get("pid", 0) - def processIncomingPacket(self, data, callback, slave, **kwargs): + def processIncomingPacket(self, data: bytes, callback, slave, **kwargs): """Process new packet pattern. This takes in a new request packet, adds it to the current @@ -150,7 +158,7 @@ def frameProcessIncomingPacket( ) -> None: """Process new packet pattern.""" - def buildPacket(self, message) -> bytes: + def buildPacket(self, message: ModbusRequest) -> bytes: """Create a ready to send modbus packet. :param message: The populated request/response to send diff --git a/pymodbus/framer/old_framer_rtu.py b/pymodbus/framer/old_framer_rtu.py index 024dba269..ccd293352 100644 --- a/pymodbus/framer/old_framer_rtu.py +++ b/pymodbus/framer/old_framer_rtu.py @@ -146,7 +146,7 @@ def check_frame(self): Log.debug("Frame check failed, ignoring!!") x = self._buffer self.resetFrame() - self._buffer = x + self._buffer: bytes = x skip_cur_frame = True continue start = self._hsize @@ -176,7 +176,7 @@ def buildPacket(self, message): message.transaction_id = 0 return packet - def sendPacket(self, message): + def sendPacket(self, message: bytes) -> int: """Send packets on the bus with 3.5char delay between frames. :param message: Message to be sent over the bus diff --git a/pymodbus/framer/old_framer_socket.py b/pymodbus/framer/old_framer_socket.py index bc515ab2a..e812fdda9 100644 --- a/pymodbus/framer/old_framer_socket.py +++ b/pymodbus/framer/old_framer_socket.py @@ -88,8 +88,8 @@ def frameProcessIncomingPacket(self, single, callback, slave, tid=None, **kwargs self.resetFrame() raise ModbusIOException("Unable to decode request") self.populateResult(result) - self._buffer = self._buffer[used_len:] - self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0} + self._buffer: bytes = self._buffer[used_len:] + self._reset_header() if tid and tid != result.transaction_id: self.resetFrame() else: diff --git a/pymodbus/framer/old_framer_tls.py b/pymodbus/framer/old_framer_tls.py index a6a4df892..71e0a5a9d 100644 --- a/pymodbus/framer/old_framer_tls.py +++ b/pymodbus/framer/old_framer_tls.py @@ -64,6 +64,6 @@ def frameProcessIncomingPacket(self, _single, callback, _slave, _tid=None, **kwa self.resetFrame() raise ModbusIOException("Unable to decode request") self.populateResult(result) - self._buffer = self._buffer[used_len:] - self._header = {"tid": 0, "pid": 0, "len": 0, "uid": 0} + self._buffer: bytes = self._buffer[used_len:] + self._reset_header() callback(result) # defer or push to a thread? diff --git a/pymodbus/pdu/pdu.py b/pymodbus/pdu/pdu.py index c50cf281a..b430d5740 100644 --- a/pymodbus/pdu/pdu.py +++ b/pymodbus/pdu/pdu.py @@ -102,12 +102,13 @@ class ModbusRequest(ModbusPDU): function_code = -1 - def __init__(self, slave=0, **kwargs): # pylint: disable=useless-parent-delegation + def __init__(self, slave=0, **kwargs): """Proxy to the lower level initializer. :param slave: Modbus slave slave ID """ super().__init__(slave, **kwargs) + self.fut = None def doException(self, exception): """Build an error response based on the function. @@ -146,6 +147,7 @@ def __init__(self, slave=0, **kwargs): super().__init__(slave, **kwargs) self.bits = [] self.registers = [] + self.request = None def isError(self) -> bool: """Check if the error is a success or failure.""" diff --git a/pymodbus/transaction.py b/pymodbus/transaction.py index 09f648270..914edb7bb 100644 --- a/pymodbus/transaction.py +++ b/pymodbus/transaction.py @@ -1,4 +1,6 @@ """Collection of transaction based abstractions.""" +from __future__ import annotations + __all__ = [ "ModbusTransactionManager", @@ -6,14 +8,14 @@ "ModbusTlsFramer", "ModbusRtuFramer", "ModbusAsciiFramer", + "SyncModbusTransactionManager", ] -# pylint: disable=missing-type-doc import struct import time from contextlib import suppress -from functools import partial from threading import RLock +from typing import TYPE_CHECKING from pymodbus.exceptions import ( ConnectionException, @@ -27,15 +29,96 @@ ModbusTlsFramer, ) from pymodbus.logging import Log +from pymodbus.pdu import ModbusRequest +from pymodbus.transport import CommType from pymodbus.utilities import ModbusTransactionState, hexlify_packets +if TYPE_CHECKING: + from pymodbus.client.base import ModbusBaseSyncClient + + # --------------------------------------------------------------------------- # # The Global Transaction Manager # --------------------------------------------------------------------------- # class ModbusTransactionManager: """Implement a transaction for a manager. + Results are keyed based on the supplied transaction id. + """ + + def __init__(self): + """Initialize an instance of the ModbusTransactionManager.""" + self.tid = 0 + self.transactions: dict[int, ModbusRequest] = {} + + def __iter__(self): + """Iterate over the current managed transactions. + + :returns: An iterator of the managed transactions + """ + return iter(self.transactions.keys()) + + def addTransaction(self, request: ModbusRequest): + """Add a transaction to the handler. + + This holds the request in case it needs to be resent. + After being sent, the request is removed. + + :param request: The request to hold on to + """ + tid = request.transaction_id + Log.debug("Adding transaction {}", tid) + self.transactions[tid] = request + + def getTransaction(self, tid: int): + """Return a transaction matching the referenced tid. + + If the transaction does not exist, None is returned + + :param tid: The transaction to retrieve + + """ + Log.debug("Getting transaction {}", tid) + if not tid: + if self.transactions: + ret = self.transactions.popitem()[1] + self.transactions.clear() + return ret + return None + return self.transactions.pop(tid, None) + + def delTransaction(self, tid: int): + """Remove a transaction matching the referenced tid. + + :param tid: The transaction to remove + """ + Log.debug("deleting transaction {}", tid) + self.transactions.pop(tid, None) + + def getNextTID(self) -> int: + """Retrieve the next unique transaction identifier. + + This handles incrementing the identifier after + retrieval + + :returns: The next unique transaction identifier + """ + if self.tid < 65000: + self.tid += 1 + else: + self.tid = 1 + return self.tid + + def reset(self): + """Reset the transaction identifier.""" + self.tid = 0 + self.transactions = {} + + +class SyncModbusTransactionManager(ModbusTransactionManager): + """Implement a transaction for a manager. + The transaction protocol can be represented by the following pseudo code:: count = 0 @@ -51,32 +134,24 @@ class ModbusTransactionManager: Results are keyed based on the supplied transaction id. """ - def __init__(self, client, **kwargs): + def __init__(self, client: ModbusBaseSyncClient, **kwargs): """Initialize an instance of the ModbusTransactionManager. :param client: The client socket wrapper :param retry_on_empty: Should the client retry on empty :param retries: The number of retries to allow """ - self.tid = 0 - self.client = client + super().__init__() + self.client: ModbusBaseSyncClient = client self.backoff = kwargs.get("backoff", 0.3) self.retry_on_empty = kwargs.get("retry_on_empty", False) self.retry_on_invalid = kwargs.get("retry_on_invalid", False) self.retries = kwargs.get("retries", 3) - self.transactions = {} self._transaction_lock = RLock() - self._no_response_devices = [] + self._no_response_devices: list[int] = [] if client: self._set_adu_size() - def __iter__(self): - """Iterate over the current managed transactions. - - :returns: An iterator of the managed transactions - """ - return iter(self.transactions.keys()) - def _set_adu_size(self): """Set adu size.""" # base ADU size of modbus frame in bytes @@ -107,7 +182,7 @@ def _calculate_exception_length(self): return self.base_adu_size + 2 # Fcode(1), ExceptionCode(1) return None - def _validate_response(self, request, response, exp_resp_len, is_udp=False): + def _validate_response(self, request: ModbusRequest, response, exp_resp_len, is_udp=False): """Validate Incoming response against request. :param request: Request sent @@ -118,7 +193,10 @@ def _validate_response(self, request, response, exp_resp_len, is_udp=False): if not response: return False - mbap = self.client.framer.decode_data(response) + if hasattr(self.client.framer, "decode_data"): + mbap = self.client.framer.decode_data(response) + else: + mbap = {} if ( mbap.get("slave") != request.slave_id or mbap.get("fcode") & 0x7F != request.function_code @@ -129,7 +207,7 @@ def _validate_response(self, request, response, exp_resp_len, is_udp=False): return mbap.get("length") == exp_resp_len return True - def execute(self, request): # noqa: C901 + def execute(self, request: ModbusRequest): # noqa: C901 """Start the producer to send the next request to consumer.write(Frame(request)).""" with self._transaction_lock: try: @@ -167,9 +245,8 @@ def execute(self, request): # noqa: C901 full = True else: full = False - c_str = str(self.client) is_udp = False - if "modbusudpclient" in c_str.lower().strip(): + if self.client.comm_params.comm_type == CommType.UDP: is_udp = True full = True if not expected_response_length: @@ -221,13 +298,9 @@ def execute(self, request): # noqa: C901 break # full = False Log.debug("Retry getting response: - {}", _buffer) - addTransaction = partial( # pylint: disable=invalid-name - self.addTransaction, - tid=request.transaction_id, - ) self.client.framer.processIncomingPacket( response, - addTransaction, + self.addTransaction, request.slave_id, tid=request.transaction_id, ) @@ -278,7 +351,7 @@ def _retry_transaction(self, retries, reason, packet, response_length, full=Fals return result, None return self._transact(packet, response_length, full=full) - def _transact(self, packet, response_length, full=False, broadcast=False): + def _transact(self, request: ModbusRequest, response_length, full=False, broadcast=False): """Do a Write and Read transaction. :param packet: packet to be sent @@ -291,7 +364,7 @@ def _transact(self, packet, response_length, full=False, broadcast=False): last_exception = None try: self.client.connect() - packet = self.client.framer.buildPacket(packet) + packet = self.client.framer.buildPacket(request) Log.debug("SEND: {}", packet, ":hex") size = self._send(packet) if ( @@ -331,11 +404,11 @@ def _transact(self, packet, response_length, full=False, broadcast=False): result = b"" return result, last_exception - def _send(self, packet, _retrying=False): + def _send(self, packet: bytes, _retrying=False): """Send.""" return self.client.framer.sendPacket(packet) - def _recv(self, expected_response_length, full): # noqa: C901 + def _recv(self, expected_response_length, full) -> bytes: # noqa: C901 """Receive.""" total = None if not full: @@ -419,7 +492,7 @@ def _recv(self, expected_response_length, full): # noqa: C901 self.client.state = ModbusTransactionState.PROCESSING_REPLY return result - def _get_expected_response_length(self, data): + def _get_expected_response_length(self, data) -> int: """Get the expected response length. :param data: Message data read so far @@ -429,60 +502,3 @@ def _get_expected_response_length(self, data): func_code = int(data[1]) pdu_class = self.client.framer.decoder.lookupPduClass(func_code) return pdu_class.calculateRtuFrameSize(data) - - def addTransaction(self, request, tid=None): - """Add a transaction to the handler. - - This holds the request in case it needs to be resent. - After being sent, the request is removed. - - :param request: The request to hold on to - :param tid: The overloaded transaction id to use - """ - tid = tid if tid is not None else request.transaction_id - Log.debug("Adding transaction {}", tid) - self.transactions[tid] = request - - def getTransaction(self, tid): - """Return a transaction matching the referenced tid. - - If the transaction does not exist, None is returned - - :param tid: The transaction to retrieve - - """ - Log.debug("Getting transaction {}", tid) - if not tid: - if self.transactions: - ret = self.transactions.popitem()[1] - self.transactions.clear() - return ret - return None - return self.transactions.pop(tid, None) - - def delTransaction(self, tid): - """Remove a transaction matching the referenced tid. - - :param tid: The transaction to remove - """ - Log.debug("deleting transaction {}", tid) - self.transactions.pop(tid, None) - - def getNextTID(self): - """Retrieve the next unique transaction identifier. - - This handles incrementing the identifier after - retrieval - - :returns: The next unique transaction identifier - """ - if self.tid < 65000: - self.tid += 1 - else: - self.tid = 1 - return self.tid - - def reset(self): - """Reset the transaction identifier.""" - self.tid = 0 - self.transactions = {} diff --git a/pymodbus/transport/transport.py b/pymodbus/transport/transport.py index 265d98e1d..ee0cf64f5 100644 --- a/pymodbus/transport/transport.py +++ b/pymodbus/transport/transport.py @@ -83,7 +83,7 @@ class CommParams: comm_type: CommType | None = None reconnect_delay: float | None = None reconnect_delay_max: float = 0.0 - timeout_connect: float | None = None + timeout_connect: float = 0.0 host: str = "localhost" # On some machines this will now be ::1 port: int = 0 source_address: tuple[str, int] | None = None diff --git a/test/framers/test_tbc_transaction.py b/test/framers/test_tbc_transaction.py index b072909f8..2dd0405dc 100755 --- a/test/framers/test_tbc_transaction.py +++ b/test/framers/test_tbc_transaction.py @@ -12,7 +12,7 @@ ModbusRtuFramer, ModbusSocketFramer, ModbusTlsFramer, - ModbusTransactionManager, + SyncModbusTransactionManager, ) @@ -42,7 +42,7 @@ def setup_method(self): self._tls = ModbusTlsFramer(decoder=self.decoder, client=None) self._rtu = ModbusRtuFramer(decoder=self.decoder, client=None) self._ascii = ModbusAsciiFramer(decoder=self.decoder, client=None) - self._manager = ModbusTransactionManager(self.client) + self._manager = SyncModbusTransactionManager(self.client) # ----------------------------------------------------------------------- # # Modbus transaction manager @@ -113,7 +113,7 @@ def test_execute(self, mock_time): request.get_response_pdu_size.return_value = 10 request.slave_id = 1 request.function_code = 222 - trans = ModbusTransactionManager(client) + trans = SyncModbusTransactionManager(client) trans._recv = mock.MagicMock( # pylint: disable=protected-access return_value=b"abcdef" ) diff --git a/test/sub_client/test_client.py b/test/sub_client/test_client.py index 04ea7828f..a6f07fe04 100755 --- a/test/sub_client/test_client.py +++ b/test/sub_client/test_client.py @@ -262,7 +262,7 @@ async def test_client_instanciate( client.connect = lambda: False client.transport = None with pytest.raises(ConnectionException): - client.execute() + client.execute(ModbusRequest()) async def test_serial_not_installed(): """Try to instantiate clients.""" @@ -371,7 +371,7 @@ async def test_client_protocol_handler(): reply.transaction_id = 0x00 base.ctx._handle_response(None) # pylint: disable=protected-access base.ctx._handle_response(reply) # pylint: disable=protected-access - response = base.build_response(0x00) # pylint: disable=protected-access + response = base.build_response(reply) # pylint: disable=protected-access base.ctx._handle_response(reply) # pylint: disable=protected-access result = response.result() assert result == reply @@ -647,7 +647,7 @@ async def test_client_build_response(): """Test fail of build_response.""" client = ModbusBaseClient(FramerType.RTU) with pytest.raises(ConnectionException): - await client.build_response(0) + await client.build_response(ModbusRequest(transaction=0)) async def test_client_mixin_execute(): diff --git a/test/test_transaction.py b/test/test_transaction.py index b072909f8..2dd0405dc 100755 --- a/test/test_transaction.py +++ b/test/test_transaction.py @@ -12,7 +12,7 @@ ModbusRtuFramer, ModbusSocketFramer, ModbusTlsFramer, - ModbusTransactionManager, + SyncModbusTransactionManager, ) @@ -42,7 +42,7 @@ def setup_method(self): self._tls = ModbusTlsFramer(decoder=self.decoder, client=None) self._rtu = ModbusRtuFramer(decoder=self.decoder, client=None) self._ascii = ModbusAsciiFramer(decoder=self.decoder, client=None) - self._manager = ModbusTransactionManager(self.client) + self._manager = SyncModbusTransactionManager(self.client) # ----------------------------------------------------------------------- # # Modbus transaction manager @@ -113,7 +113,7 @@ def test_execute(self, mock_time): request.get_response_pdu_size.return_value = 10 request.slave_id = 1 request.function_code = 222 - trans = ModbusTransactionManager(client) + trans = SyncModbusTransactionManager(client) trans._recv = mock.MagicMock( # pylint: disable=protected-access return_value=b"abcdef" )