Reputation: 1238
I am creating a Modbus Server using umodbus python module. Two clients are connecting to the server. One is reading the registers and other one is writing the same registers after every 5 seconds. Now problem is that both the clients are not able to read and write at the same time. '''
I later figured out that i need to close the connection after every read and write from both the clients. But still some times one of the client is not able to connect and the connection flag show False.
How can i handle this situation on the server side that it run stable, and 1st client can write the register and other can easily read the register?
from socketserver import TCPServer
from collections import defaultdict
from umodbus import conf
from umodbus.server.tcp import RequestHandler, get_server
from umodbus.utils import log_to_stream
log_to_stream(level=logging.DEBUG)
data_store =defaultdict(int)
conf.SIGNED_VALUES = True
TCPServer.allow_reuse_address = True
app = get_server(TCPServer, ('0.0.0.0', 502), RequestHandler)
data_store[10]=0
data_store[11]=0
data_store[20]=0
data_store[21]=0
@app.route(slave_ids=[1], function_codes=[3,4], addresses=list(range(10,15)))
def read_data_store_power(slave_id, function_code, address):
"""" Return value of address. """
print("Read Power: "+str(address))
return data_store[address]
@app.route(slave_ids=[1], function_codes=[6, 16], addresses=list(range(10, 15)))
def write_data_store_power(slave_id, function_code, address, value):
"""" Set value for address. """
print("Write Power: "+str(address)+" Value: "+str(value))
data_store[address] = value
@app.route(slave_ids=[1], function_codes=[3,4], addresses=list(range(20,25)))
def read_data_store_energy(slave_id, function_code, address):
"""" Return value of address. """
print("Read Request for Energy no:"+str(address))
return data_store[address]
@app.route(slave_ids=[1], function_codes=[6, 16], addresses=list(range(20, 25)))
def write_data_store_power_energy(slave_id, function_code, address, value):
"""" Set value for address. """
print("Write Request for: "+str(address)+" and Value: "+str(value))
data_store[address] = value
if __name__ == '__main__':
try:
app.serve_forever()
finally:
app.shutdown()
app.server_close()````
Upvotes: 2
Views: 911
Reputation: 11
The answer is here: https://github.com/AdvancedClimateSystems/uModbus/issues/119
This uses ThreadingMixin from the socketserver module to allow the get_server to handle multiple TCP sesssions.
from socketserver import TCPServer, ThreadingMixIn
...
class ThreadingServer(ThreadingMixIn, TCPServer):
pass
ThreadingServer.allow_reuse_address = True
try:
app = get_server(ThreadingServer, (host, port), RequestHandler)
except PermissionError:
print("You don't have permission to bind on {}".format(port))
print("Hint: try with a different port (ex: localhost:50200)")
exit(1)
Upvotes: 0