Hi, I was trying to make use of luup.variable_watch, against a virtual switch, but I must be missing something - please could someone look at the following code and let me know what’s wrong? .
function watchCallBackTest (lul_device, lul_service, lul_variable, lul_value_old, lul_value_new)
require "xxprowlnotification"
local a = lul_service or "nothing"
local b = lul_variable or "nothing"
local c = lul_value_old or "nothing"
local d = lul_device or "nothing"
local e = lul_value_new or "nothing"
xxprowlnotification.my_prowl ("VeraPlus Testing", "Watch Callback Test", "Callback information equals " ..a.." , " ..b.. " , " ..c.." , " ..d.. " , " ..e.. ".")
end
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:SwitchPower1", "Status", 60)
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:SwitchPower1", "Target", 60)
The log shows the variable changing, but there is no response - the function is not called…
01
10/27/20 22:48:03.621
JobHandler_LuaUPnP::REQ_VariableGet variable not found <0x73394520>
The function works fine when I call it on its own, plus I’ve added actions into the function too, like turning lights on or off, but for some reason the function is never called when the variable being watched changes.
Sorry I should have said, yes the code is in Lua Startup…
I’m wondering - Is there a way to see what variables are being watched , so I know that it’s been registered, and if not what am I missing , what could be wrong that stops it being registered/called.
@reneboer earlier suggested that you add a luup.log() statement in the watch function. This is the way. You need to add it as the first line, before the require. The require is the riskiest statement in the bunch and could be failing, so everything after is not being executed, including all the other actions you tried to make it do. I would follow his suggestion, being careful as I said to make the log statement be the first thing it does.
Then, if you see the log message emitted to the log, you know (a) the callback is working, and (b) something else, possibly the require, is not. Let’s take it one step at a time and see if you can make the log statement work first.
I have moved the luup.log to the very top, plus added a few more variables to the watch list - but it seems to have made no difference, the updated code is below and the logs show the following…
function watchCallBackTest (lul_device, lul_service, lul_variable, lul_value_old, lul_value_new)
luup.log("watchCallBackTest function called")
local a = lul_service or "nothing"
local b = lul_variable or "nothing"
local c = lul_value_old or "nothing"
local d = lul_device or "nothing"
local e = lul_value_new or "nothing"
luup.log("watchCallBackTest function called")
require "xxprowlnotification"
xxprowlnotification.my_prowl ("VeraPlus Testing", "Watch Callback Test", "Callback information equals " ..a.." , " ..b.. " , " ..c.." , " ..d.. " , " ..e.. ".")
end
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:SwitchPower1", "Status", 60)
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:SwitchPower1", "Target", 60)
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:VSwitch1", "Status", 60)
luup.variable_watch ('watchCallBackTest', "urn:upnp-org:serviceId:VSwitch1", "Target", 60)
First of all, are you reloading Luup after every time you change the code? It is, after all, startup Lua… so it will only be re-parsed/executed at startup. You can make sure that’s going well by adding a luup.log() statement at the start and end of the code, each with different strings (e.g. “START STARTUPLUA” and “END STARTUPLUA”). You should be able to restart Luup, and at then go look at the LuaUPnP log file and find at least the output of the first luup.log() statement’s output (e.g. “START STARTUPLUA”). From there, follow the log output and see if there are errors logged, or if you get the final luup.log() statement’s output. If you have errors, fix what is indicated by the errors.
OK, so in one of your scenes… cifsmount… go hunting! LuaView is built for this… remember LuaView only finds syntax errors, not runtime errors (e.g. a module that can’t be loaded, reference to a device that doesn’t exist, etc.).
One of the horrid things Vera does at startup is it combines all the Lua from all of your scenes, plus the startup Lua, into one big code block, and then executes that. If you have an error in any scene Lua or startup Lua, it blows up everything (probably why your startup Lua is failing then). And then they only show the error, but not the entire block, so it makes it really hard to isolate the code (the line number shown is meaningless, for example, because it’s relative to the block, which you cannot see).
But if you find that string “cifsmount”, you’re in the hot zone for the problem here…
I’ve just added ‘ - -‘ to the beginning of that line for now to try and work out what it was causing an error, especially as it had been working fine for ages.
QQ: when using modules, and wanting to call functions stored within them from luastartup - do they need to be global functions in the module ?
The luastartup code is …
require "xxcifsmount"
xxcifsmount.cifsmount()
The upload file is called xxcifsmount.lua
module("xxcifsmount", package.seeall)
local function cifsmount()
Awesome! By the way, together with that error you should have seen a “Error in Lua for Scenes and Events” or something to that effect in your UI, even before you started this particular effort. If you’re not seeing those messages, you may want to turn them on in the notification settings or by running this:
The function is declared local, so it will not be accessible outside the module in which it is declared. Remove that local keyword to make a function you can access from outside the module.
Well, they’re not “global” in the real sense, they have “module scope”, which is to say, they appear to be global within the module, but if you want to access them from outside the module, you need to qualify them with the scope. When you do a require, you get a table with the module name… you require "xxcifsmount" and you get a table called “xxcifsmount” through which you can access the function: xxcifsmount.cifsmount( arguments ). So the “xxcifsmount” table is your scope qualifier.