LuaSocket

Is LuaSocket/JSON4Lua/JSONRPC4Lua supported by 1.0.994? Are there limitations?

LuaSocket is included and supported.

The JSON utilities are not included; but since they’re pure Lua libraries, you can install them (via SSH, the upload button in the UI won’t put them on the right place). Or you can use the slightly modified version of JSON4Lua i’ve put on code.mios.com (http://code.mios.com/trac/mios_genericutils/wiki/JSONLua)

Thanks for your reply.

From http://code.mios.com/trac/mios_genericutils/wiki/JSONLua:
“the JSON-RPC client depend on the (missing) LuaSocket HTTP module”

So the question remains:
Does Vera’s LuaSocket (firmware 1.0.994) support JSONRPC4Lua?

[quote=“Ap15e, post:3, topic:165877”]Thanks for your reply.

From http://code.mios.com/trac/mios_genericutils/wiki/JSONLua:
“the JSON-RPC client depend on the (missing) LuaSocket HTTP module”[/quote]

heh, i have to update that line. the latest firmware does include the full LuaSocket package, including the HTTP module.

[quote=“Ap15e, post:3, topic:165877”]So the question remains:
Does Vera’s LuaSocket (firmware 1.0.994) support JSONRPC4Lua?[/quote]

i haven’t tried (yet); but i would be surprised if there was any serious trouble. the change i did to JSON4Lua is pretty trivial, and the RPC client is just a straightforward use of [tt]luasocket.http[/tt]

Thanks, I will give it a try.

Any pointers as to where to put the additional Lua packages?

[quote=“Ap15e, post:5, topic:165877”]Thanks, I will give it a try.

Any pointers as to where to put the additional Lua packages?[/quote]

just drop them on [tt]/usr/lib/lua/[/tt]

Javier,
Do you have a Bug open for getting the [tt]/etc/cmh-ludl[/tt] directory added to the [tt]LUA_PATH[/tt] env for Vera startup?

It seems like it should be there, given you can use the UI to upload [tt].lua[/tt] files to that directory.

… or is something else planned (and can you share these plans)?

The reason for asking is that I have a modified [tt]dns.lua[/tt] for something I’m writing, and I’ll need folks to “upload” it to their Vera for the stack to work correctly.

[quote=“guessed, post:7, topic:165877”]Javier,
Do you have a Bug open for getting the [tt]/etc/cmh-ludl[/tt] directory added to the [tt]LUA_PATH[/tt] env for Vera startup?

It seems like it should be there, given you can use the UI to upload [tt].lua[/tt] files to that directory.[/quote]

the problem is that anything you upload using the UI is compressed, and the [tt]require “”[/tt] function in Lua doesn’t decompress it.

the ‘correct’ way to do it is to add decompression to the [tt]pagckage.loaders[/tt] table used by [tt]require “”[/tt]. then adding [tt]/etc/cmh-ludl[/tt] to the [tt]package.path[/tt] would do the trick. Yes, I’ll see to eventually add this to the engine.

“modified [tt]dns.lua[/tt]”? AFAIR, LuaSocket’s DNS functions are written in C, in the [tt]socket/core.so[/tt] file (could be wrong, I don’t have the docs right here and LuaSocket’s pages are very unstable). In any case, the preferred solution to override existing functionality is not to replace it, but to override it. something like this:

do
  local old = socket.dns.resolv
  function socket.dns.resolv(name)
    if name=="www.forbidden.com" then
      return nil, "you can't go there!"
    else
      return oldresolv(name)
    end
  end
end

but, if you really need to distribute a loadable module, there are some other options:

a very ugly solution would be to just include your [tt]dns.lua[/tt] inside your ‘main’ file; maybe inside a string, and then just load it (with a little voodoo passes to make it work as the [tt]require “”[/tt] function). yeah, it’s ugly.

also, you can modify [tt]package.path[/tt] as you wish before callint [tt]require “”[/tt], the main difficutl here is how to upload without compression. you could have an ‘installer’ function that creates the [tt]dns.lua[/tt] file itself. after that, you can [tt]require “”[/tt] it.

also… i haven’t tried it, but a MiOS Marketplace package should be able to specify where do you want to install the pieces. that would also solve the problem, no?

Yeah, there’s a whole lot more to DNS than just resolv() :wink:

[tt]dns.lua[/tt] is a pure-Lua DNS client that lets you get this extra information, but it’s still a little incomplete so it needs a little tweaking.

So it’s not a matter of overriding another implementation, it’s a matter of having a complete impl.

the 'correct' way to do it is to add decompression to the pagckage.loaders table used by require "". then adding /etc/cmh-ludl to the package.path would do the trick.

Yeap, that’s kinda what I figured. Not dissimilar to overriding the ClassLoader in Java to handle “other” storage/resolution mechanisms for Class files.

Ultimately what I need to know is the MiOS “recommended” solution to the packaging issue, one where “.lua” files need to be distributed alongside the .xml couterparts.

Right now, we cannot package .lua, and get “regular” end users to upload them (as we can for the .xml stuff) and a short term solution is needed for this… otherwise we’ll never build shared libs.

Also, this solution should handle how to resolve “multiple” .lua conflicts over time, where my .xml might depend upon one ver, and someone elses might depend upon another.

[quote=“guessed, post:9, topic:165877”]Right now, we cannot package .lua, and get “regular” end users to upload them (as we can for the .xml stuff) and a short term solution is needed for this… otherwise we’ll never build shared libs.

Also, this solution should handle how to resolve “multiple” .lua conflicts over time, where my .xml might depend upon one ver, and someone elses might depend upon another.[/quote]

just thinking aloud…

what about an extension to [tt]require[/tt] that takes an URL? it would check on a per-url directory, if the file isn’t there downloads it, and add that dir to the [tt]packages.path[/tt] before doing the usual [tt]require[/tt].

Usually the download would be done only the first time, and tying the directory to the URL lets different plugins share the same module, and unrelated plugins can have a different version, even if the filename is the same.

this can be written in pure Lua, and until it gets included in the firmware, it can be included in the plugin itself (should be around 10 lines of code… maybe less)

You’re starting to touch on my other outstanding question, in relation to what the “form” of the deployment package looks like for the MiOS Marketplace.

ie. an EAR file with a manifest.inf?

Then, instead of loading an individual lib, you load an entire [EAR] file that’s got either a depends list, or actually contains the files. The thing that “downloads” these can unpack them at “install” time so we don’t need to do it over and over again at runtime.

I did one of the early JAR file IfModified-download-and-cache mechanism in a past life (in JDK 1.0Beta), to make stuff run fast in the Browser-embedded Java, but that will tie you to having internet access to run stuff, which likely isn’t going to be favorable with some.

For the longer-term MiOS Library, I’d prefer people download a single package, and then disconnect.

In the short term though, I’d be happy if people could use the Built-in UI to “upload” the .lua file, similar to how they load the .xml, and we had a [library?] way to load those (an override of [tt]require[/tt], if that’s necessary)

In preference, I’d like to just use “require” in my code, and have you guys do the mapping magic of “where” the library is, and override the built-in require in the master table, before we get our hands on it.

just drop them on /usr/lib/lua/

My file structure:
/usr/lib/lua/json/json.lua
/usr/lib/lua/json/rpc.lua
/usr/lib/lua/json/rpcserver.lua

require(‘json’)
require(‘json.rpc’)

luup.log(json.encode( { 1, 2, ‘fred’, {first=‘mars’,second=‘venus’,third=‘earth’} } ) )
does work.

json.rpc.call(‘http://192.168.178.22:9000/jsonrpc.js’, ‘{“id”:1, “method”:“slim.request”,“params”:[“XX:XX:XX:XX:XX:XX”,[“display”,“Hello world”]]}’)
does not work. Error message: “attempt to call field ‘call’ (a nil value)”

Any ideas? A LUA_PATH related problem?

[quote=“Ap15e, post:12, topic:165877”]json.rpc.call(‘http://192.168.178.22:9000/jsonrpc.js’, ‘{“id”:1, “method”:“slim.request”,“params”:[“XX:XX:XX:XX:XX:XX”,[“display”,“Hello world”]]}’)
does not work. Error message: “attempt to call field ‘call’ (a nil value)”

Any ideas? A LUA_PATH related problem?[/quote]

two part fix:
1: change the module declaration in [tt]rpc.lua[/tt], line 25, from

module('json.rpc')

to

module('json.rpc', package.seeall)

2.a: add the [tt]‘?/?.lua’[/tt] part to [tt]package.path[/tt] as required on the webpage doc. simply do

package.path=package.path..";/usr/lib/lua/?/?.lua"

before calling [tt]require “”[/tt]

or
2.b: change the [tt]json.lua[/tt] file from [tt]json/json.lua[/tt] to just [tt]json.lua[/tt]:

mv /usr/lib/lua/json/json.lua /usr/lib/lua/json.lua

personally, i prefer 2.b

Thanks, this did the trick.

Next problem: :slight_smile:

I am going to interface Vera with my Squeezebox Server (192.168.178.22). The idea is to use a json.rpc.call for remote communication with my Squeezebox (MAC address 00:04:20:XX:XX:XX):

result, error=json.rpc.call(‘http://192.168.178.22:9000/jsonrpc.js’, ‘slim.request’, ‘{id=1, params={“00:04:20:XX:XX:XX”,{“display”,"Helloworld "}}}’)
print(result)
print(error)

Result:
nil
HTTP ERROR: closed

What am I doing wrong?

[quote=“Ap15e, post:14, topic:165877”]Result:
nil
HTTP ERROR: closed[/quote]

At this point, I would take a packet analyzer to find who’s misbehaving. Unfortunately, [tt]tcpdump[/tt] (my tool of choice) isn’t installed by default on Vera, so i would run the same Lua code from my desktop while storing the packets. if it fails similarly, check the packets to see who closes the connection (and at what step). if it works there, then point the Vera code to the PC and try to reproduce the same conversation.

The syntax of the last parameter seems to be the problem.

Workaround:

socket=require(‘socket’)
client = socket.connect(‘192.168.178.22’, 9090)
client:send(“00:04:20:XX:XX:XX display Helloworld\n”)
print(client:receive())
client:send(“version ?\n”)
print(client:receive())
client:close()

so is it working now?

i checked a little on the squeezebox forum; it seems the JSONRPC API isn’t (or wasn’t? most posts are a little old) too stable. it would be a pity if the only solution is to use the Web CLI (as on your last example).

No, talking to SBS via JSON/RPC from Lua does not work yet. Does not seem to be a Vera related problem, as it does not work from Lua4Windows either. If I find time, I will try to debug it.

Basically, SBS CLI and SBS JSON/RPC API are the same. IIUC, the SBS JSON/RPC API does not support asynchronous communication. OTOH: Parsing JSON messages is easier than parsing SBS CLI messages.

Ap15e, I hope to talk to SqueezeBox Server via JSON-RPC. Have you made progress or do you have something to start from? I am willing to do most of the heavy lifting as far as debugging. I have a number of packet captures from iPeng and a Duet controller to use as a baseline. Since it looks like we are both looking at talking to Squeezebox Server for our plugins I imagine there will be some overlap. Hopefully we can bounce ideas off each other.

http://forums.slimdevices.com/showthread.php?t=78165&highlight=JSON%2FRPC has some information on JSON/RPC.