The hardware:
Node ESP32 development board, running standard Arduino libs
The intention:
One trigger event performs an action on multiple lights (ie: a group) instantly. If any action fails, it needs to be retried.
The problem:
Using UDP, requiring a response (or an ack) introduces a noticeable delay in the subsequent requests as each request waits for a response before timeout.
Not requiring a response can end up with lights in the wrong state due to a dropped packet.
I’ve got a couple of ideas for solutions, but just wondering if @delfick-employee or @daniel_hall have any guidance on a “best practice” here?
My current thoughts on options are:
Never require a response, but use a GETSTATE call after the fact to ensure the change has taken place
Refactor the code handling the response to make it non-blocking
Investigate Async UDP calls
NB: Currently I’m not worrying about the lights’ IPs and just sending broadcasts using the header.target to match the correct mac address. Is there any foreseeable problem with this approach? Would specifying an IP result in a reduced delay, or greater chance of success?
Broadcast should work fine as long as your network isn’t really busy. You can use wireshark to confirm the broadcast packets are being received by your devices.
Also, I would set ack_required to True and res_required to false. Send out all the messages and then determine which messages need to be resent based on what acks you don’t get.
Unfortunately I’m unfamiliar with arduino and micropython so I don’t really have any tips on achieving that.
Thanks. I’m actually no longer using uPython for this, back on the standard C implementation (which is a learning curve).
The issue is that waiting and listening for the ack is a blocking operation (no async UDP in its current form), so I’d like to keep it down to a few hundred microseconds. Roughly how quickly should it be received, assuming a reasonably good network?
Another option is to send the packet multiple times, ignore the response and hope for the best. This approach seems to be used on the “rapid” color change method in the popular “lifxlan” Python module.
P.S. If you get this working, it’d be great if you’d be willing to share it. I’ve also been planning an ESP32 light controller but haven’t had time to do anything yet and don’t know when will I do. Some base code to start working with would greatly improve the chance of getting something done.
Absolutely I’ll be sharing it. Thanks for the tip. I’ve taken a few looks at @mclark’s excellent library in the past.
I’m leaning towards optimistically set (aka fire_and_forget, maybe two or three times), then use getState to check, but need to play around with it a bit more first.