openLuup: Suggestions

Hi akbooer,

yes it’s for my front-end systems. Eventually I’ll modify the standard install file.

tnks

donato

Can’t recall how exactly you have the front-end configured for watching variables. If you use the AltUI Data Storage Provider to push to DataYours, then you will still need AltUI! If you’re using just DataWatcher, then all thould be OK.

Yes, I’ve only Datayours for watching variables.

tnks

@akbooer, One possible suggestion/request: Would it be possible to add a lua code field associated each individual scene watch? Application would be to reduce the number or identical or near identical scenes where I would want to trigger only a very small variation to the code depending which trigger started the scene. It is equivalent to the trigger lua on the vera? Maybe it’s already there but I didn’t figure how to use it?

The device variable watch functionality is entirely implemented in AltUI, so I have no control over that.

I did wonder why @amg0 chose to require just a logical statement rather than a Lua function there, but that’s the way it is.

There is, however, a work-around. According to Lua syntax, it’s perfectly acceptable to define an in-line function and evaluate it to return the required boolean value. Within that function, you can do pretty much what you need to do.

Here’s an example which simply writes the new variable value to the log…

(function () luup.log (new) return true end) ()

take care with the final open/close parentheses, which evaluate the given function.

Here’s the relevant section of the log (the variable watch in this case is looking at openLuup’s CpuLoad .)

2020-01-21 10:44:11.823   luup.variable_set:: 2.openLuup.CpuLoad was: 0.3 now: 0.30 #hooks:1
2020-01-21 10:44:11.825   luup.watch_callback:: 2.openLuup.CpuLoad function: 0x006e9290
2020-01-21 10:44:11.825   luup_log:3: 0.30
2020-01-21 10:44:11.825   luup.call_action:: 0.urn:micasaverde-com:serviceId:HomeAutomationGateway1.RunScene 
2020-01-21 10:44:11.928   luup.scenes:: scene 6, test altui watch, initiated by command

You can see that AltUI has a watch callback which is activated by the variable change, the function code is run and outputs to the log, and because the return value is true, it then runs the scene.

Hope this works for you.

(One day, perhaps, openLuup will get its own version of triggers with Lua code.)


PS: There is one caveat here… the code is run in the context of the AltUI plugin, NOT in the global scene/startup Lua one. This means that you can’t access the usual global variables/functions you may have defined in startup, so it might limit its application.

1 Like

Thanks AK, I was suspecting that it was controlled my by ALTUI than openLuup as I was writing the previous post. I ended up using the “clone” scene function of ALTUI as it is simpler than to work around this limitation through Lua and less error prone so it isn’t all that bad.

yes, I have not checked lately but a function should be ok if it returns a bool true/false.

the point of the lua context is valid, I never quite figured out how I could run in another context

On Vera, I don’t think you can (well, you could isolate the environment from the plugin, but you couldn’t share the scene/startup one.) Under openLuup, you could. But I wouldn’t worry about it.

Ideally they both should behave the same anyway.

Well, it has taken about 18 months to get around to this, but I am looking at incorporating this into the next release. It’s also relevant for the next version of the ZWay plugin which will number its child devices in a similar way.

Thanks for the (old) suggestion @reneboer!

AK - wanted to try out the cjson in the latest dev release (release is working fine so far!). However not being a unix expert, I’ve no idea if I installed it or not successfully. So suggestion is: can one of the console pages (system parameters perhaps?) indicate if it has been found and is in use or not so. May be there is somewhere this already gets indicated but I couldn’t find it. I tried AltUI–> OS Command–>Find Json but it wasn’t found. Where does it end up on a RasPi? Here is my attempted install report - it seems like it worked?:

/$ sudo apt-get install lua-cjson
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
  lua-cjson
