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

Some device calls stalling app depending on tinytuya #590

Open
lmcd opened this issue Jan 28, 2025 · 6 comments
Open

Some device calls stalling app depending on tinytuya #590

lmcd opened this issue Jan 28, 2025 · 6 comments
Labels
enhancement New feature or request

Comments

@lmcd
Copy link

lmcd commented Jan 28, 2025

Hey,

I'm using tinytuya from a Swift codebase (via PythonKit) to interact with a set of Tuya devices via a native macOS app. Works really well 🎉

However, sometimes the app completely stalls waiting on a network request when a device is no longer discoverable on the network. For example, I'm seeing this in BulbDevice.heartbeat, even with nowait: true. It's not always reproducible, but often I come back to the app after it's been running for a few hours and have switched network, and the main thread is completely stuck inside heartbeat. Sometimes, if I switch back to the Tuya wifi network, the app will spring back to life, presumably because the devices are now discoverable.

Any idea how I can have these methods more gracefully fail if a device is not detected, rather than hanging indefinitely?

@lmcd
Copy link
Author

lmcd commented Jan 28, 2025

Also, I'm noticing the various timeout parameters when initialising BulbDevice, but could these methods not be designed non-blocking with zero penalty if nowait: true

@uzlonewolf
Copy link
Collaborator

Unfortunately there really isn't a good way to make it non-blocking. v3.4 and v3.5 devices require a 3-way handshake before any commands can be sent, and the library just isn't written to be non-blocking. It can be done (I do it for both the scanner and my half-finished multiserver) but it's pretty hack-y.

nowait just tells it to not wait for a reply to a command, making a connection and (for v3.4 and v3.5 devices) the 3-way handshake always block.

The most common way I've seen to reduce the impact of offline devices is to turn off retrying and setting a really low connection timeout with connection_retry_limit=1 and connection_timeout=0.5.

@uzlonewolf uzlonewolf added the enhancement New feature or request label Jan 29, 2025
@lmcd
Copy link
Author

lmcd commented Jan 29, 2025

Got it, thanks for the information!

I might spend some time implementing a simple swift-nio port - as this is specifically designed for any kind of non-blocking use case.

The tinytuya code seems quite straightforward to understand, but is there any protocol documentation floating around that could ease an implementation?

@uzlonewolf
Copy link
Collaborator

You mean Tuya's LAN protocol, to re-implement tinytuya or something? I have the packet format and checksums documented in #260.

@jasonacox
Copy link
Owner

I would love to see us move the library to a more elegant non-blocking asyncio friendly approach. Of course, if that were easy, it would have been done by now. :)

@lmcd
Copy link
Author

lmcd commented Jan 30, 2025

I have a really nice Swift proof of concept version of TinyTuya now working 🎉 Fully async with Swift Concurrency.
Was able to bootstrap fairly quickly by having Claude Pro help me figure out the protocol/encryption based on tinytuya code.

Doesn't support receiving messages - only sending, no scanning on anything like that, and only supports v3.3 devices without the handshake, but I can't see why all this can't be added fairly trivially.

Will post the repo when it's stable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants