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 whether you accept or reject these cookies being set.

Creation of custom package
#1
How can I create custom package for LM?
I need custom websocket connections with TV and other stuff and I want to use this connection inside LUA resident or event scripts.
The main idea is I create a package which works as HTTP server on some local port and it has and ability to create websocket clients inside.

e.g.

event script

Code:
ws = require('lua.websocket') 
tvConnection, err = ws.connect('ws://my.tv.ip:3000') -- (blocking with t/o) send to local HTTP server
                                                     --  a command to connect if no connection
tvConnection.send('raw data') -- send text or array of bytes to 'ws://my.tv.ip:3000'


resident script 0 sec

Code:
ws = require('lua.websocket')
tvConnection, err = ws.connect('ws://my.tv.ip:3000') -- (blocking with t/o) send to local HTTP server
                                                    -- a command to connect if no connection
data = tvConnection.receive() -- receive array of data came from 'ws://my.tv.ip:3000' 


Could you please create kind of this stuff? Or give me instruction how to build own package, I know C/C++, Golang, JS, Lua

Thank you in advance!
Reply
#2
There's a pure Lua websocket client library. It should work on LM with some minimal changes.

As for custom packages we do not provide build tools but we can provide some custom packages by request.
Reply
#3
Attached is websocket client library ported from https://github.com/lipp/lua-websockets/

Main changes:
1. Support for basic auth in URL
2. Receive timeout does not close the websocket connection
3. Server support is removed

Add it as a user library named websocket

Minimal example (resident script):
Code:
if not ws then
  ws = require('user.websocket')
  url = 'ws://admin:admin@192.168.1.12/apps/localbus.lp'
  -- mode is either sync or copas, second parameter sets timeout in seconds
  client = ws.client('sync', 10)
  client:connect(url)
end

log(client:receive())


Attached Files
.lua   websocket.lua (Size: 13.64 KB / Downloads: 30)
Reply
#4
Hi,

Thank you. This is great. Is there an recommend way for connecting to multiple websocket servers with this client?

Thanks,

Roger
Reply
#5
Hi,

I am trying to use the copas part because being a resident script i need to run a udp server to accept an event script client.  

On connecting with the copas parameter I get the following in the error log.


Library copas:0: attempt to yield across C-call boundary
stack traceback:
[C]: in function 'yield'
Library copas: in function 'connect'
User library websocket:500: in function 'sock_connect'
User library websocket:438: in function 'connect'


Code:
 ws = require("user.websocket")
 url = 'ws://demos.kaazing.com/echo'
 -- mode is either sync or copas, second parameter sets timeout in seconds
 
 client = ws.client('copas', 10)
 client:connect(url)
Reply
#6
Hi,

I am using the following UDP server code for taking requests from the LM objects.  effectively the websockets client needs to running asynchronously  so it doesn't block the udp server running.  In the past I have used copas to do this.

Code:
 local server = usocket.udp()
 server:setsockname("127.0.0.1",53450)
 function handler(skts)
   skts = copas.wrap(skts)
   alert("UDP connection handler")
   while true do
     local s, err
     alert("UDP receiving..")
     s, erro = skts:receive(2048)
     if not s then
       alert("Receive error: %s", erro)
       break
     end
     alert("Received data, bytes: %s",s)
      -- send to the websocket
     client:send(s)
   end
 end
   
 copas.addserver(server, handler, 1)
Reply
#7
You need to wrap websocket client in copas mode with function passed to copas.addthread
Reply
#8
Hi,

Is there an example from this?  Because that's what I am trying. thx Roger

Code:
if not ready then
 socket = require("user.websocket")
 usocket = require("socket")
 copas = require("copas")
 ready=true
 apps = {}

 --helper functions to round and increment values
 
 function increment(n)
   n = n + 1
   return n
 end
 
 function parse(data)
   alert('parsing: %s', data)
   local response = string.split(data,' = ')

 end
 
 function sendCommand(command)
   skt:send(command)
   sleep(1)    
 end
 
 
 function init()

 end
 
 function fromKNX(command)
   local telegram = string.split(command,',')
   log(command)
   sendCommand(command)
 end
 
 local server = usocket.udp()
 server:setsockname("127.0.0.1",53450)
 function handler(skts)
   skts = copas.wrap(skts)
   alert("UDP connection handler")
   while true do
     local s, err
     alert("UDP receiving..")
     s, erro = skts:receive(2048)
     if not s then
       alert("Receive error: %s", erro)
       break
     end
     alert("Received data, bytes: %s",s)
     fromKNX(s)
   end
 end
   
 copas.addserver(server, handler, 1)
end

if not skt then
url= 'ws://demos.kaazing.com/echo'
 skt,err = socket.client('copas',5)

 skt:connect(url,80)
 skt:send('hello')
 -- when theres no error connect ok, initialize
 if(not err) then

   -- add receive thread
   copas.addthread(function()
       while true do
         local resp,err = copas.receive(skt)
         -- if theres no connection start a new connection
         if not resp then
           alert("[tcp-client] Receive error: %s", err)
           copas.removeserver(skt)
           skt = nil
           break
         end
         local fd,prtd = pcall(parse,resp)
         if(fd==false)then
           alert("Error with parsemsg %s ",prtd)
         end
       end
     end)
   if skt then
     alert('[tcp-client] connection ok')
     init()
     -- error while connecting,
   else
     if warningfailed then alert('[tcp-client] connection failed (conn): %s', err) end
     return
   end
 else
   alert('[tcp-client] error connecting %s',err)
   return
 end
end
copas.loop()
Reply
#9
connect part must be inside copas thread
Reply
#10
Hi,

Ok adding the connect in the thread works. Thank you. The timeout parameter doesn't seem to have any effect. The connection always lasts about 10 seconds disconnects and reconnects. Is there no way to keep it permanently connected?

Another thing I need to account for is that the webservice is not always running. It's live when the device is powered on. So what I see is that the script would be constantly trying to reconnect. I guess the only way to handle this is by disabling the resident script when the device is powered off. Unless you have any other idea?

thanks

Roger
Reply
#11
Disconnect might happen from the server side. To keep connection alive you probably need to request data periodically or send ping frames.

As for reconnect, enable/disable is one approach, another one is just to keep script running and check if connect is ok or not. When device is offline then connect function will return once timeout is reached.
Reply
#12
(26.03.2018, 08:42)rocfusion Wrote: Hi,

Ok adding the connect in the thread works.  Thank you.   The timeout parameter doesn't seem to have any effect.  The connection always lasts about 10 seconds disconnects and reconnects.  Is there no way to keep it permanently connected?

Another thing I need to account for is that the webservice is not always running.  It's live when the device is powered on.  So what I see is that the script would be constantly trying to reconnect.  I guess the only way to handle this is by disabling the resident script when the device is powered off.  Unless you have any other idea?

thanks

Roger

Hi Roger,

Did you have any success getting your LG TV to work with this? Also did you manage to support connecting to multiple clients?

I'm trying to do the same (I have 2 LG WebOS TVs I'd like to control).. but I'm a complete newbie to Lua.

Nick
Reply


Forum Jump: