Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions pymodbus/client/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from pymodbus.pdu import DecodePDU, ModbusPDU
from pymodbus.transaction import TransactionManager
from pymodbus.transport import CommParams
from pymodbus.utilities import ModbusTransactionState


class ModbusBaseClient(ModbusClientMixin[Awaitable[ModbusPDU]]):
Expand Down Expand Up @@ -44,7 +43,6 @@ def __init__(
trace_pdu,
trace_connect,
)
self.state = ModbusTransactionState.IDLE

@property
def connected(self) -> bool:
Expand Down Expand Up @@ -146,7 +144,6 @@ def __init__(
)
self.reconnect_delay_current = self.comm_params.reconnect_delay or 0
self.use_udp = False
self.state = ModbusTransactionState.IDLE
self.last_frame_end: float | None = 0
self.silent_interval: float = 0

Expand Down Expand Up @@ -191,15 +188,6 @@ def execute(self, no_response_expected: bool, request: ModbusPDU) -> ModbusPDU:
# ----------------------------------------------------------------------- #
# Internal methods
# ----------------------------------------------------------------------- #
def _start_send(self):
"""Send request.

:meta private:
"""
if self.state != ModbusTransactionState.RETRYING:
Log.debug('New Transaction state "SENDING"')
self.state = ModbusTransactionState.SENDING

@abstractmethod
def send(self, request: bytes, addr: tuple | None = None) -> int:
"""Send request.
Expand Down
64 changes: 5 additions & 59 deletions pymodbus/client/serial.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from pymodbus.logging import Log
from pymodbus.pdu import ModbusPDU
from pymodbus.transport import CommParams, CommType
from pymodbus.utilities import ModbusTransactionState


with contextlib.suppress(ImportError):
Expand Down Expand Up @@ -158,10 +157,6 @@ def run():
Please refer to :ref:`Pymodbus internals` for advanced usage.
"""

state = ModbusTransactionState.IDLE
inter_byte_timeout: float = 0
silent_interval: float = 0

