Global Lua functions

Hi,

I am trying to add some Lua functions to be used across different scenes, but I can’t make it happen. I’ve uploaded the file, declared my module name in the beginning of it, referred it with ‘require’ in the scene - no success. I’ve also dug a lot in the forum and in the wiki and failed to get an answer on those. So the questions are several:

  • Do I have to always make the D_XXX.xml, I_XXX.xml, L_XXX.lua structure to get the LUA file loaded and reusable?
  • Can I just uploaded the LUA file and reuse it? If YES - what exactly need to be sone, to succeed?

Thank you very much for the answer(s).

There are many ways to do modules in LUA …
If the file is called XXX.lua
Then for Vera the module MUST start with something like:

module("XXX", package.seeall)
... Lua Functions ...

Then you use then as:

    xxx = require("XXX")
    result = xxx.GlobalFunction1(Arg1)

If i get it right, you want your global functions to be reused in multiple scenes. Take a look at this topic : http://forum.micasaverde.com/index.php/topic,8237.0.html

Yes, this is exactly what I need and although I didn’t have the chance to test today, I saw write away what was the missing key in my code: “package.seeall”…

It just didn’t get clear for me whether mu file need to be names the same as the declared module-name, not that this is a problem.

Thanks for the help!

I’m glad we could help you.

Hi,

Unfortunately, when I did manage to test it today - it still doesn’t work :frowning:

My file is names ‘ihLib.lua’, it starts with:

module("ihLib", package.seeall)

And I refer the functions inside like this:

local mod = require("ihLib")
mod.updateDimmer(4, {57, 70})

I do restart the Luup engine on lua file upload.

And I receive the following in the log file:

luup_require can't find ihLib <0x2b5fb680>

Any new ideas, please? :slight_smile:

Where is the File located on Vera ? How did you
Are you a Vera 2/UI4 ? or Vera3/VeraLite UI5 ?

Hi,

I’m on UI5, and I’ve discovered my mistake - my file was names iHLib, while the module name is ihLib… Find the difference? A capitalized ‘h’ in the filename. Sorry for this. And thanks for answering!

It works now, i.e. it finds and uses the functions. Not that it works the way I want - to update dimmer status properly on many devices. Any ideas why ‘LoadLevelTarget’ variable on ‘urn:upnp-org:serviceId:Dimming1’ service is not properly read? And, yes - I need this variable, but now “Status”, because by the time of scene launch the target status is not yet received so I want to get the desired target and send it to other devices that need to be updated…

Because the Variable is not called LoadLevelTarget.

Do not confuse argument names for arguments to luup.call_action with a variable name for a device (They are often related … so this can be confusing).

The variable is called Target
Look in the Advanced tab to see the names of variables … the lower section of the advanced tab lists all of the variables for that device.

If you let the mouse hover over the variable name … it will show the Service ID for that variable.

Hmm,

It is dimmer, not switch - both here: http://wiki.micasaverde.com/index.php/Luup_UPnP_Variables_and_Actions#Dimming1 and in Advanced tab it is ‘LoadLevelTarget’ variable. Am I missing something?

I use these in lua for dimmers, maybe it helps:

SET a loadlevel:

luup.call_action("urn:upnp-org:serviceId:Dimming1","SetLoadLevelTarget",{["newLoadlevelTarget"] = LOADLEVEL},DEVICEID)

GET current load level target:

luup.variable_get("urn:upnp-org:serviceId:Dimming1","LoadLevelTarget",DEVICEID)

Thanks for the reply! Yes, that’s what I’m using too:

stat = luup.variable_get("urn:upnp-org:serviceId:Dimming1", "LoadLevelTarget", masterId)

and, according to documentation it should work perfectly fine, but - it doesn’t!
I’m using it in a scene which is triggered on ON or OFF of the dimmer status change, reads the target value and updates the (several) remote dimmer keys. It started to work for some time, but not anymore. No code error reports, I’ve added logging and - just like in the beginning - LoadLevelTarget always reports ‘0’?

Not to mention that scene approach prevents me from updating when only the dimmer level is changed, no the on/off status…

Strange, I quickly tested this in Apps=>Develop Apps=>Test Luup Code. It read the variable just fine and wrote it to a variable of a virtual switch, works just fine.

Maybe you could also quickly test your code there.

