NETIO 4x includes a native graphical calendar/timer (Scheduler function). However, the Scheduler is configured for each output separately and may be impractical for short sequences.
The AN07 Lua script allows to specify in a text form when and how to perform actions with the outputs. The action can also be a “no action” (value 5, output state unchanged). The value of 5 may be useful when the output is controlled via a M2M protocol or with its button.
The script controls the outputs at specified times
"1111,22:30:00,0001000"
„Outputs,time,week-days“
- Outputs = Action for each of the outputs – O1 O2 O3 O4
- Time = Time when to perform the action
- WeekDays = Days of the week when the action shall be performed
Supported devices: NETIO 4All, NETIO PowerPDU 4C, NETIO 4
Creating the rule
To create and run the Lua script, do the following:
1) In the Actions section of NETIO 4 web administration, click Create Rule to add a rule.
2) Fill in the following parameters:
- Enable rule: checked
- Name: Lua scheduler (user-defined)
- Description: Lua script for switching outputs based on time (user-defined)
- Trigger: System started up
- Schedule: Always
3) Copy the following code and paste it into the field for the Lua script:
------------NETIO AN07------------ ------------Section 1------------ -- Actions for all outputs (1-4), time and days -- Format: -- 4 x number with action (0 - turn off, 1 - turn on, 2 - short off, 3 short on, 4 - toggle, 5 - keep previous state), time (hours:minutes:seconds), day (Mo-Sun, 0 - not active in this day, 1 - active in this day) -- Example – Toggle O1 and turn off other Outputs at 18:30 every day except Wednesday: "4000,18:30:00,1101111" local states = { "4444,16:14:00,1111111", "1000,09:00:00,1111100", "5515,22:33:44,0000011", "0000,00:00:00,1000000" } local initialState = "0055" -- state to which outputs will be set after restart (0-5) local shortTimeMs = 1000 -- time used for action 2 and 3 [milliseconds] ---------End of Section 1--------- local sortedStates = {} local swapped = false function checkFormat() for i=1,4 do local test = tonumber(initialState:sub(i,i)) if test == nil or test>5 or test<0 then logf("Action in initialState for outlet %d is invalid!", i) return false end end for i=1,#states do for j=1,4 do local test = tonumber(states[i]:sub(j,j)) if test == nil or test>5 or test<0 then logf("Action in state %d for outlet %d is invalid!", i,j) return false end end if states[i]:sub(5,5) ~= "," or states[i]:sub(14,14) ~= "," then logf("Time or days in state %d are not separated by comma!", i) return false end local hours = tonumber(states[i]:sub(6,6)) local minutes = tonumber(states[i]:sub(9,9)) local seconds = tonumber(states[i]:sub(12,12)) if hours == nil or hours > 2 or hours < 0 or tonumber(states[i]:sub(7,7)) == nil or states[i]:sub(8,8) ~= ":" or minutes == nil or minutes > 5 or minutes < 0 == nil or tonumber(states[i]:sub(10,10)) == nil or states[i]:sub(11,11) ~= ":" or seconds == nil or seconds > 5 or seconds < 0 == nil or tonumber(states[i]:sub(13,13)) == nil then logf("Time in state %d is invalid!",i) return false end for j=15,21 do local day = tonumber(states[i]:sub(j,j)) if day == nil or (day ~= 0 and day ~= 1) then logf("Value for day %d in state %d is invalid", (j-14), i) return false end end end log("FORMAT OK") return true end function loadStates() for i=1,#states do sortedStates[i] = {state,time} sortedStates[i].state = states[i] sortedStates[i].time = (3600*tonumber(states[i]:sub(6,7)) + 60*tonumber(states[i]:sub(9,10)) + tonumber(states[i]:sub(12,13))) end end function sortStates() for i=1,#states-1 do swapped = false for j=1, #states-1 do if sortedStates[j].time > sortedStates[j+1].time then local temp = sortedStates[j] sortedStates[j] = sortedStates[j+1] sortedStates[j+1] = temp swapped = true; end end if not swapped then break end end end function startScheduler() -- Current time local stringTime = os.date("%X") local time = (3600*tonumber(stringTime:sub(1,2)) + 60*tonumber(stringTime:sub(4,5)) + tonumber(stringTime:sub(7,8))) local nextState = sortedStates[1].state local timeLeft = (86400-time+sortedStates[1].time) local stateIndex = 1 for i=1,#sortedStates do if time < sortedStates[i].time then nextState = sortedStates[i].state timeLeft = (sortedStates[i].time - time) stateIndex = i break end end -- Delay between states must be at least 1s if timeLeft <= 0 then timeLeft = 1 end delay(timeLeft,function() scheduler(nextState,stateIndex) end) end function scheduler(currentState, stateIndex) if checkDay(currentState) then setOutputs(currentState:sub(1,4)) end local nextIndex = stateIndex%#sortedStates + 1 local currentTime = sortedStates[stateIndex].time local stringTime = os.date("%X") local realTime = (3600*tonumber(stringTime:sub(1,2)) + 60*tonumber(stringTime:sub(4,5)) + tonumber(stringTime:sub(7,8))) if currentTime ~= realTime then currentTime = realTime end local timeLeft = 0 if nextIndex == 1 then timeLeft = (86400-currentTime+sortedStates[nextIndex].time) else timeLeft = sortedStates[nextIndex].time - currentTime end -- Delay between states must be at least 1s if timeLeft <= 0 then timeLeft = 1 end delay(timeLeft,function() scheduler(sortedStates[nextIndex].state,nextIndex) end) end function checkDay(state) local day = tonumber(os.date("%w")) -- os.date("%w") returns 0 for Sunday if day == 0 then day = 7 end if tonumber(state:sub(14+day,14+day)) == 1 then return true end return false end function setOutputs(state) for i=1,4 do value = tonumber(state:sub(i,i)) if value == 0 then -- turn off devices.system.SetOut{output = i, value = false} elseif value == 1 then -- turn on devices.system.SetOut{output = i, value = true} elseif value == 2 then -- short off devices.system.SetOut{output = i, value = false} milliDelay(shortTimeMs,function() devices.system.SetOut{output=i,value=true} end) elseif value == 3 then -- short on devices.system.SetOut{output = i, value = true} milliDelay(shortTimeMs,function() devices.system.SetOut{output=i,value=false} end) elseif value == 4 then -- toggle if devices.system["output" ..i.. "_state"] == 'on' then devices.system.SetOut{output=i,value=false} else devices.system.SetOut{output=i, value=true} end elseif value == 5 then -- do nothing end end end function initiate() setOutputs(initialState) end log("Lua scheduler started") checkFormat() initiate() loadStates() sortStates() startScheduler()
Setting the variables
-
states
- Variable that specifies the actions, times and days of week. It is a table of strings. Each string defines the actions at one particular time. Individual strings are enclosed in double quotes and separated with commas
- Each string has the form of "aaaa,hh:mm:ss,mtwtfss".
-
action (aaaa)
- The first 4 symbols specify the actions to be performed with the outputs at the given time.
- The first number corresponds to the first output, the second number to the second output, and so on.
- Action numbers follow the standard numbering in NETIO devices:
- 0 – output switched off
- 1 – output switched on
- 2 – “short off” (output is set to 0, and after a delay specified in the shortTimeMs variable, the output is set to 1)
- 3 – “short on” (output is set to 1, and after a delay specified in the shortTimeMs variable, the output is set to 0)
- 4 – “toggle”, if the output was on, it is turned off, and vice versa
- 5 – the output is unchanged
- Example – to switch on output 3, switch off outputs 1 and 2, and leave output 4 unchanged: 0015
-
time (hh:mm:ss)
- The second part of the string specifies the time when the action shall take place.
- The script takes the time from the NETIO device (can be set in the web administration in Settings - Date/Time).
- The time format is: hours:minutes:seconds
- The hour must be specified in the two-digit 24-hour format (9:00am is written as 09:00:00, 5pm is written as 17:00:00).
- Example – to set 5:30am: 05:30:00
-
day (mtwtfss)
- The action can be restricted to certain days of the week.
- This part of the string specifies on which days of the week the action shall take place.
- Individual digits correspond to individual days of the week (from Monday to Sunday).
- Possible values are 0 and 1.
- 0 – the action is not performed on the given day.
- 1 – the action is performed on the given day.
- Example – to perform an action on weekends only: 0000011
- Individual parts of the string are separated with commas and the whole string is enclosed in double quotes.
- Example – to toggle all outputs at 9:30am every workday (Monday to Friday): "4444,09:30:00,1111100".
- Example – to switch off all outputs every Friday at 6pm: "0000,18:00:00,0000100"
-
initialState
- This variable contains the actions to perform with individual outputs whenever the device is restarted.
- It is a string enclosed in double quotes.
- The string has the form of "aaaa". Replace each "a" symbol with the number of the action to perform with the given output.
- The action values are the same as in the states variable.
- Example – to switch off outputs 1 and 2 and leave outputs 3 and 4 unchanged: local initialState = "0055
-
shortTimeMs
- Specifies (in milliseconds) for how long is the output on and off for actions 2 and 3 respectively
- The minimum value is 100 ms
- Example for 2-second pulses: shortTimeMs = 2000
Starting the script
After configuring all the parameters and saving the script, the NETIO smart sockets device needs to be restarted. After the device boots, the script starts and the outputs are set to the states determined by the initialState variable.
FAQ:
1) How many individual actions can this script contain?
The number of actions is unlimited. The states variable can contain as many strings as needed.
2) What happens with the output if its state is changed through a different channel (e.g. using the button at the device, over the Web, using another M2M protocol, or from the mobile app)?
The script starts at the specified time and sets the output according to the table. If the script is supposed to switch on an output that is already switched on, nothing happens and the output remains switched on.
To keep an output unchanged (regardless of whether its state is 0 or 1), use action 5 (5 = leave the output state unchanged).
3) What happens when the time changes to Daylight Savings Time or back?
When the time changes, it is possible that an action scheduled during the transition will not take place. Subsequent actions will be performed normally.
4) What if the device is powered off at the time specified in the table?
In this case, the action is not performed. After the NETIO sockets device is powered on, the outlets are set according to the initialState variable at the beginning of the Lua script, and the sequence continues according to the current time.
5) Do the actions in the table have to be in chronological order?
It is not necessary but we recommend doing it nevertheless for clarity.
6) What if I encode two actions at the same time?
The first one is performed, and the second one is performed one second later.
Supported FW versions:
3.0.0 and higher (Archiv firmware)
More about Lua:
https://wiki.netio-products.com
This Application Note is compatible with:
|
NETIO 4NETIO 4 is smart power socket (smart power strip) with four 230V/8A sockets, connected to LAN and WiFi. Each of the four power sockets can be individually switched on/off using various M2M API protocols. NETIO 4 is a unique product designed for IT, industry, smart homes, multimedia installations and other applications. Use the product whenever you need 230V sockets controlled by a mobile app, by a computer program (via M2M API) or by a custom script (Lua), and featuring a timer (Scheduler) or auto reboot functionality (IP WatchDog).
|
|
NETIO 4AllNETIO 4All is a PDU module featuring four 230V/8A power sockets with consumption metering for each socket as well as LAN and WiFi connectivity. Each of the four sockets can be individually switched on/off over the Web or using various M2M API protocols. Electricity consumption (A, W, kWh) can be measured at each power socket. NETIO 4All smart sockets are designed for remote measurement and control of electrical sockets. Use the product whenever you need 230V sockets controlled by a mobile app, by a computer program (via M2M API) or by a custom script (Lua) that runs directly in the NETIO 4All smart socket device. |
|
NETIO PowerPDU 4CNETIO PowerPDU 4C is a small 110/230V PDU (Power Distribution Unit). Each of the four IEC-320 C13 outlets can be independently controlled (On / Off / Reset / Toggle). Electrical parameters (A, W, kWh, TPF, V, Hz) are measured with high accuracy at each outlet. The device features two LAN ports (and a built-in Ethernet switch) for connecting to a LAN. Each power output supports ZCS (Zero Current Switching) to protect the connected equipment. |