Closed dkhawajafaithtechinc closed 7 months ago
Did you allow connections to that port in windows ? windows typically blocks ports below 2058.
And a stupid question the client runs on the same PC ?
If you add our logging call (see examples or documentation), then you can see what the server does and especially if it starts listening.
Just a hint, if you see the output in your while loop, then the server do not start.
c.read_holding_registers(53031, 1, 1) do not follow the API, please see the documentation, but that a problem you will see later once connected.
Port is allowed and yes client and server are running on the same pc. Turns out server was not listening. I am trying to get the server to serve using server.serve_forever. When I use await server.serve_forever, I get that the server is listening, but I don't want to await this because I need the rest of my code to run so I am trying to run it in a separate async task but when I do it seems that the server never starts listening until I call await server_task which still gives the same blocking issue. I know the following code is wrong because I was trying a few different things with asyncio.create_task but not 100% sure how to go about this
async def run_server(device):
port = int(device['port'])
device_name = device['name']
try:
print(f"Starting server for device {device_name}...")
store = ModbusSlaveContext(
di=ModbusSequentialDataBlock.create(),
co=ModbusSequentialDataBlock.create(),
hr=ModbusSequentialDataBlock.create(),
ir=ModbusSequentialDataBlock.create())
context = ModbusServerContext(slaves=store, single=True)
server = ModbusTcpServer(context=context, address=("127.0.0.1", port))
# Run the Modbus server in a separate task
server_task = asyncio.create_task(server.serve_forever())
await asyncio.wait_for(server.serving, timeout=10)
print(f"Server for device {device_name} is online")
while device['simulate']:
for i in #values:
address = i["address"]
values = #some register values
if values is not None:
context[0x03].setValues(3, address, values)
# Print the values in the HR (holding registers) block
print("Values in HR block:")
# Get values for addresses 53000 to 53100
res = [value for value in store.store["h"].values[53000:53101]]
print(res)
sleep(5)
print(f"Shutting down server for device {device_name}...")
server.shutdown()
# Wait for the server task to complete - DOESN'T COMPLETE
await server_task
print(f"Server for device {device_name} is offline")
return True
except Exception as e:
print("Error starting server:", e)
c.read_holding_registers(53031, 1, 1) do not follow the API, please see the documentation, but that a problem you will see later once connected.
Okay I finally got it to work by replacing sleep(5) with asyncio.sleep(5) and removing the await asyncio.wait_for...
For what you said about this, I am able to read using this code but you said it does not follow the documentation. How so?
Read the documentation, that explains how to use the server without having to wait, but of course it does not tell you how to program async, which seems to be the problem.
read_holding_registers do not use 3 positional parameters, please read the documentation.
Read the documentation, that explains how to use the server without having to wait, but of course it does not tell you how to program async, which seems to be the problem.
read_holding_registers do not use 3 positional parameters, please read the documentation.
The last parameter is for broadcasting which was needed in my case to be able to communicate
OK....but this is not what the documentation says (nor what the API uses), and actually if you want broadcasting the value is not 1.
Versions
Pymodbus Specific
Description
I have a server started up with the following code:
The server runs properly and populates holding registers with appropriate values asynchronously. I am having trouble reading using a client. I wrote quick test code, but the error I get is:
Connection to (127.0.0.1, 601) failed: [WinError 10061] No connection could be made because the target machine actively refused it
Am I missing a parameter somewhere? I tried using broadcast_enable = True, but I am not sure.
Code and Logs