Supported devices: NETIO 4All, NETIO PowerPDU 4C,
The Lua script shown in NETIO AN03 monitors the current flowing through a selected output (or the sum of currents through all the outputs). If the current exceeds a specified limit, the script starts counting time. When the overcurrent condition lasts longer than the specified time period without interruption, the Lua script turns the socket off and sends an e-mail.
For the example in the picture, the script can be configured in the following way. If the limit is exceeded for a short time only (situation A), the output remains on. If the current limit is exceed for a longer time (situation B), the output is switched off.
NETIO AN03 also shows how to detect undercurrent in addition to overcurrent. For instance, this can be used to detect that during an extended period of time, an A/C unit has only been consuming power for ventilation but not for cooling, and send an e-mail alert.
The example demonstrates how to use global variables and how to measure current.
Contents
- Creating the rule
- Creating the Lua script
- Adding undercurrent monitoring
- Setting up e-mail alerts
Creating the rule
To create and run a 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:
- Enabled: checked
- Name: Watcher (user-defined)
- Description: Current watcher (user-defined)
- Trigger: System variables updated
- Schedule: Always
3) Copy the following code and paste it into the field for the Lua script:
------------Section 1------------ local output = 1 -- choose number of outlet local currentLimit = 100 -- choose ampere limit [mA] local timeLimit = 1 -- choose time limit [seconds] local recipient = "my.email@example.com" local subject = "Output takes too much power" local text = "Output " .. string.format(output) .. " on your NETIO exceeded limit " .. string.format(currentLimit) .. "mA!" ---------End of Section 1--------- -- Global variables: _G.timestamp local current = 0 function shutDown() if output == 0 then for i=1,4,1 do devices.system.SetOut{output=i, value=false} end else devices.system.SetOut{output=output, value=false} end end function checkTime() local timeNow = os.time() if (_G.timestamp == 0 or _G.timestamp == nil) then _G.timestamp = timeNow end if (timeNow - _G.timestamp >= timeLimit) then return true end return false end function currentMeasurement() if output == 0 then for i=1,4,1 do current = current + devices.system["output" .. i .. "_current"] end else current = devices.system["output" .. output .. "_current"] end if current > currentLimit then if checkTime() then shutDown() mail(recipient, subject, text) end else _G.timestamp = 0 end end currentMeasurement()
4) To finish the rule creation, click Create Rule at the bottom of the screen.
Creating the code for Lua script in NETIO inteligent power socket
- The script is run whenever a system variable (e.g. current or voltage at a particular output) changes. In most situations, the script is run once per second.
- If the immediate current at a socket exceeds, without interruption, the specified limit for the specified time, the script automatically switches the socket off. It can also send an e-mail.
- The script can also monitor the sum of currents through all outputs: simply set the number of the monitored output to 0.
- In order to set the parameters, 6 variables are needed (socket number, current limit, time limit, e-mail address, e-mail subject, e-mail body).
- The script contains a function that reads the current and compares it with the limit; if exceeded, it switches the socket off and sends an e-mail. This function is called currentMeasurement. The checkTime function checks if the specified time period has been exceeded. The shutDown function reacts to the overcurrent.
Variables
- The variables for configuration parameters are called output, currentLimit, timeLimit, recipient, subject, text
- The variables are declared using the local keyword (e.g. local output = 1)
- Their meanings are as follows:
-
output
- Specifies the socket to monitor.
- To monitor all sockets at once, specify 0.
- For example, to monitor socket No. 3: output = 3
-
currentLimit
- Specifies the current limit (in milliamps).
- The maximum value is 8A = 8000mA (currentLimit = 8000).
- The value must be an integer (NETIO Lua does not support decimal numbers).
- For example, to set a current limit of 200mA: currentLimit = 200
-
timeLimit
- Specifies the time (in seconds) for which the current through the output must exceed the limit for the socket to be switched off.
- To switch the socket off as soon as the current exceeds the limit, specify 0.
- For example, to switch off after 5 seconds of overcurrent: timeLimit = 5
-
recipient
- E-mail address of the alert message recipient.
- It is a text string, so it has to be enclosed in double quotes.
- For example, to send the e-mail to john.smith@gmail.com: recipient = "john.smith@gmail.com"
-
subject
- Specifies the subject of the alert e-mail message.
- It is again a text string so it has to be enclosed in double quotes.
- Example: subject = "Output takes too much power"
-
text
- Specifies the body of the alert e-mail message.
- It is again a text string so it has to be enclosed in double quotes.
- Example: text = "Output " .. string.format(output) .. " on your NETIO exceeded limit " .. string.format(currentLimit) .. "mA!"
- The script also includes a variable to keep the value of the current. It is named current and is initially set to zero (local current = 0).
checkTime function
function checkTime() local timeNow = os.time() if (_G.timestamp == 0 or _G.timestamp == nil) then _G.timestamp = timeNow end if (timeNow - _G.timestamp >= timeLimit) then return true end return false end
- The function contains 2 variables: the local variable timeNow that keeps the current time, and the global variable _G.timestamp that keeps the time when the limit was first exceeded. If the current limit has never been exceeded, it has the value of nil. When the current returns below the limit, the currentMeasurement function resets the value of this variable to 0.
- A global variable is not declared using the local keyword and it can be accessed from all scripts. It is therefore very important not to use a global variable with the same name in other scripts. Most likely, both scripts would malfunction in such a case. In Lua, it is customary to prefix global variables with _G. for clarity.
- First, the current time is read using the os.time() library function and stored into the timeNow variable.
- Then, it is checked whether the current limit has been exceeded anew (if (_G.timestamp == 0 or _G.timestamp == nil) then)*. If so, the current time is stored into the _G.timestamp variable (_G.timestamp = timeNow).
- Finally the function checks whether the duration of the overcurrent condition has reached the specified time (if (timeNow - _G.timestamp >= timeLimit) then). If so, the function returns the value of true (return true). Otherwise, it returns the value of false (return false).
currentMeasurement function
function currentMeasurement() if output == 0 then for i=1,4,1 do current = current + devices.system["output" .. i .. "_current"] end else current = devices.system["output" .. output .. "_current"] end if current > currentLimit then if checkTime() then shutDown() mail(recipient, subject, text) end else _G.timestamp = 0 end end
- First, according to the output variable, the function stores the current flowing through one of the outputs (or the sum of currents through all the outputs) to the current variable. This value is then compared to the currentLimit variable.
- The devices.system.outputN_current function, where N is the number of the output to measure, is used to read the value of the current.
- The syntax to pass the parameters (output in this case) is as follows: devices.system["output" .. output .. "_current"]
- Then, the function checks whether it should measure the total over all sockets (if output = 0 then), or just one socket (else).
function currentMeasurement() if output == 0 then ---- if section ---- else ---- else section ---- end end
-
In case of all sockets (if section), the currents through all the sockets are added together.
- This is done with a for loop that adds the currents through the individual sockets to the current variable one by one.
- The loop declaration contains the initialization (variable name and the initial value), the condition (the value where the loop stops) and the increment** (the increase at each iteration).
- This is the initialization: i=1, the condition: 4, the increment: 1
- Then follows the do keyword, and the loop is terminated with the end keyword.
- Inside the for loop, the currents flowing through the individual sockets are added to the current variable one by one: current = current + devices.system["output" .. i .. "_current"]
- The entire loop looks like this:
for i=1,4,1 do current = current + devices.system["output" .. i .. "_current"] end
- If only one socket is monitored (else section), the current is read directly: current = devices.system["output" .. output .. "_current"]
-
The current is compared to the specified limit.
- This is done with a simple condition: if current > currentLimit
- If the condition is true, that is the current is higher than the limit, the checkTime function checks whether the time limit has been exceeded (if checkTime() then). If so, the shutDown() function is called to switch off the socket (or sockets) and send the e-mail alert.
- The mail function is used to send the e-mail. Its parameters are: recipient, subject, body. In this case, the variables recipient, subject and text are passed as the parameters.
- The statement is: mail(recipient, subject, text)
- The limit for sending e-mails is one per 5 minutes. This limit can be changed by passing a 4th parameter to the mail function. This parameter is a number in seconds. To be able to send a mail every 30 seconds, the command would look like: mail(recipient, subject, text,30)
- If the current limit is not exceeded, the _G.timestamp global variable needs to be reset to zero (_G.timestamp = 0).
shutDown function
function shutDown() if output == 0 then for i=1,4,1 do devices.system.SetOut{output=i, value=false} end else devices.system.SetOut{output=output, value=false} end end
- The function switches off the output (or all the outputs).
-
To switch off all outputs, the same condition (output = 0) as in the currentMeasurement function is used.
-
The condition and the loop are the same as in the currentMeasurement function, except that the adding of currents is replaced by the switching off of the given socket. This command is used:
devices.system.SetOut{output=i, value=false}
-
The condition and the loop are the same as in the currentMeasurement function, except that the adding of currents is replaced by the switching off of the given socket. This command is used:
- If only one socket is monitored, the following command is used: devices.system.SetOut{output=output, value=false}
Starting the script in NETIo smart power socket
- The script is started by calling the currentMeasurement function. The script ends with the following command: currentMeasurement().
- After checking Enabled and saving changes, the script is activated.
*Every unitialized variable has the value of nil.
**The default increment is 1. So, in this case, it was not necessary to specify it.
Adding undercurrent monitoring
To monitor whether the current through a socket lies within a certain range, make the following changes.
1) In Section 1, add a new currentLowerLimit variable and set it to the minimum allowed value of the current. Example for 100mA: local currentLowerLimit = 100
2) Replace the currentMeasurement function with the following:
function currentMeasurement() if output == 0 then for i=1,4,1 do current = current + devices.system["output" .. i .. "_current"] end else current = devices.system["output" .. output .. "_current"] end if (current > currentLimit or current < currentLowerLimit) then if checkTime() then shutDown() mail(recipient, subject, text) end else _G.timestamp = 0 end end
- The script will now check for current above as well as below the limits. The time limit specified in the timeLimit variable applies to both situations – the output must be outside of the allowed range for longer than the specified time.
Setting up e-mail alerts when limit was exceeded
- In order to send e-mails from your NETIO device, it is necessary to configure the settings in the Settings – E-mail section of the web interface.
- For details, see NETIO AN07
Supported FW versions:
3.0.0 and higher (Firmware archive)
More about Lua:
https://wiki.netio-products.com
This Application Note is compatible with:
|
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. |