Not to mention that scene approach prevents me from updating when only the dimmer level is changed, no the on/off status...
Another approach would be to use the excellent plugin PLEG from Richard. I almost do anything with this now and replaced all of my logic scenes with it.

Actually, it works most of the time, but not all. When the scene is activated from controlling the target dimmer - it works fine.
BUT, since the same dimmer I want to be controlled from satellite (Vitrum) key, which acts as a dimmer, I’ve made an association from the Vitrum to the actual (Fibaro) dimmer. And this is where things break:

  • pressing the satellite key sends (via association group) direct commands to the dimmer;
  • the dimmer lights (up or down) and this invokes the scene on the controller;
  • the scene goes on all satellites and updates their status based on THIS variable (LoadLevelTarget) value;
  • and HERE is where things break - in this scenario the returned value is always ‘0’, so the satellite key, just turned one, goes back to OFF, leaving the actual dimmer turned on.
  • The very same scene works fine when the change on the dimmer happens from the controller.

Strange… :frowning:

Why does it return 0? Has the Vera not had a chance to poll the dimmer? Maybe it just needs a small delay.

Do you mind sharing your code? My friend has a couple 3-way dimmers and may find this useful.

It is interesting, that it fails to receive the proper value only when the dimmer’s state is changed due to command from other, associated device. When you change the state from the Vera - no problem at all. I don’t think polling is relevant here - the device’s state need to be pushed to Vera, and I guess this is exactly what fails - it is not pushed on time.

I’ve tried with luup.variable_watch(), but obviously, I don’t know where to but it to work.

Otherwise, no problem sharing the code, it is not anything that fancy:

function setDimmers(slaveIds, value)
	for i, deviceId in ipairs(slaveIds) do
		luup.call_action("urn:upnp-org:serviceId:Dimming1","SetLoadLevelTarget", { newLoadlevelTarget = tostring(value)}, deviceId)
	end
end

function updateDimmer(masterId, slaveIds)
	local stat = luup.variable_get("urn:upnp-org:serviceId:Dimming1", "LoadLevelTarget", masterId)
	setDimmers(slaveIds, stat)
end

updateDimmer() is called from the scene. Something like:

updateDimmer(4, {57, 23})

Try using the value of the variable LoadLevelStatus rather than LoadLevelTarget in your luup.variable_get…

Hi, RexBeckett,

Of course, I’ve tried this and it works for switches, but not for dimmers, because “LoadLevelStatus” represents the current status, while “LoadLevelTarget” represents the future status, so in the initial moment of turning on the dimmer LoadLevelStatus = 0, while LoadLevelStatus should_be 100 and since THIS is the moment I’m reading the variable - I’m actually getting the OLD status, and not the new one.

It works for switches, because they are updates immediately, so Target == Status.

Thanks for suggestion, however.

Any help of how to “install” variable_watch() so it gets called? It doesn’t work in my “library” lua file, it doesn’t work in Vera Startup Code, nor is it written in the documentation, where is the right place for it?

Thanks! :slight_smile:

I should say I’m rather surprised to see that such basic functionality as keeping several dimmers in sync, or - generally speaking - keeping several uni-type devices in-sync does not already have THE solution - it could be because I’m new to Vera and Lua, so I can’t see it. I promise to post here a complete, flexible code that does the job, once I find it… :slight_smile:

Ok, found it! :slight_smile:

I should have read more about Lua at the first place, I guess… So, it finally started to work, I’ll make it a bit more universal before posting the code (as I promised), but I’d like to clarify the things that I’ve found:

  • in Lua you can declare a file as ‘module’, but it is not necessity. If you do so, however, all your functions inside stop being global and you can’t call them just by their name, which make them UNusable in variable_watch().
  • luup.variable_watch() can be placed anywhere you want, but you can’t watch any variable you want. For example LoadLevelTarget is not watchable. I guess it is determined from the no tag in its service file (S_Dimming.xml). LoadLevelStatus IS watchable, however.
  • Obviously there is a bug in Vera, for not updating all variables upon scene event triggering. For example, when another device changes the state of a dimmer using Z-Wave associations, and that state change triggers a scene associated with the dimmer, it is expected to have LoadLevelTarget set to new value. But it’s not.

So, I’ve managed to make things work, by putting everything in one (Lua) file, I’ll delete all scenes and keep devices in sync using variable_watch(), which from performance perspective won’t be different, because triggers are form of variable_watch() too, I guess. I’ll rework my code a bit and will post it here. Thanks for all replies and help!