This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

localhost socket stuck with specific data ?
#1
Hi!
I have a project with Lutron integration and I follwed the thread below to setup Lutron library.

https://forum.logicmachine.net/showthrea...ght=lutron

As I have a lot of group addresses which requires to send command to Lutron server, I have setup localhost socket inside LM as always, in order to unite the place to open TCP port for Lutron.

My scripts are below.

Event script to simulate Lutron button press and release.
Code:
1234567891011121314151617181920212223242526
--1    ALL ON --2    Reading --3    Relax --4    Goodnight --5    ALL OFF --18    Dim down --19    Dim up --20    Dim down button release (stop dimming) --21    Dim up button release (stop) device = '5101' value = event.getvalue() if value == 20 then   cmd = '#DEVICE,'..device..',18,4\r\n'   log(cmd..'_dim down↓stop') elseif value == 21 then   cmd = '#DEVICE,'..device..',19,4\r\n'   log(cmd..'_dim up↑stop') else   cmd = '#DEVICE,'..device..','..value..',3\r\n' end sock = require('socket').udp() log(cmd..'_sent to udp socket in the event') sock:sendto(cmd, '127.0.0.1', 5485) sock:close()

Resident script which collects the udp information and send to Lutron server
(address "10/1/2" indicates if there is a conection error with Lutron server)
Code:
12345678910111213141516171819202122232425262728293031323334
require('user.lutron') require('socket') if not server then    server = socket.udp()   server:setsockname('127.0.0.1', 5485) end data = server:receive() if data then   log(data..'_data before sent to lutron tcp')   tcp, err = lutron_login()   if not tcp then     grp.checkwrite('10/0/2', true)     log('no connection to device', err)   end   if tcp == nil then     grp.checkwrite('10/0/2', true)   else     tcp:send(data)     log(data)     os.sleep(0.3)   end   if tcp == nil then     grp.checkwrite('10/0/2', true)   elseif lutron_receive(tcp)~= nil then     if lutron_receive(tcp)[1] ~= nil then       if lutron_receive(tcp)[1]== "no connection to device" then         log(lutron_receive(tcp)[1])         grp.checkwrite('10/0/2', true)       end     end   end end

When I execute the event above, this is what I can see in the log.
For some reason, when I send val 18 or 19 to press dim up /down button on lutron
I cannot send button release command (val 20 or 21) within next 20 seconds even though I simulate to press them way earlier than that.
This happens only when I send val 18 or 19 to this event....how am I making the socket stuck?

Attached Files Thumbnail(s)
   
Reply
#2
You resident script opens a new connection for each message that should be sent. At some point the connection limit is reached.
You can try opening the connection and sending the command directly from the event script. Otherwise the resident script must be modified to have only a single open connection.
Reply
#3
Thank you for your reply!
OK.....I guess it is because the resident script runs lutron_login() every time?

Does this code look better?
Code:
12345678910111213141516171819
require('user.lutron') require('socket') if not server then    server = socket.udp()   server:setsockname('127.0.0.1', 5485)   --server:settimeout(3) end data = server:receive() if data then   if not tcp then     tcp, err = lutron_login()     if tcp == nil then       grp.checkwrite('10/0/2', true)     else       tcp:send(data)       os.sleep(0.3)     end   end end
Reply
#4
Try this. It will try sending the data again if the first send call failed due to a closed socket or any other error. Remove log() calls once you get it working.
Code:
12345678910111213141516171819202122232425262728293031323334353637
if not server then   require('user.lutron')   require('socket')   server = socket.udp()   server:setsockname('127.0.0.1', 5485)   function send(data)     if not sock then       sock, err = lutron_login()       if not sock then         log('lutron login failed', err)       end     end     if sock then       res, err = sock:send(data)       if res then         return true       end       log('lutron send failed', err)       sock:close()       sock = nil     end   end end data = server:receive() if data then   if not send(data) then     send(data)   end end
Reply
#5
Thank you so so much!
It works and I don't see the send delay anymore.... internal socket does not get stuck also.

I guess I am opening TCP port each time I run this resident script as well ?
I tried to edit them like you did but I am failing....could you suggest how to modify it to have only a single open connection?

Code:
12345678910111213
require('user.lutron')   tcp, err = lutron_login() if not tcp then   log('no connection to device', err) end while tcp do   res, err = lutron_receive(tcp)   log(res,err)     if (res == nil) then       return     end end


By the way in this project we have iOS tablet app and phone app but the frontend does not have functionality to prevent user from continuously clicking on the command button.
That is why I put os.sleep(0.3) every time after sending TCP command but do you have better way to prevent high load caused by users' over-clicking ?

Thank you very much for your help as always!
Reply
#6
Trying to work on this but I am still keep failing....
With the status script above(with 0 sec interval), I figured out new connection is open every 10 seconds.
I guess it is because of the timeout that I set inside lutron_connect script
Code:
1234567891011
function lutron_connect()     local tcp = assert(socket.tcp())     tcp:settimeout(10)     local res, err = tcp:connect('172.16.1.10', 23)   if res then     return tcp   else     tcp:close()     return nil, err   end end

What I have tried with modifying status script is as below but it creates an infite roop inside LM....
Appreciate a lot if you could help.
Thank you so much!
Code:
1234567891011121314151617
if not tcp then   tcp, err = lutron_login()   if not tcp then     log('no connection to device', err) end end while tcp do   res, err = lutron_receive(tcp)     if (res == nil) then       return     else       log(res)     end      if (err ~= nil) then         alert('Lutron error '..err)     end end
Reply
#7
Try this:
Code:
123456789101112131415161718
if not tcp then   tcp, err = lutron_login()   if not tcp then     log('no connection to device', err)     os.sleep(5)   end end while tcp do   res, err = lutron_receive(tcp)   if res then     log(res)   elseif err == 'closed' then     tcp:close()     tcp = nil   end end
Reply


Forum Jump: