I'm encountering an issue while using pymodbus for asynchronous data writing to a Modbus device. When I write data to the PLC synchronously one by one, everything works fine without any errors. However, my objective is to write 56 pieces of data to the Modbus device simultaneously using asynchronous threads.
Here's the problem: when I attempt to write data asynchronously with 56 threads, the pymodbus TCP connection unexpectedly closes. After the writing process, there is no response value, indicating a communication failure.
I've confirmed that the issue lies specifically with the asynchronous operation because when I perform synchronous writes, the connection remains stable, and I receive the expected response values.
I'm seeking guidance on how to troubleshoot and resolve this issue. Could it be related to how pymodbus handles asynchronous operations or potentially a limitation of the Modbus device itself?
Any insights or suggestions would be greatly appreciated. Thank you!
functions.py
from pysnmp.hlapi.asyncio import *
import pymodbus.client as ModbusClient
import time
async def getSnmp(oid, ipAddress, readReg, statusReg, client):
while True:
writeData = {}
writeData["ReadRegister"] = readReg
writeData["StatusRegister"] = statusReg
writeData["CurrentType"] = 0
writeData["ReadValue"] = 0
modbusFeedBack = await write_data_to_registers(client, writeData)
time.sleep(4)
return snmp_engine,context_data
async def connect_to_modbus():
MODBUS_IP = '120.100.1.30'
MODBUS_PORT = 502
try:
client = ModbusClient.AsyncModbusTcpClient(
MODBUS_IP,
port=MODBUS_PORT,
#framer=framer,
timeout=1,
retries=0,
# retry_on_empty=False,
# source_address=("localhost", 0),
)
#client = ModbusTcpClient(MODBUS_IP, port=MODBUS_PORT)
if await client.connect():
print("Modbus connected")
return client
else:
print(f"Sleep 10")
await asyncio.sleep(5)
return None
except Exception as e:
print(f"Err: - {e}")
return None
async def write_data_to_registers(client, data):
if not client:
return None
try:
print(f"Writinggg Data {data}")
readReg = int(data['ReadRegister'])
readVal = int(data['ReadValue'])
connReg = int(data['StatusRegister'])
connVal = int(data['CurrentType'])
writeA = print(await client.write_register(readReg, readVal, unit=1))
#writeB = await client.write_register(connReg, connVal, slave=1)
return True
except Exception as e:
print(f"Err: {e}")
return None
app.py
import asyncio
import time
import json
from datetime import datetime
from functions import getSnmp, connect_to_modbus # Custom Converter Fun
async def proccessTask(client,data):
startTime = datetime.now()
activateOID = "1.3.6.1.4.1.1206.4.2.3.6.3.0"
tasks = [getSnmp(activateOID, vtsData['Ip'],vtsData['ReadRegister'],vtsData['StatusRegister'],client) for vtsData in data] #56 task
results = await asyncio.gather(*tasks)
for result in results:
result[0].transportDispatcher.closeDispatcher()
endTime = datetime.now()
elapsedTime = endTime - startTime
print(f"İşlem tamam cycle süre {elapsedTime}")
async def main():
while True:
client = None
while not client:
client = await connect_to_modbus()
with open('../data/vtsData.json') as file:
data = json.load(file)
if data:
feedBack = await proccessTask(client, data)
if not feedBack:
client.close()
client = None
if client:
client.close()
time.sleep(2)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
I was expecting each thread to write data to the Modbus device simultaneously.