Open hadesto opened 1 month ago
in case it helps :
xled==0.7.0
xled_plus==0.1.35
python 3.10
Hi,
I remember this issue from a couple of years ago. I see that the latest xled package released (0.7.0) is from 2021, and I think this may have been fixed in 2022. One thing to try is to download the latest xled version from git instead of using "pip install", then you will get the latest version. (Alternatively you can download just the "udpclient.py" file from the xled package and let it replace the old file.) The reason is that the old udpclient.py hogged a receiving port on the local machine, even when, as in this case, no messages are received. Therefore several UDP clients would try to use the same port.
If the above does not help, I may be able to provide a workaround, but try the above first.
Best Regards Anders Holst
appreciate the speedy response!! thank you so much!!
I went code diving and realized that this is an issue indeed in the original xled
package. The library is written such that the source port is forced to be the same as the destination port ( 7777
). For now I've had to overload the way the udp client handle is created. It is ugly but it works.
Here's what found so far:
7777
for source / destination portsfor now the way I've gotten away with it is with the following:
for count, (controller_ip, src_port) in enumerate(zip(settings.default.twinkly_controller_ip_list,
settings.default.twinkly_controller_src_ports)):
ctrl_list.append(HighControlInterface(host=controller_ip))
ctrl_list[count].udpclient
if count == 0:
while ctrl_list[count]._udpclient._handle == None:
ctrl_list[count].udpclient.handle
logger.debug("Waiting for default Xled connection to build so we can close it")
ctrl_list[count]._udpclient._handle.close()
while ctrl_list[count]._udpclient._handle._closed == False:
logger.debug("Waiting for default Xled connection to close so we can assign new ones")
else:
while ctrl_list[count]._udpclient == None:
ctrl_list[count].udpclient
logger.debug("Waiting for default Xled connection to build so we can close it")
ctrl_list[count]._udpclient._handle = None
ctrl_list[count]._udpclient._handle = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
ctrl_list[count]._udpclient._handle.bind(("", src_port))
# wait this time in seconds before starting to send data
logger.info(f"Connection configured. Waiting {settings.default.connection_settling_time} seconds for it to settle")
time.sleep(settings.default.connection_settling_time)
(controller_ip, src_port)
is something i provide with a config file. happy to take other suggestions, but it would be great to have this be configurable. On the plus side it would also allow running different instances of the xled-plus derived code to better multiprocess if we can set the port up front.
I'm guessing this is looking more like an xled
issue than an xled-plus
issue? should I be asking there?
Thanks again for this awesome library and all the work that has gone into it !
as a side note i did notice that there are changes in the developer
branch per your suggestion. will take a look at it too.
Hi!!
thank you so much for putting this out there. This library is pretty awesome.
While playing around with it I noticed that if you create more than one controller at a time for some reason the socket connection is not built separately. It seems like a valid socket connection is given to only one of the controllers, I would have expected each object to be an independent separate socket.
Here's a specific example :
The code will run, but the socket builds will fail. Specifically if
ctrl_obj
is each of the elements inctrl_list
then :ctrl_obj._udpclient.handle
is resulting inOSError: [Errno 48] Address already in use
at least for one of the items (i've tried a total of 2 so far).I also tried using the
MultiHighControlInterface
class but it seems to be directed at setups joined at the twinkly app level and I'm using each set differently.Thanks again for this awesome library. Appreciate any help!