0

I have approximately the following code

import asyncio
.
.
.
async def query_loop()
    while connected:
        result = await asyncio.gather(get_value1, get_value2, get_value3)
        if True in result:
            connected = False

async def main():
    await query_loop()

asyncio.run(main())

The get_value - functions query a device, receive values, and publish them to a server. If no problems occur they return False, else True.

Now I need to implement, that the get_value2-function checks if it received the value 7. In this case I need the program to wait for 3 min before sending a special command to the device. But in the mean time, and also afterwards the query_loop should continue.

Has anybody an idea how to do that ? thanks in advance!

1 Answer 1

0

If I understand you correctly, you want to modify get_value2 so that it reacts to a value received from device by spawning additional work in the background, i.e. do something without the loop in query_loop having to wait for that new work to finish.

You can use asyncio.create_task() to spawn a background task. In fact, you can always combine create_task() and await to runs things in the background; asyncio.gather is just a utility function that does it for you. In this case query_loop remains unchanged, and get_value2 gets modified like this:

async def get_value2():
    ...
    value = await receive_value_from_device()
    if value == 7:
        # schedule send_command() to run, but don't wait for it
        asyncio.create_task(special_command())
    ...
    return False

async def special_command():
    await asyncio.sleep(180)
    await send_command_to_device(...)

Note that if get_value1 and others are async functions, the correct invocation of gather must call them, so it should be await asyncio.gather(get_value1(), get_value2(), get_value3()) (note the extra parentheses).

Sign up to request clarification or add additional context in comments.

ok thanks for your answer it was very helpful! But one last question: you never await the task "asyncio.create_task(special_command()). Are sheduled task executed automatically even if they are not called with await ?
@Art3mis Yes, that's what create_task does, you can think of it as "await in the background".
so now I have the problem, that the task special_command is invoked on every iteration of the loop. But i only need it to run once in a time..
@Art3mis special_command is only invoked when the value 7 is received from device. If you need to additionally restrict it by time, you can use a global variable (or any other shared-state variable) to prevent multiple special_commands from running at once. The answer was intended to show how to spawn a background task, not to cover all the minutiae of your use case.

Your Answer

Draft saved
Draft discarded

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.