openLuup and luup.variable_watch

Hello,

openLuup is not totally compliant with luup.variable_watch (http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_variable_watch)

parameters are: function_name (string), service (string), variable (string or nil), device (string or number)

If variable is nil, function_name will be called whenever any variable in the service is changed. It’s not said in this doc, but it’s the same when device is nil.

OpenLuup doesn’t accept a device with value nil.

Yes, that’s absolutely true, and documented in the source code file luup.lua

-- Whenever the UPnP variable is changed for the specified device, 
-- which if a string is interpreted as a UDN [NOT IMPLEMENTED] 
-- and if a number as a device ID, function_name will be called
-- with parameters: device, service, variable, value_old, value_new.
-- If variable is nil, function_name will be called whenever any variable in the service is changed. [NOT IMPLEMENTED]
local function variable_watch (global_function_name, service, variable, device)

In truth, I never imagined anyone would use this. But what do I know?

It can be implemented, but as a matter of interest… why?

It’s more the feature when device is nil that I need.

I have a plugin (RulesEngine) that does a lot of luup.variable_watch.
As luup engine does not allow to un-watch, unless to do a reload, the plugin just watches service and variable.
When an event occurs, it checks if the device which has triggered is one of the devices it watches.

Doing this way, it allows to stop the watch if needed without a luup reload.

You mentioned that this is not documented… what exactly is the functionality when device is omitted?

It’s the same idea as variable is nil.

If variable is nil, function_name will be called whenever any variable in the service is changed.
If device is nil, function_name will be called as soon as the variable in the service for any device is changed.

If device and variable are nil, function_name will be called for any device and variable as soon as there’s a change on the service (for a device).

If several variables have been changed in the service, or several devices have a service variables changed, then are there multiple callbacks (one for each device, service, and variable?)

I presume so.

Yes, function_name is called at each change and you can find the device and the variable in the parameters.

I’m rather hoping that a watch call with all parameters nil does not do the callback for every variable change in the system?

Either way, this more general application of variable watch is an interesting opportunity for race conditions - if the callback routine changes any variable that it’s watching…

FYL … I’ve implemented the nil device variable (and, incidentally, a nil service too) for a specified device. So now on to the case you really wanted.

Thanks for the nil device

The Vera does not accept a “luup.variable_watch” with service nil, so this should’nt be used for compatibility.

OK, it’s done and GitHub updated.

The following combinations are allowed, as shown in this log of the watch call in a test case:

2015-11-03 17:40:53.424   luup.variable_watch:4: callback=VAR_WATCHER, watching=4.AKB_service.lastDelay
2015-11-03 17:40:53.424   luup.variable_watch:4: callback=SRV_WATCHER, watching=4.AKB_service.*
2015-11-03 17:40:53.424   luup.variable_watch:4: callback=DEV_WATCHER, watching=4.*.*
2015-11-03 17:40:53.424   luup.variable_watch:4: callback=ALL_WATCHER, watching=*.AKB_service.*
2015-11-03 17:40:53.424   luup.variable_watch:4: callback=DEL_WATCHER, watching=*.AKB_service.lastDelay

…so I do allow a nil serviceId in the specific case of a defined device, but undefined variable: it simply makes the callback for all changes to that device. It was, essentially, a side-effect of the other changes I made, so it’s there in openLuup, even if it’s not there in Vera. (Without adequate documentation, who could tell? - except for @vosmont with, presumably, extensive testing!) You don’t have to use it.

Great ! It works well ;D

Thanks