nodecentral
nodecentral

Reputation: 466

Lua - How can I dynamically construct a function’s conditions/options?

I have the following Lua function, which I want to construct dynamically, but I can’t seem to get it to work.

Calling the function normally would look like this wattsFromDim.LWB010(128).

However I want to be able to dynamically populate the model ‘LWB010’ and ‘Brightness level’ values wattsFromDim.MODELID(Brightness-level) to get the required value from the array/table.

-- Dummy data
local wattsFromDim = {
  LWB010 = function (dim) return 0.43981651 * math.exp(0.012712893 * dim) end.
  LWA004 = function (dim) return 0.45677776 * math.exp(0.012712893 * dim) end,
  LWW001 = function (dim) return 0.48765897 * math.exp(0.012712893 * dim) end,
  LWB006 = function (dim) return 0.40134543 * math.exp(0.012712893 * dim) end,
  LCT007 = function (dim) return 0.41987568 * math.exp(0.012712893 * dim) end
}

for k,v in pairs(huelights) do
-- FYI - json - v[1]=deviceID, v[2]=status, v[3]=brightness, v[4]=modelNo
    if v[2] == true then
        -- local watts = wattsFromDim.LWB010(128)
        local watts = wattsFromDim. v[4] ( v[3] ) *-- runtime errors*
        print(v[4], v[2], v[3], watts)
    end
end

Any/all help is much appreciated..

Upvotes: 0

Views: 133

Answers (2)

koyaanisqatsi
koyaanisqatsi

Reputation: 2813

A corrected version with metamethod __call example
Shown in lua -i ( Console )

-- I have a table for Lua code for pure not interpreted text strings
code
table: 0x5668ecf0
print(code.cmd) -- function for adding more code.codestrings
-- cmd()
return function(cmd)
local cmd=io.popen(cmd, 'r')
cmd=cmd:read('a+')
return cmd
end
-- code.cmd is already loaded, so lets load a wfd.lua into code.wattsFromDim
code.wattsFromDim=cmd('cat wfd.lua')
-- Check the code by simply print it
print(code.wattsFromDim)
local wattsFromDim = {
  LWB010 = function (dim) return 0.43981651 * math.exp(0.012712893 * dim) end,
  LWA004 = function (dim) return 0.45677776 * math.exp(0.012712893 * dim) end,
  LWW001 = function (dim) return 0.48765897 * math.exp(0.012712893 * dim) end,
  LWB006 = function (dim) return 0.40134543 * math.exp(0.012712893 * dim) end,
  LCT007 = function (dim) return 0.41987568 * math.exp(0.012712893 * dim) end
}

setmetatable(wattsFromDim,{__call=function(...)
self,huelights=...
assert(huelights)
for k,v in pairs(huelights) do
-- FYI - json - v[1]=deviceID, v[2]=status, v[3]=brightness, v[4]=modelNo
    if v[2]==true then
        -- local watts=wattsFromDim.LWB010(128)
        local watts=self[v[4]](v[3])
        print(v[4],v[2],v[3],watts)
    end
end
end})
return wattsFromDim
-- EOF

-- Now load the code into wattsFromDim
wattsFromDim=load(code.wattsFromDim)()
-- Done, create a sample data table...
huelights={{1,true,1,'LCT007'},{0,false,0,'LWW001'},{3,true,0,'LWA004'}}
-- Here we go...
wattsFromDim(huelights) -- Remember it is a table with __call metamethod
LCT007  true    1   0.42524758849267
LWA004  true    0   0.45677776
-- __call metamethod: Job done ;-)

Upvotes: 0

Oka
Oka

Reputation: 26355

Simply index the table using the model's string value. This gets you a function, which you call with your brightness value.

local watts = wattsFromDim[v[4]](v[3])

Remember that these two forms of member access are equivalent.

wattsFromDim.LWB010(128)
wattsFromDim["LWB010"](128) 

Upvotes: 2

Related Questions