Issue with pymodbus TCP connection closing when writing data asynchronously

44 views Asked by At

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.

0

There are 0 answers