ljean / modbus-tk

Create Modbus app easily with Python
Other
557 stars 211 forks source link

Error while flushing the socket: argument must be an int, or have a fileno() method after executing master._do_close() method-Modbus_tk #150

Open ShyamBhattacharyya opened 3 years ago

ShyamBhattacharyya commented 3 years ago

I want to get the modbus data from a device in a 5 seconds interval. So my program goes like that.

def _con():
   master = modbus_tcp.TcpMaster(host=ip,port=prt)
   master.set_timeout(15)
   read1 = master.execute(uid,cst.READ_HOLDING_REGISTERS,add,leng)

while True:
    time.sleep(5)
    _con()

Now the problem is that every time this program executes, It creates a new socket every time and after some iterations when the client device reaches its max socket count, my program fails to connect with the client again till the die of the previous open sockets. To achieve my goal, I modified this code like this

def _con():
   master = modbus_tcp.TcpMaster(host=ip,port=prt)
   master.set_timeout(15)
   read1 = master.execute(uid,cst.READ_HOLDING_REGISTERS,add,leng)
   #master.__del__()
   #master.close()
   master._do_close()
while True:
    time.sleep(5)
    _con()

This throws an error "Error while flushing the socket: argument must be an int, or have a fileno() method." in every iteration and no of new sockets still increases. When I uncomment either of both comments (i.e. master.del() or master.close()), the error is sorted out but still no of the new sockets increases. How to close the previous sockets every time after receiving data, so that no of socket remains same. I am using modSimR simulator for testing. Please note that I want to run this code under crontab in every 15mins interval. I will remove the while loop after development. In the attachment, you can see that no of connected devices(marked in red) increases with every iteration and after 10/10 connections, my program will throw an error, socket timed out. modbus_tk

Slasktra commented 3 years ago

I'm not a friend of the github editor. ">" should be replaced with indentation:

`def _con(): ">"master.set_timeout(15) ">"read1 = master.execute(uid,cst.READ_HOLDING_REGISTERS,add,leng) ">"master.close()

master = modbus_tcp.TcpMaster(host=ip,port=prt) while True: ">"time.sleep(5) ">"_con()`

ShyamBhattacharyya commented 3 years ago

Hey Slasktra. Thanks for your code. But still, that does not work. Every time it opens a new socket and not killing the previous connection. May be _do_close() function will kill the socket as per the library but that is throwing an error as I told you in my earlier comment.

test

I did it as you told like

def _con():
    master.set_timeout(15)
    read1 = master.execute(1,cst.READ_HOLDING_REGISTERS,0,10)
    master.close()
    print(read1)

master = modbus_tcp.TcpMaster(host='127.0.0.1',port=502)
while True:
    time.sleep(5)
    _con()

If I do not close the connection inside the function, that case, this problem is not occurring. See my correction

def _con():
    while True:
        master.set_timeout(15)
        read1 = master.execute(1,cst.READ_HOLDING_REGISTERS,0,10)
        print(read1)
        time.sleep(5)
master = modbus_tcp.TcpMaster(host='127.0.0.1',port=502)
master.open
_con()
master.close

test

But that does not work under crontab when I have to run the entire code in a 15 min block without using the while loop. Like this.

def _con():
        master.set_timeout(15)
        read1 = master.execute(1,cst.READ_HOLDING_REGISTERS,0,10)
        print(read1)
master = modbus_tcp.TcpMaster(host='127.0.0.1',port=502)
master.open
_con()
master.close

Please Note, Every time the connection needs to be closed after every 15 mins call. In that time it fails. I am using the while loop for testing purposes in this code just to check how the modbus_tk library is working with the simulator in a repetitive connection.

And one help for you, after writing any code in Github, select the whole code block and press Ctrl+e. It will display your code as you want it to be. :-)