0 upgraded, 1 newly installed, 0 to remove and 119 not upgraded.
Need to get 18.0 kB of archives.
After this operation, 56.3 kB of additional disk space will be used.
Get:1 http://mirrordirector.raspbian.org/raspbian/ jessie/main lua-cjson armhf 2.1.0+dfsg-2 [18.0 kB]
debconf: unable to initialize frontend: Dialog
debconf: (Dialog frontend will not work on a dumb terminal, an emacs shell buffer, or without a controlling terminal.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin: 
Fetched 18.0 kB in 1s (15.0 kB/s)
Selecting previously unselected package lua-cjson:armhf.(Reading database ... 
(Reading database ... 5%
........................
(Reading database ... 100%
(Reading database ... 32185 files and directories currently installed.)Preparing to unpack .../lua-cjson_2.1.0+dfsg-2_armhf.deb ...Unpacking lua-cjson:armhf (2.1.0+dfsg-2) ...Setting up lua-cjson:armhf (2.1.0+dfsg-2) ...Processing triggers for libc-bin (2.19-18+deb8u7) ...
1 Like

Glad to hear that the latest is working well for you.

Good idea! Because the openLuup.json module is not dependent on any other openLuup modules, it doesn’t report its presence in the logs, so the version info doesn’t appear in the startup log.

It’s easy to do an explicit check:

if json.C then print "using Cjson" end

so I’ll put that in the log and perhaps on a console page.

Thanks for the suggestion.

AK

OK - looks like cjson did install OK. AltUI didn’t find it, because it’s command is looking for json Lua files but cjson is not Lua. I tried your test but that failed but this indicated it was available:

local ok, result = pcall(require, 'cjson')
local json = package.loaded['cjson']
if (json) then
    print('Found cjson')
else
    print('cjson not found')
end

return true
1 Like

Had you restarted openLuup after installing Cjson?

Yep and this is the response:

"[string "ALTUI - LuaRunHandler"]:39: attempt to index global 'json' (a nil value)"

Wondering if this is a version of Cjson which adds a global to the Lua environment, rather than returning a module.

Is the result of

local j = require "cjson"

true or a table ?

…or, possibly, you ran this code on Vera, not on openLuup?

Definitely on openLuup; err Vera? :upside_down_face:

local j = require "cjson"
print(j)

for k,v in pairs(j) do
    print(k)
    print(v)
end

return true

It returns a table and the contents are:

table: 0x105ad28

_NAME
cjson
encode
function: 0x105b470
decode_max_depth
function: 0x105b620
_VERSION
2.1.0
decode_invalid_numbers
function: 0x104bad0
encode_keep_buffer
function: 0x104ba40
null
userdata: (nil)
encode_number_precision
function: 0x105b570
new
function: 0x104b938
encode_max_depth
function: 0x105b4f8
encode_invalid_numbers
function: 0x104ba70
decode
function: 0x105b4c8
encode_sparse_array
function: 0x105b540

Then I have absolutely no idea what is going on.

Hi,

I installed cjson on a PI and works just fine running the latest openLuup development branch.

I am also using it in one of my plugins in a way that works on openLuup (with cjson) and Vera (without). It is based on what AK did in openLuup, with some changes as Vera would not take that for some reason. The cjson.decode only works on a perfect json string, else it trows an exception. You can use cjson.safe.decode then it will not throw the exceptions.

local cjson 	= require("cjson")
local dkjson 	= require("dkjson")
local json

-- Wrapper for more solid handling for cjson as it trows a bit more errors that I'd like.
local function jsonAPI()
local is_cj, is_dk

	local function _init()
		is_cj = type(cjson) == "table"
		is_dk = type(dkson) == "table"
	end
	
	local function _decode(data)
		if is_cj then
			local ok, res = pcall(cjson.decode, data)
			if ok then return res end
		end
		local res, pos, msg = dkjson.decode(data)
		return res, msg
	end
	
	local function _encode(data)
		-- No special chekcing required as we must pass valid data our selfs
		if is_cj then
			return cjson.encode(data)
		else
			return dkjson.encode(data)
		end
	end
	
	return {
		Initialize = _init,
		decode = _decode,
		encode = _encode
	}
end

json = jsonAPI()
json.Initialize()

local res = json.decode("{some json}")

Maybe it helps finding the problem.

Note, the instructions say this: Import Lua CJSON via the Lua require function. Lua CJSON does not register a global module table. https://www.kyne.com.au/~mark/software/lua-cjson-manual.html

Cheers Rene

2 Likes

@a-lurker

My suggestion here would have worked but for the fact that in my Lua Startup I have the line

json = require "openLuup.json"

which makes my json module globally available in the startup / scene / Lua Test context.

The latest releases of openLuup have the new json module which should now be working for you.

Apologies for my confusion.

AK