pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.16k stars 891 forks source link

StartAsyncTcpServer freezing #2037

Closed dkhawajafaithtechinc closed 4 months ago

dkhawajafaithtechinc commented 4 months ago

Versions

Pymodbus Specific

Description

Hello, I am trying to run a modbus server asynchronously, but I am having quite a bit of trouble. When debugging my python code I find that my code hangs on the following line:

server = await StartAsyncTcpServer(context, address=("127.0.0.1", port))

I am not sure what I am doing wrong but I have tried using ModbusTcpServer directly as well and tried running await server.serve_forever(), but it hangs on that as well. Any guidance on this would be greatly appreciated.

Code and Logs

# code and logs here.
async def run_server(port):
    try:
        print(f"Starting server for device...")
        store = ModbusSlaveContext(
            di=ModbusSequentialDataBlock.create(),
            co=ModbusSequentialDataBlock.create(),
            hr=ModbusSequentialDataBlock.create(),
            ir=ModbusSequentialDataBlock.create())
        context = ModbusServerContext(slaves=store, single=True)

        server = await StartAsyncTcpServer(context, address=("127.0.0.1", port))
        #server = ModbusTcpServer(context, address=("127.0.0.1", port), ignore_missing_slaves=True, broadcast_enable=True)
        #StartAsyncTcpServer(context, address=("localhost", port))
        #await server.serve_forever()
janiversen commented 4 months ago

Please read the documentation, that call will not return until the server terminates.

dkhawajafaithtechinc commented 4 months ago

Hi yes, I have updated my code to this, but how can I get the actual ModbusTCPServer object in my "server" variable, this currently returns a coroutine object:

async def run_servr(port):
    try:
        print(f"Starting server for device...")
        store = ModbusSlaveContext(
            di=ModbusSequentialDataBlock.create(),
            co=ModbusSequentialDataBlock.create(),
            hr=ModbusSequentialDataBlock.create(),
            ir=ModbusSequentialDataBlock.create())

        context = ModbusServerContext(slaves=store, single=True)

        server = StartAsyncTcpServer(context, address=("127.0.0.1", port))

        print(f"Server for device {udt['name']} is online")

        while server.isServing():
        ...
janiversen commented 4 months ago

But the call still do not return until the server terminates! Did you read the documentation, there is a part about how to use the API without the blocking start call.

janiversen commented 4 months ago

please read the documentation, that helps to understand how the library works, you are calling a blocking function.

dkhawajafaithtechinc commented 4 months ago

I tried to look in the documentation, but couldn't find much. Could you point me in the right direction?

dkhawajafaithtechinc commented 4 months ago

please read the documentation, that helps to understand how the library works, you are calling a blocking function.

Can you point in the right direction? Also, just for more insight into what I am trying to accomplish. I want to be able to start an async server, stop the server, and update the server with 3 different functions asynchronously.

janiversen commented 4 months ago

there are several ways to do that, Start* is one way but it needs to run in a separate task.

I already pointed you at our documentation, where it is explained, did you look ?

janiversen commented 4 months ago

We also provide examples showing different ways to use the server objects.

dkhawajafaithtechinc commented 4 months ago

I don't see where you pointed to your documentation. There is no link or anything in any of your responses. Am I looking in the wrong place?

janiversen commented 4 months ago

I did not, you can find the links to the source, documentation etc in the package info.