joaquincasares / python-wifi-leds

A cross-vendor Python library for WiFi LED products.
27 stars 20 forks source link

Using TCP as optionnal feature #1

Open Seraf opened 11 years ago

Seraf commented 11 years ago

Hello,

My controller (firmware 3.00.08) seems to offers the possibility to use TCP instead of UDP. I tested your library yesterday and had sometimes packet transmitted but not received by the controller. Should be great to use TCP to avoid this kind of things, even if you transmit few times the udp packet to avoid this behavior.

What do you think about this ? Anyway, I wanted to thanks you a lot, you saved me a LOT of time by sharing this library. I will use it in my project ! Thanks !

joaquincasares commented 11 years ago

Awesome feedback and glad you're enjoying the project!

Sure thing. I've added some code and hopefully this should work for your device: eb3f879cb215aceca79eec7bf553702714c0f950 5a5017e5f18c18da80e32e82a8d9ad2ff0093464

So, instead of using:

led_connection = wifileds.limitlessled.connect(address, port)

please use:

led_connection = wifileds.limitlessled.connect(address, port, 'tcp')

Let me know what the result is!

I'm also not sure if the tcp sends will send all responses 3 times or a single time (due to a loop to mimic keypresses). Let me know if you try sending a single brightness_down() command and you see the brightness decrease 3 times. Thanks!

Seraf commented 11 years ago

Hello,

Thanks for your answer. I'm sorry I didn't had the time to test it, but anyway, thanks for your reactivity. I will try to give a test during next week and keep you informed.

Thanks !

Seraf commented 11 years ago

Hello, I have not been able to connect on the controller in TCP mode. It says : "Connection refused".

I had to fix the init.py :

def connect(address='192.168.1.100', port=50000, protocol='udp'):
    return bridge.Bridge(address=address, port=port, protocol=protocol)

Without setting which parameter you pass, the short_pause_duration had the value of the "tcp" protocol.

I haven't done a pull request as I can't connect to the controller... If you find a solution it should be nice :)

Thanks for the quick change of your code :)

joaquincasares commented 11 years ago

Heh, thanks for catching that. It's been fixed with 8690a9e58a97e0af5cd69e3484c807ab64aaf661.

Could you send me the complete stacktrace? Just to make sure the issue is not on my end?

Can you try creating a sample script to connect to your bridge via TCP? If it connects, can you send that my way as well? Perhaps I need to connect in another way.

Thanks!

Seraf commented 11 years ago

Here's the traceback :

Traceback (most recent call last):
      File "/usr/local/lib/python2.7/dist-packages/twisted/python/log.py", line 88, in callWithLogger
        return callWithContext({"system": lp}, func, *args, **kw)
      File "/usr/local/lib/python2.7/dist-packages/twisted/python/log.py", line 73, in callWithContext
        return context.call({ILogContext: newCtx}, func, *args, **kw)
      File "/usr/local/lib/python2.7/dist-packages/twisted/python/context.py", line 118, in callWithContext
        return self.currentContext().callWithContext(ctx, func, *args, **kw)
      File "/usr/local/lib/python2.7/dist-packages/twisted/python/context.py", line 81, in callWithContext
        return func(*args,**kw)
    --- <exception caught here> ---
      File "/usr/local/lib/python2.7/dist-packages/twisted/internet/posixbase.py", line 614, in _doReadOrWrite
        why = selectable.doRead()
      File "/usr/local/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 215, in doRead
        return self._dataReceived(data)
      File "/usr/local/lib/python2.7/dist-packages/twisted/internet/tcp.py", line 221, in _dataReceived
        rval = self.protocol.dataReceived(data)
      File "/home/julien/Sandbox/LISA/LISA-Engine/libs/Server.py", line 77, in dataReceived
        libs.RulesEngine(configuration).Rules(jsonData=jsonData, lisaprotocol=self)
      File "/home/julien/Sandbox/LISA/LISA-Engine/libs/RulesEngine.py", line 50, in Rules
        plugininstance = namedAny('.'.join((str(oPlugin["name"]),'modules',str(oPlugin["name"]).lower(),str(oPlugin["name"]))))()
      File "/home/julien/Sandbox/LISA/LISA-Engine/Plugins/Wifiledlamps/modules/wifiledlamps.py", line 21, in __init__
        protocol='tcp')
      File "/usr/local/lib/python2.7/dist-packages/wifileds/limitlessled/__init__.py", line 5, in connect
        return bridge.Bridge(address=address, port=port, protocol=protocol)
      File "/usr/local/lib/python2.7/dist-packages/wifileds/limitlessled/bridge.py", line 65, in __init__
        self.create_connection()
      File "/usr/local/lib/python2.7/dist-packages/wifileds/limitlessled/bridge.py", line 50, in create_connection
        self.sock.connect((self.address, self.port))
      File "/usr/lib/python2.7/socket.py", line 224, in meth
        return getattr(self._sock,name)(*args)
    socket.error: [Errno 111] Connection refused

2013-09-10 21:30:48+0200 [Lisa,3,127.0.0.1] Lost connection.  Reason: [Failure instance: Traceback (failure with no frames): <class 'socket.error'>: [Errno 111] Connection refused
joaquincasares commented 11 years ago

I'm thinking TCP may have a different port than the UDP port?

Here's the code that I based my assumptions off of: https://wiki.python.org/moin/TcpCommunication

If you wouldn't mind trying to figure out the TCP port or perhaps playing with socket a bit more to get a connection established, that would be great: http://docs.python.org/2/library/socket.html

Once we have the connection portion then the rest of the code should be reusable, save for a fix or two that I'm foreseeing for better performance.

Thanks again!

Seraf commented 11 years ago

It's strange because a nmap reveal the 50000 port listen in tcp mode. So it seems OK on the controller side. I will try to dig deeper with the python code.