So http://bugs.micasaverde.com/view.php?id=1302 describes the defect of not being able to “unwatch” a variable, and Im looking into ways to work around this until it gets fixed properly. I came up with the following notion:
local watch_t = {}
local watch_id = 1
function watch_register(function_name, service, variable, device)
local req = {}
req.n = 5
req["function_name"] = function_name
req["service"] = service
req["variable"] = variable
req["device"] = device
req["id"] = watch_id
watch_t[req.id] = req
watch_id = watch_id + 1
return req.id
end
function watch_unregister(id)
watch_t[id] = nil
end
function watch_callback(lul_device, lul_service, lul_variable, lul_value_old, lul_value_new)
for id,req in pairs(watch_t) do
if((not req.device or (req.device == lul_device)) and
(not req.service or (req.service == lul_service)) and
(not req.variable or (req.variable == lul_variable))) then
req.function_name(lul_device, lul_service, lul_variable, lul_value_old, lul_value_new)
end
end
end
luup.variable_watch("watch_register", nil, nil, nil)
Ive not actually tested this yet, but the Lua is good. The biggest limitation I have is the device argument to watch_register must be a device, and cannot be a UDN (I suppose I can do a lookup, but thats more complex than I need for now). Basic usage is the same idea as luup.watch_variable, but instead of passing a string of the function name, you pass the function itself, and you are returned an id that can be used to unregister it at a later time.
A question of scope: if this gets put in the Lua Startup section, will plugins, etc be able to see the defined functions? If not, is there some global scoping I can use?
A question of threads: There does not seem to be a good way to put a semaphore/mutex in place to protect watch_id from simultaneous access with multiple threads. Assuming multiple plugins use this in their startup routines, is there any assurance they do not run all at once? Is there some better way to provide the mutex?