Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cannot reuse already awaited coroutine #372

Closed
MaierJuerg opened this issue Apr 30, 2024 · 14 comments
Closed

cannot reuse already awaited coroutine #372

MaierJuerg opened this issue Apr 30, 2024 · 14 comments
Labels
cannot reproduce usage question How to use the library waiting validation Waiting for user's validation/approval/test

Comments

@MaierJuerg
Copy link

using python3.10 and meross-iot 0.4.7.0

My python task checks a number of input values and turns on/off a fan.

The sequence of commands is as follows, each command is in a try/except section but none triggers.

http_api_client = await MerossHttpClient.async_from_user_password(
    email=EMAIL,
    password=MEROSS,
    api_base_url="https://iotx-eu.meross.com")
manager = MerossManager(http_client=http_api_client)
await manager.async_device_discovery()
await dev.async_update()
await dev.async_turn_off(channel=0)
manager.close()
await http_api_client.async_logout()

This usually works fine bot sometimes i get this exception:

Task failed, msg=Task exception was never retrieved, exception=cannot reuse already awaited coroutine

how can I avoid getting this message?

@albertogeniola
Copy link
Owner

Hi!
it looks like the code you posted is invalid...
For instance, there is no dev declaration: you are invoking dev.async_update() without declaring a dev variable.

I guess you did not post the entire code listing... can you post the whole code that gives you the exception? Please also include a complete stack trace with the specific error.

@albertogeniola albertogeniola added the usage question How to use the library label Apr 30, 2024
@MaierJuerg
Copy link
Author

MaierJuerg commented Apr 30, 2024 via email

@MaierJuerg
Copy link
Author

Alberto
created this more straight forward example. It usually runs trough but I sometimes get this error
errTurnOn.txt
scratch_1.txt

@albertogeniola albertogeniola added the bug Something isn't working label Apr 30, 2024
albertogeniola added a commit that referenced this issue Apr 30, 2024
@albertogeniola
Copy link
Owner

I confirm there is still a race condition in the last version that might cause the issue you are experiencing.
I've released a new beta version that attempts to fix that. Can you please try this version and report if working as intended?

You can update your library version with the following command: pip install meross-iot==0.4.7.2b1

@albertogeniola albertogeniola added the waiting validation Waiting for user's validation/approval/test label Apr 30, 2024
@MaierJuerg
Copy link
Author

MaierJuerg commented May 1, 2024 via email

@albertogeniola
Copy link
Owner

So I am having hard time to replicate your issue.
According to the logs, it seems you are "re-connecting" to the MerossCloud just before closing the connection. When this happens, the reconnection handler schedules a discovery update of all devices; however at the same time the manager tells the system to "close everything" and to cancel the update. There is an edge case (race condition) that arises when the scheduled (delayed) update executes after the manager has invoked the cancel() method on the scheduled coroutine.

To further investigate, I need your "test code" that triggers the race condition. Can you post the minimal python examples that "sometimes" fails?

@albertogeniola albertogeniola removed the waiting validation Waiting for user's validation/approval/test label May 1, 2024
albertogeniola added a commit that referenced this issue May 1, 2024
@albertogeniola
Copy link
Owner

In the meantime, I'm releasing a newer beta, v0.4.7.2.b2. That should better address the issue. I would still love to have the code example to test. in any case.

As soon as the pipeline completes, you should find a new beta version and thus you can update the library and test again.

Let me know!

@MaierJuerg
Copy link
Author

MaierJuerg commented May 2, 2024 via email

@albertogeniola
Copy link
Owner

Hi @MaierJuerg ,

maybe I'm missing something, but it looks like you have posted the logs, not the python code.

scratch_1.txt looks like the following:
image

errTurnOn.txt looks like this:
image

I believe you updated the same file twice :-)

Can you please doublecheck? Moreover, have you tried v0.4.7.2.b2?

@MaierJuerg
Copy link
Author

MaierJuerg commented May 3, 2024 via email

@albertogeniola
Copy link
Owner

Hi @MaierJuerg ,

Looking at your code, I don't understand a number of things. I'm not sure there is a correlation between the way you are coding and the issue you are getting.

Let me ask you the following:

  1. Why are you manually invoking manager.async_execute_cmd() to get info about the onOff status? Why don't you use the is_on() method on the device?
  2. Why are you invoking again the same method after issuing the async_turn_on() method on the device? This should not be needed.

I would rewrite the code as follows:

import asyncio
import os

from meross_iot.controller.mixins.electricity import ElectricityMixin
from meross_iot.http_api import MerossHttpClient
from meross_iot.manager import MerossManager
from meross_iot.model.enums import Namespace, OnlineStatus

EMAIL = os.environ.get('MEROSS_EMAIL')
PASSWORD = os.environ.get('MEROSS_PASSWORD')
DEV_NAME = "Lüfter Wärmetauscher"

async def main():
    # Setup the HTTP client API from user-password
    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")

    # Setup and start the device manager
    manager = MerossManager(http_client=http_api_client)
    await manager.async_init()

    # Retrieve all the devices that implement the electricity mixin
    await manager.async_device_discovery()
    devs = manager.find_devices(device_name=DEV_NAME, online_status=OnlineStatus.ONLINE)
    if len(devs)<1:
        raise Exception(f"Could not find device {DEV_NAME} or it's not online.")
    dev=devs[0]

    # Update the initial status of the device
    await dev.async_update()

    # Check if the device is on
    dev_is_on = dev.is_on()
    if dev_is_on:
        print(f"Device {DEV_NAME} is already on, nothing to do!")
    else:
        print(f"Turning {DEV_NAME} on...")
        # If this method does not raise an exception, we can assume the device has been turned on.
        await dev.async_turn_on(channel=0)

        # ------- THE FOLLOWING IS REDUNDANT AND YOU MIGHT NOT NEED IT ----------
        # If you really want to make a full check to be extra sure it is on (although is not really necessary in my
        # opinion, you just have to re-issue the update)
        print(f"Forcing a full update for device {DEV_NAME}...")
        await dev.async_update()
        dev_is_on = dev.is_on()
        print(f"Device {DEV_NAME} is: {'on' if dev_is_on else 'off'}")
        # ------- END OF REDUNDANT STATE CHECK ----------

        if dev_is_on:
            print("Turn on operation was successful")

    # Close the manager and logout from http_api
    print("Closing the connection and logging out...")
    manager.close()
    await http_api_client.async_logout()
    print("All done!")

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.stop()

In any case, I tried to execute the code as you posted, but I was unable to trigger the error (I tried 20 times in a row).

@albertogeniola albertogeniola added cannot reproduce and removed bug Something isn't working labels May 4, 2024
@MaierJuerg
Copy link
Author

MaierJuerg commented May 4, 2024 via email

@albertogeniola
Copy link
Owner

Hi @MaierJuerg ,

sure, you can get the total daily power consumption by calling this method.

Let me know if everything works out now :)

@albertogeniola albertogeniola added the waiting validation Waiting for user's validation/approval/test label May 6, 2024
@MaierJuerg
Copy link
Author

MaierJuerg commented May 7, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cannot reproduce usage question How to use the library waiting validation Waiting for user's validation/approval/test
Projects
None yet
Development

No branches or pull requests

2 participants