NETIO Lua Manual
Contents
Script starting
LUA Scripts in NETIO are event driven. That means if some event is triggered the script run exactly once. One of "triggers" is for example System started up. You can find list of all events called "triggers" in NETIO Lua Reference.
Periodical scipts
In NETIO there is no way for triggering scripts periodically (e.g. every 10 seconds) usng standard triggers. For such scripts the trigger System started up and the function delay() must be used. This function calls itself and allows to run some procedures periodically.
- Example switching output 1 every 10 seconds:
DoPeriod = 10 -- repeat period in seconds ------------------------------------------------- function doPeriodically() -- your periodical code -- your periodical code -- your periodical code -- your periodical code -- your periodical code -- your periodical code delay(DoPeriod,function() doPeriodically() end) end doPeriodically()
- This script can be launch using e.g. System started up trigger.
- Only way how to disable these scripts is restart of NETIO, or usage of global variables.
Debugging
To debug your code, use log() and logf() functions. See the output in system events log.
Data types and variables
Lua supports these data types:
- nil (to assign nil value effectively deletes the variable)
- boolean (falsy values are nil and false only; "" and 0 evaluates as true)
- number (decimals only in standard Lua, integers only in Netio Lua)
- string (same strings share same address, so equality operator measures both address and value)
- tables are associative arrays. (Tables with numeric indices are, well, just arrays.)
local numbers = {2,3,7,5} -- array (first index = 1) local dictionary = {one=1, two=2, three=3} -- table local numbersZeroBased = {[0]=2,3,7,5} -- array (first index = 0)
local keyword limits the variable scope to the block (ended by end) where it is declared. To access an upvalue (variable defined outside of the scope), just omit the local keyword.
Operators
Lua has its own manners:
~=
is inequality operator..
is string concatenation (don't use plus)
no increment/decrement operatori++i = i + 1
no ternary operator. Use (and get used to) and idiom instead:max = a<b ? b : amax = (a<b) and b or a
- or idiom works:
x = x or 42
is equivalent toif not x then x = 42 end
Conditions
Lua conditions has casual syntax, see here. Just keep in mind to merge else
and if
to elseif
or multiple end
s are required.
Note that falsy values are nil and false only. Empty string and 0 evaluates as true. If you come from C, you might be surprised by following snippet:
if devices.system.output1_consumption then -- always happens, even if the consumption is 0 log("Outlet 1 supplies power") end
if not devices.system.output1_consumption then -- never happens, even if the consumption is 0 log("Outlet 1 is idle") end
Loops
Lua has break
statement, but no continue
(use condition inside loop instead). Additionally, Netio Lua implementation limits the loop iterations to 32k.
While
While syntax is not different to other languages:
local i = 0 while i~=3 do i = i + 1 logf("%d",i) end
Repeat until
Repeat until syntax is the same as Pascal's, other languages have similar do-while loops:
local i = 0 repeat i = i + 1 logf("%d",i) until i==3
Numeric for
Arrays in Lua are one-based (in indices are not specified, the first one is 1, not 0).
local arr = {2,3,7,5} for i=1,#arr do logf("%d",arr[i]) end
for initVar,limit,increment do
- number assignment
initVar
inits loop-local variable - number
limit
loops until initVar reaches this value - optional number
increment
after each loop initVar increment by this value (default 1)
Generic for
Is rather sophisticated. Most common example (the order of elements in pairs()
is not guaranteed):
local tab = {one=1, two=2, three=3} for key,val in pairs(tab) do logf("%s:%d",key,val) end
Generic for syntax
for var_1, ..., var_n in explist do block end
is equivalent to (Full explanation here.)
do local _f, _s, _var = explist while true do local var_1, ... , var_n = _f(_s, _var) _var = var_1 if _var == nil then break end block end end
Iterator closure that holds its state
function iter(a) local i = 0 return function() i = i+1 return a[i] end end local arr = {2,3,7,5} for value in iter(arr) do logf("%d",value) end
Stateless iterator (in this case returns variable list: key and value)
function iter(a,i) i = i+1 if a[i] then return i,a[i] end end local arr = {2,3,7,5} for k,v in iter,arr,0 do logf("%d:%d",k,v) end
Same effect using ipairs()
Lua function (without initial state)
for k,v in ipairs(arr) do logf("%d:%d",k,v) end
Now return to the most common example above using pairs()
Lua function and read about pairs()
and ipairs()
implementation here.
Functions
Lua allows multiple results (comma separated):
function diskSpace() return devices.system.freeSpace, devices.system.totalSpace end logf("Free space: %d MB", diskSpace()) -- only first return value is used local free,total = diskSpace() -- values are stored into LHS var-list logf("Free space: %d %%", 100*free/total)
Variable-length arguments are also available:
function sum(...) local result = 0 for _,v in ipairs(arg) do result = result + v end return result end logf("Sum: %d", sum(2,3,5))