-
Hi again. Just wanted to see if anyone has successfully created a GUI to control all their smart devices that I could learn from code-wise. I'm still very new to Python after all. My vision is to make a GUI to control all gadgetry in my home. This includes both Tuya and things that I may want to build on my own using Raspberry Pi (security cameras, battery operated devices with a Pi Pico W, etc.) Tuya is great because brand doesn't matter so long as it's powered by Tuya it should still work with Tinytuya. I'm still having a tad bit of trouble though. My latest hurdle is statuses. I'm not sure if it's my specific devices (the brands I'm using like Feit and Geeni), but I can't seem to accurately monitor the devices. I will explain my code here, and try to attach the entire files since I see there is an option for it. Basically, I start a BottlePy server for the front end of the GUI, and just make requests to the server to execute Python code. Getting statuses is done via a websocket, while requests to set DPS is done through AJAX POST. I have an infinitely running while loop in a separate thread that is supposed to get the device status of every device. It can take a bit of time, about 70ish milliseconds per device I reckon. About 1.2 full seconds to fully iterate over my 18 devices. This isn't a big deal though, since mainly I just want to get the initial status of each device to give the GUI a starting point. But when I turn off a device from the front end, it doesn't seem to update on the back end for a few iterations, so maybe 4+ seconds. My GUI will show the light as turned off/on because I obviously update the GUI right away once the device is clicked on, but then my websocket will retrieve data from the back end and will force the GUI to display incorrectly that the device is in the opposite state. I understand I could do nowait=True, but obviously that wouldn't return any data to send back to the front end to update accordingly. Could it be my devices? Or in general does it take time for updates to reflect in the DPS system? A sort of cache? What could I do to make this GUI more..natural feeling with this in mind? |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 10 replies
-
The status should return the actual state, it doesn't cache the state. I think the issue is probably your long running loop taking a while to refresh. My suggestion is that you have a thread maintain state, cache the state for some TTL amount of time (e.g. 5s) and when the TTL expires, have it poll just that device. When you make a change via UI, make a websocket call should invalidate the TTL cache for that device and force an immediate poll so the websock update message back to the browser would match what you changed manually. I always wanted to do a nice UI as well, but this is as far as I got and it is NOT using websockets: https://github.com/jasonacox/tinytuya/tree/master/server. - Doing it over I would do:
Thanks for sharing your progress! |
Beta Was this translation helpful? Give feedback.
-
OK. After doing some research, I found that So I updated the device status thread like so: def getDeviceStatuses():
global devices
global statuses
x = 0
for device in devices:
statuses[x] = {"id":device.id, "status":device.status()}
x += 1
getDeviceStatuses() And instead of creating a This has resulted in only a couple seconds of a delay between issuing a voice command to Google, and 1ish second delay between two devices running the front end of the GUI. (The host device and then my phone with Chrome with the GUI web page open). This is getting really cool, and is really helping me learn Python. I want to try testing this on a Pi 4 eventually, to see if it can serve as a central server for the Python code. And then use Pi Zero W's as "clients". This would be the most cost effective route as opposed to using multiple Pi 3's, 4's, or even 5's to basically just run a web page on boot. |
Beta Was this translation helpful? Give feedback.
OK. After doing some research, I found that
for
loops are faster than infinitewhile
loops in Python.So I updated the device status thread like so:
And instead of creating a
tmp
list and populating it at the end of the loop, we update the globalstatuses
during each iteration, usingx
as an index to tell us which device we are updating. Meanwhile, the websocket continues to constantly push updates to the client side, but now instead of waiting for awhile
loop to populate a ne…