Repository navigation
ModbusTcpClient always connected and recconect when droped. #3024
|
Hello everyone, I noticed that the ModbusTcpClient object, is not able to make a reconnection, unless the client.close() is executed. Is this the normal expected behavior ? Even if i want to handle reconnection, I'm not able to because the client.close() is needed. Any comments appreciated. test code below. Versions
Code and Logsimport time
import logging
from pymodbus.client import ModbusTcpClient
logging.basicConfig(level=logging.INFO)
client = ModbusTcpClient("192.168.6.69", port=1502)
while True:
try:
# 2. Open the connection
if client.connect():
print("Successfully connected to SERVER")
result = client.read_holding_registers(address=0, count=5, device_id=1)
if result.isError():
print(f"Modbus Error: {result}")
else:
# Access the data via the .registers list
print("Successfully read registers!")
print(f"Raw register values: {result.registers}")
#client.close()
except:
print("Failed to connect to SERVER")
client.connect()
print('client connected property : ' , client.connected)
print('client connect property : ' , client.connect())
time.sleep(1) |
Replies: 4 comments 2 replies
|
I am not really understanding your description. A client is connected until .close() is called or the device terminates the connection, in the later case the client tries to reconnect automatically. once a client is disconnected, there are no api calls to reconnect. The reason being that a lot of the connect configuration happens in init. when .connected is false you should be able to simply call .connect(). So checking .connected before making write operations should solve your problem. a couple of note .connected is a property not a method ! Of course you cannot connect and already connected object, that would be strange to allow that. If you want ,connect() to work differently feel free to submit a pull request. |
|
Hello Sir, client.connect() is not working correctly if client.close() is comment out, as per my example above. Is there any way to achieve persistent connection with reconnection with sync client ? or you suggest the async client ? |
|
The sync client works fine for this (one TCP connection, cyclic reads plus event driven writes). Putting together what janiversen said, plus two things that are easy to miss:
Something like this: import threading
import time
from pymodbus.client import ModbusTcpClient
from pymodbus.exceptions import ConnectionException, ModbusException
client = ModbusTcpClient("192.168.6.69", port=1502, timeout=2)
lock = threading.Lock()
def ensure_connected():
# connect() on an object that still thinks it is connected does nothing,
# so close first, then connect
if not client.connected:
client.close()
return client.connect()
return True
def poll_loop():
while True:
with lock:
try:
if ensure_connected():
rr = client.read_holding_registers(address=0, count=5, device_id=1)
if not rr.isError():
print(rr.registers)
except (ConnectionException, OSError):
client.close() # link is gone, next pass reconnects
except ModbusException as exc:
print("modbus error, connection kept:", exc)
time.sleep(1)
def write_on_event(address, value):
with lock:
try:
if ensure_connected():
client.write_register(address, value, device_id=1)
except (ConnectionException, OSError):
client.close()I tested it on 3.15.0 against a local pymodbus server: read and a write from a second thread, then killed the server (first poll gets the reset and closes, the next ones fail to connect), restarted it, and the following poll reads again without restarting the client. Two things from your original code:
If the rest of your program is already asyncio you can do the same with |
|
Calling client.connect() on an open SERIAL connection, will pr design just return true...there are no reconnect. |
Calling client.connect() on an open SERIAL connection, will pr design just return true...there are no reconnect.