call_action SendConfig
-
rafale77replied to DesT on Dec 28, 2020, 11:33 PM last edited by rafale77 Dec 28, 2020, 6:38 PM
It is this function at line 521 of the z-way bridge
SendConfig = function (d,args) local cc = 112 local par,cmd,sz = args.parameter, args.command, args.size or 0 local data = "Set(%s,%s,%s)" data = data: format(par,cmd,sz) local altid = luup.devices[d].id local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, data) end,
We can add a get function but will have to create a variable to store the return...
GetConfig = function (d,args) local cc = 112 local par = args.parameter local data = "Get(%s)" data = data: format(par) local altid = luup.devices[d].id local id, inst = altid: match (NIaltid) status, response = Z.zwcommand(id, inst, cc, data) luup.variable_set(SRV.HaDevice, "config", response, d) end,
-
Not quite, My code proposal above creates a “config” variable which you would have to watch or get within the lua code.
As far as I know the luup.call_action does not return a variable unfortunately. It returns a status Boolean. -
In fact, action calls can, and do, return associated variable values. You just have to make sure that the service file is written correctly.
-
Interesting... I did not know that. I submitted a pull request on github though I have not tested it. Take a look.
Edit: I am able to get z-way to send a get parameter command but it doesn't appear to return the correct value. It seems to always be returning 0.
-
Try the updated plugin file below. I can't figure out how to make a luup.call_action return any value other than 0 but... I created 2 new functions:
-GetConfig which will get z-way to poll the parameter value from the device.
-UpdateConfig which gets the value from z-way-server to openLuup and saves it to a device variableThe way to use them is for your example
luup.call_action("urn:micasaverde-com:serviceId:HaDevice1","GetConfig",{parameter=6}, ID["D-Bathroom0"]) luup.call_action("urn:micasaverde-com:serviceId:HaDevice1","UpdateConfig",{parameter=6}, ID["D-Bathroom0"])
Which will create and update a variable called Config(6) which will have the value you are looking for.
-
@rafale77 said in call_action SendConfig:
Interesting... I did not know that.
Yes, indeed. Standard behaviour for
luup.call_action()
as documented here:http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_call_action
The fourth return parameter is a table of named return arguments.
-
@rafale77 said in call_action SendConfig:
Try the updated plugin file below.
A few problems here:
GetConfig()
data2 = data2: format(par)
...this variable is completely undefined, and this line should cause an error.
UpdateConfig()
response = Z.zwcommand(id, inst, cc, data)
this should really be a local:
local response = Z.zwcommand(id, inst, cc, data)
However, I'd prefer an implementation which used the luup.call_action() return parameter. I'll provide a version a bit later.
-
Here's a skeleton for the code that you need:
GetConfig = { run = function() -- do whatever you need to get the status into ZWay_ZWaveCONFIG ZWay_ZWaveCONFIG = 42 end, extra_returns = {Config = function () return ZWay_ZWaveCONFIG end} },
I'm unable to work out from your posted code exactly what you need to do to get the value you want, but just provided a dummy line which sets a global to
42
.Running this from Lua Test on my machine:
local d = 23 local sid = "urn:micasaverde-com:serviceId:HaDevice1" local e,m,j,a = luup.call_action(sid, "GetConfig", {}, d) print(pretty {e,m,j,a})
gives the output:
{0,"",0,{Config = 42}}
-
rafale77replied to akbooer on Dec 30, 2020, 3:14 PM last edited by rafale77 Dec 30, 2020, 10:19 AM
Thank you. This is what the code should look like:
GetConfig = { run = function() local cc = 112 local par = args.parameter local data = "Get(%s)" data = data: format(par) local data2 = "data[%s].val.value" data2 = data2: format(par) local altid = luup.devices[d].id local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, data) extra_returns = {Config = function () return Z.zwcommand(id, inst, cc, data) end} },
Note, there might need to be a small delay between the two zwcommand executions to allow time for away to get the parameter from the device which is why I had the idea of splitting out the two actions.
Note that I also modified the zwcommand function for it to return a variable. -
That has a syntax error... you are missing an
end
.Should be:
GetConfig = { run = function() local cc = 112 local par = args.parameter local data = "Get(%s)" data = data: format(par) local data2 = "data[%s].val.value" data2 = data2: format(par) local altid = luup.devices[d].id local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, data) end, extra_returns = {Config = function () return Z.zwcommand(id, inst, cc, data) end} }
-
another error on my part...
the extra return command should use data2
GetConfig = { run = function() local cc = 112 local par = args.parameter local data = "Get(%s)" data = data: format(par) local data2 = "data[%s].val.value" data2 = data2: format(par) local altid = luup.devices[d].id local id, inst = altid: match (NIaltid) Z.zwcommand(id, inst, cc, data) end, extra_returns = {Config = function () return Z.zwcommand(id, inst, cc, data2) end} }
Edit: don't the variables need to be global to be reused in another function? Do they need to be redefined in the extra_returns function?
-
@rafale77 said in call_action SendConfig:
don't the variables need to be global to be reused in another function?
Yes, that's true. It's why in my original example I used a global for the single return parameter. You could simply do that here by including the second call at the end of the main
GetConfig()
function. -
huhhh very tempted to add a luup.sleep() here to put a delay between the two commands... It would be so much more convenient than a luup.delay and having to define another function.
-
obviously it is work in progress. The way I implemented it works in spite of the typos but it's not ideal. With AK's help, I think we can get something better.
@akbooer if I run the command as part of the main run command, the return is a function... not a variable as I was expecting. It is pretty strange since I get the variable if I take that return and do a luup.variable_set() with it.
-
I'm playing with the SendConfig a lot since couple of days and I can tell you that I need to put some delay between a couple of SendConfig as something it's not working all the time mixed with some "usual" zwave command!
For example, at night, I turn off a couple of zwave dimmer/switch and sending a couple of SendConfig and the SendConfig are not working 100% of the time!
Maybe zwave stack is handling on/off command differently from "SendConfig" in the queue!
-
@rafale77 said in call_action SendConfig:
I run the command as part of the main run command, the return is a function...
Ah yes. Update to the latest development branch for openLuup.
I discovered a long-standing omission in the scheduler’s return parameter processing. It should now evaluate those parameters which are functions.
-
rafale77replied to akbooer on Dec 30, 2020, 9:19 PM last edited by rafale77 Dec 30, 2020, 4:23 PM
@akbooer
Awesome. I thought I was missing something again.
Is it still strongly recommended not to use luup.sleep with openLuup? I put a 1 sec one in there just to improve reliability.Try the file below. You know what to do... You get the value from the luup call action just as AK is describing above and you do need to update openLuup to the latest dev version.
The reliability of the command, I think is a timing issue and the get will be worse because it needs to get a response from the device to get the up to date value. Otherwise it will just report the previous value. Not a problem if you did not update it but I think that your purpose is to toggle these configs quite a bit.
-
@rafale77 said in call_action SendConfig:
I put a 1 sec one in there just to improve reliability.
If that's what makes it work... although it would be nice to find out why the delay.
Oh, I was hoping that this wouldn't be called too often!
13/52