def __init__( # pylint: disable=too-many-arguments
self,
port: str,
Expand Down Expand Up @@ -219,6 +214,8 @@ def __init__( # pylint: disable=too-many-arguments
# Set a minimum of 1ms for high baudrates
self._recv_interval = max(self._recv_interval, 0.001)

self.inter_byte_timeout: float = 0
self.silent_interval: float = 0
if baudrate > 19200:
self.silent_interval = 1.75 / 1000 # ms
else:
Expand Down Expand Up @@ -264,14 +261,9 @@ 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: bytes) -> int: # pragma: no cover
"""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()._start_send()
def send(self, request: bytes, addr: tuple | None = None) -> int:
"""Send data on the underlying socket."""
_ = addr
if not self.socket:
raise ConnectionException(str(self))
if request:
Expand All @@ -283,52 +275,6 @@ def _send(self, request: bytes) -> int: # pragma: no cover
return size
return 0

def send(self, request: bytes, addr: tuple | None = None) -> int: # pragma: no cover
"""Send data on the underlying socket."""
_ = addr
start = time.time()
if hasattr(self,"ctx"):
timeout = start + self.ctx.comm_params.timeout_connect
else:
timeout = start + self.comm_params.timeout_connect
while self.state != ModbusTransactionState.IDLE:
if self.state == ModbusTransactionState.TRANSACTION_COMPLETE:
timestamp = round(time.time(), 6)
Log.debug(
"Changing state to IDLE - Last Frame End - {} Current Time stamp - {}",
self.last_frame_end,
timestamp,
)
if self.last_frame_end:
idle_time = self.idle_time()
if round(timestamp - idle_time, 6) <= self.silent_interval:
Log.debug(
"Waiting for 3.5 char before next send - {} ms",
self.silent_interval * 1000,
)
time.sleep(self.silent_interval)
else:
# Recovering from last error ??
time.sleep(self.silent_interval)
self.state = ModbusTransactionState.IDLE
elif self.state == ModbusTransactionState.RETRYING:
# Simple lets settle down!!!
# To check for higher baudrates
time.sleep(self.comm_params.timeout_connect)
break
elif time.time() > timeout:
Log.debug(
"Spent more time than the read time out, "
"resetting the transaction to IDLE"
)
self.state = ModbusTransactionState.IDLE
else:
Log.debug("Sleeping")
time.sleep(self.silent_interval)
size = self._send(request)
self.last_frame_end = round(time.time(), 6)
return size

def _wait_for_data(self) -> int:
"""Wait for data."""
size = 0
Expand Down
5 changes: 1 addition & 4 deletions pymodbus/client/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ async def run():
Please refer to :ref:`Pymodbus internals` for advanced usage.
"""

socket: socket.socket | None

def __init__( # pylint: disable=too-many-arguments
self,
host: str,
Expand Down Expand Up @@ -177,7 +175,7 @@ def __init__( # pylint: disable=too-many-arguments
trace_pdu,
trace_connect,
)
self.socket = None
self.socket: socket.socket | None = None

@property
def connected(self) -> bool:
Expand Down Expand Up @@ -217,7 +215,6 @@ def close(self):
def send(self, request, addr: tuple | None = None):
"""Send data on the underlying socket."""
_ = addr
super()._start_send()
if not self.socket:
raise ConnectionException(str(self))
if request:
Expand Down
7 changes: 2 additions & 5 deletions pymodbus/client/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ async def run():
Please refer to :ref:`Pymodbus internals` for advanced usage.
"""

socket: socket.socket | None

def __init__( # pylint: disable=too-many-arguments
self,
host: str,
Expand Down Expand Up @@ -177,15 +175,15 @@ def __init__( # pylint: disable=too-many-arguments
trace_pdu,
trace_connect,
)
self.socket = None
self.socket: socket.socket | None = None

@property
def connected(self) -> bool:
"""Connect internal."""
return self.socket is not None

def connect(self):
"""Connect to the modbus tcp server.
"""Connect to the modbus udp server.

:meta private:
"""
Expand All @@ -212,7 +210,6 @@ def send(self, request: bytes, addr: tuple | None = None) -> int:
:meta private:
"""
_ = addr
super()._start_send()
if not self.socket:
raise ConnectionException(str(self))
if request:
Expand Down
29 changes: 0 additions & 29 deletions pymodbus/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,6 @@
import struct


class ModbusTransactionState: # pylint: disable=too-few-public-methods
"""Modbus Client States."""

IDLE = 0
SENDING = 1
WAITING_FOR_REPLY = 2
WAITING_TURNAROUND_DELAY = 3
PROCESSING_REPLY = 4
PROCESSING_ERROR = 5
TRANSACTION_COMPLETE = 6
RETRYING = 7
NO_RESPONSE_STATE = 8

@classmethod
def to_string(cls, state):
"""Convert to string."""
states = {
ModbusTransactionState.IDLE: "IDLE",
ModbusTransactionState.SENDING: "SENDING",
ModbusTransactionState.WAITING_FOR_REPLY: "WAITING_FOR_REPLY",
ModbusTransactionState.WAITING_TURNAROUND_DELAY: "WAITING_TURNAROUND_DELAY",
ModbusTransactionState.PROCESSING_REPLY: "PROCESSING_REPLY",
ModbusTransactionState.PROCESSING_ERROR: "PROCESSING_ERROR",
ModbusTransactionState.TRANSACTION_COMPLETE: "TRANSACTION_COMPLETE",
ModbusTransactionState.RETRYING: "RETRYING TRANSACTION",
}
return states.get(state, None)


def dict_property(store, index):
"""Create class properties from a dictionary.

Expand Down
9 changes: 0 additions & 9 deletions test/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from pymodbus.exceptions import ConnectionException, ModbusException
from pymodbus.pdu import ModbusPDU
from pymodbus.transport import CommParams, CommType
from pymodbus.utilities import ModbusTransactionState


BASE_PORT = 6500
Expand Down Expand Up @@ -543,14 +542,6 @@ def test_idle_time(self):
client.last_frame_end = None
assert not client.idle_time()

def test_start_send(self):
"""Test idle_time()."""
client = lib_client.ModbusTcpClient("127.0.0.1")
client.state = ModbusTransactionState.IDLE
client._start_send()
client.state = ModbusTransactionState.RETRYING
client._start_send()

def test_sync_block(self):
"""Test idle_time()."""
with lib_client.ModbusTcpClient("127.0.0.1") as client:
Expand Down