Hsn
Hsn

Reputation: 1238

Modbus Server with umodbus

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

Answers (1)

Keith
Keith

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

Related Questions