AN16 Lua SNMP – Reading UPS battery charge state and switching electrical sockets off when the battery is low (Lua Active client) | NETIO products: Smart power sockets controlled over LAN and WiFi
Tags: 
User library

AN16 presents a script that runs in the NETIO smart sockets device, actively reads a value from an external device over SNMP and reacts to it. The smart sockets read the state of another device (at a different IP address) over the LAN using SNMP. In particular, AN16 shows how to detect the low battery state of a UPS in order to help a datacenter run longer on back-up power. When the battery is less than 50% charged, the smart socket device switches off a part of the cooling system. By querying different SNMP OIDs, it is possible to react to other UPS parameters (e.g. detect the absence of input voltage). The NETIO smart socket device and the UPS communicate directly, without an intermediate server or application.

 

Do you have any questions?

 

Supported devices: NETIO 4All, NETIO 4, PowerPDU 4C

 

NETIO AN16 is an example of an actively communicating Lua script that runs in the smart sockets device and can react to any SNMP value read from another device. Lua Active Client is a unique feature of NETIO 4x smart socket devices.

 

Lua Active Client can:

  • Read SNMP values from a generic SNMP device (IP address, OID)
  • Read values over Modbus/TCP from a generic device (IP, port, Modbus/TCP address)
  • Detect a response to PING (AN09, AN24, AN25)
  • Control the outputs of another NETIO device (URL API) – AN04

The AN16 Application Note shows two examples of Lua scripts. They differ in the processing of the obtained value. In your application, choose one of them.

  1. SNMP - number Lua script – reads a numeric value
    The script reads the variable at the specified OID address over SNMP as a string. The obtained value is converted from a string to a number, which is then compared to the limitValue specified at the beginning of the script. Only integer values are supported – no decimals. The controlled output is set depending on whether the obtained value is less than or greater than the limitValue.
     
  2. SNMP - string Lua script – compares strings
    The script reads the variable at the specified OID address over SNMP as a string. Within this string, the script tries to find the substring defined in the Lua script header in the requestedString variable. The specified output is switched on or off depending on whether or not the substring is found in the response.

 

 

Lua script that reads value (SNMP - number)

The first variant of the Lua script looks for a continuous string in the SNMP response, converts it to a number and compares this number with the limitValue variable. Depending on the result, the designated power output is switched on or off.

 

Creating the rule

To create and run the Lua script, do the following:

1) In the Actions section of NETIO 4x web administration, click Create Rule to add a rule

 

2) Fill in the following parameters:

  • Enabled: checked
  • Name: SNMP - number (user-defined)
  • Description: Read number over SNMP and set output (user-defined)
  • Trigger: System started up
  • Schedule: Always

3) Copy the following code and paste it into the field for the Lua script:

------------NETIO AN16 SNMP Value reading------------

------------Section 1------------
local IP = "192.168.101.132" -- device IP
local oid = ".1.3.6.1.2.1.33.1.3.3.1.3.1" -- oid
local snmpVersion = "2c" -- 1 or 2c
local positionInString = 16
local limitValue = 50
local output = 1
local stateHigh = 1
local stateLow = 0
local period = 1
---------End of Section 1---------

local version = ""
if snmpVersion == "1" then
  version = SNMP_VERSION.Snmp1
elseif snmpVersion == "2c" then
  version = SNMP_VERSION.Snmp2c
else
  logf("Invalid SNMP version: %s, valid options: 1, 2c",snmpVersion)
  return
end

function snmpcallbackPower(data)
  if data.result == 0 then
    --FAQ01 (log results)
    --logf("Result: %d, oid: %s, value: %s", data.result, data.oid, data.value)
    local value = data.value:sub(positionInString)
    logf("not converted: %s",value)
    local numValue = convertNumber(value)
    logf("converted: %s",tostring(numValue))
    
    if numValue ~= nil then
      if numValue >= limitValue then
        devices.system.SetOut{output=output,value=stateHigh}
        log("Value is higher then limit")
      else
        devices.system.SetOut{output=output,value=stateLow}
        log("Value is lower then limit")
      end
    else
      log("Wrong value format")
    end
  else
      log(string.format("snmpget failed with error %d: %s", data.result, data.errorInfo))
  end
end

function convertNumber(num)
  local ret = ""
  for i=1,string.len(num) do
    if tonumber(num:sub(i,i)) ~= nil then
      ret = ret .. num:sub(i,i)
    elseif string.len(ret) ~= 0 then
      break
    end
  end
  return tonumber(ret)
end

function sendSNMP()
  snmpGet{host=IP, timeout=6, oid=oid, snmpVersion=version, community='public', callback=snmpcallbackPower}
  delay(period,function() sendSNMP() end)
end

sendSNMP()

4) To finish creating the rule, click Create Rule at the bottom of the screen.

 

Method of operation

  • The Lua script periodically (the period can be set in the period variable) sends a SNMP get request to the specified IP address (IP variable) and OID (oid variable).
  • The response is received as a string, and the script looks for a numerical value at the specified position in that string.
  • The obtained value can be logged, see FAQ 01.
  • The positionInString variable specifies the place in the string where the actual value begins (useful e.g. if the numerical value is preceded by a unit, such as “$25.0” instead of “25 USD”). The first integer in the string from that position onwards is read.
  • The conversion stops at the first non-numeric character. This means that the script only works with integers, decimals are truncated.
  • The obtained number is compared to the specified limit (limit variable) and the corresponding action (stateHigh and stateLow variables) is performed with the specified output (output variable).
  • When no response is received (e.g. the target device is switched off), the output state is unchanged and the NETIO smart sockets will keep trying to get a response from the target device

 

Setting the variables

  • IP
    • IP address of the SNMP device from which the values are read
    • It is a string, so it has to be enclosed in double quotes
    • For example, to specify 192.168.2.50 as the IP address: local IP = "192.168.2.50"
  • oid
    • SNMP oid is the identifier of the variable to read in the SNMP tree. It can be considered as an “address” of the variable.
    • It is a string, so it has to be enclosed in double quotes
    • For example, to specify the oid of .1.3.6.1.2.1.33.1.3.3.1.3.1 :
    • local oid = ".1.3.6.1.2.1.33.1.3.3.1.3.1"
       
  • snmpVersion
    • Defines the SNMP protocol version to use. Versions 1 and 2c can be used.
    • For example, to use version 2c: local snmpVersion = "2c"
  • snmpCommunityString
    • This variable sets the community string for SNMP. For most devices, the default value is public.
    • For example, to set the community string to public: local snmpCommunityString= "public"
  • positionInString
    • This is the position from which the value will be read.
    • All characters, including spaces, need to be counted.
    • For example, to read the temperature from the string:  "Temperature is 26°C", the position will be: local positionInString = "16"
  • limitValue
    • This variable specifies the limit threshold. If the obtained value is greater than or equal to the limit, the output is set to stateHigh; if it is less than the limit, the output is set to stateLow.
    • The value must be an integer.
    • For example, to set the limit to 50: local limitValue = 50
  • output
    • Specifies the output to control according to the data retrieved over SNMP.
    • Allowed values are 1,2,3,4.
    • For example, to control output no. 2: local otuput = 2
  • stateHigh
    • Specifies the desired output state if the obtained value is equal to or greater than the limit.
    • Allowed values: 0 - switch the output off, 1 - switch the output on
    • For example, to switch the output on: local stateHigh = 1
  • stateLow
    • Specifies the desired output state if the obtained value is less than the limit.
    • Allowed values: 0 - switch the output off, 1 - switch the output on
    • For example, to switch the output off: local stateLow = 0
  • period
    • Specifies the period for reading the value (in seconds)
    • The value must be an integer.
    • For example, to read the value every 30 seconds: local period = 30

 

Starting the Lua script

After configuring all the parameters and saving the script, the NETIO smart sockets device needs to be restarted. After the system reboots, the script is started and the signaling output starts indicating the status of the monitored IP address. If the script doesn’t start, please check the settings.

 

Lua script that reads the value (SNMP - string)

The second variant of the Lua script checks if the response to the SNMP request contains the string specified in the requestedString variable. Depending on the result, the designated power output is switched on or off.

 

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:

  • Enabled: checked
  • Name: SNMP - string (user-defined)
  • Description: Read string over SNMP and set output (user-defined)
  • Trigger: System started up
  • Schedule: Always

3) Copy the following code and paste it into the field for the Lua script:

 
------------NETIO AN16 SNMP String reading------------

------------Section 1------------
local IP = "192.168.101.132" -- device IP
local oid = ".1.3.6.1.2.1.33.1.3.3.1.3.1" -- oid
local smnpVersion = "2c" -- 1 or 2c
local requestedString = "aa"
local output = 1
local stringOK = 1
local stringNoOK = 0
local period = 1
---------End of Section 1---------

local version = ""
if smnpVersion == "1" then
  version = SNMP_VERSION.Snmp1
elseif smnpVersion == "2c" then
  version = SNMP_VERSION.Snmp2c
else
  logf("Invalid SNMP version: %s, valid options: 1, 2c",smnpVersion)
  return
end

function snmpcallbackPower(data)
  if data.result == 0 then
    --FAQ01 (log results)
    --logf("Result: %d, oid: %s, value: %s", data.result, data.oid, data.value)    
    if string.match(data.value,requestedString) then
      devices.system.SetOut{output=output,value=stringOK}
      log("Value contains string")
    else
      devices.system.SetOut{output=output,value=stringNoOK}
      log("Value does not contain string")
    end
  else
      log(string.format("snmpget failed with error %d: %s", data.result, data.errorInfo))
  end
end

function convertNumber(num)
  local ret = ""
  for i=1,string.len(num) do
    if tonumber(num:sub(i,i)) ~= nil then
      ret = ret .. num:sub(i,i)
    elseif ret.len ~= 0 then
      break
    end
  end
  return tonumber(ret)
end

function sendSNMP()
  snmpGet{host=IP, timeout=6, oid=oid, snmpVersion=version, community='public', callback=snmpcallbackPower}
  delay(period,function() sendSNMP() end)
end

sendSNMP()


4) To finish creating the rule, click Create Rule at the bottom of the screen

 

Method of operation

  • The script periodically (the period can be set in the period variable) sends a SNMP get request to the specified IP address (IP variable) and OID (oid variable).
  • The response is received as a character string.
  • The obtained value can be logged, see FAQ 01
  • Skript následně zjistí, jestli se v přijatém řetězec nachází zadaný řetězec (proměnná requestedString).

 

  • Depending on whether or not the requestedString was found, the corresponding action is performed (stringOK and stringNoOK variables) with the specified output (output variable).

 

Setting the variables

  • IP
    • Device IP address
    • It is a string, so it has to be enclosed in double quotes
    • For example, to specify 192.168.2.50 as the IP address: local IP = "192.168.2.50"
  • oid
    • OID (identifier) of the value to read
    • It is a string, so it has to be enclosed in double quotes
    • For example, to specify the oid of .1.3.6.1.2.1.33.1.3.3.1.3.1 :
      local oid = ".1.3.6.1.2.1.33.1.3.3.1.3.1"
  • snmpVersion
    • Specifies the SNMP protocol version to use. Versions 1 and 2c can be used.
    • For example, to use version 2c: local snmpVersion = "2c"
  • snmpCommunityString
    • This variable sets the community string for SNMP. For most devices, the default value is public.
    • For example, to set the community string to public: local snmpCommunityString= "public"
  • requestedString
    • Specifies the string to look for in the obtained response.
    • If the response contains this string, the output is set to the stringOK state. Otherwise, it is set to the stringNoOK state.
    • It is a string, so it has to be enclosed in double quotes.
    • For example, to look for the string off: local requestedString = "off"
    • In this case, if the received message reads "State: off", the output is set to the stringOK state.
  • output
    • Specifies the output to control according to the data retrieved over SNMP.
    • Allowed values are  1,2,3,4.
    • For example, to control output no. 2: local otuput = 2
  • stringOK
    • Specifies the output state if the obtained response contains the requested substring.
    • Allowed values: 0 - switch the output off, 1 - switch the output on
    • For example, to switch the output on: local stateOK = 1
  • stringNoOK
    • Specifies the output state if the obtained response does not contain the requested substring.
    • Allowed values: 0 - switch the output off, 1 - switch the output on
    • For example, to switch the output off:  local stateNoOK = 0
  • period
    • Specifies the period for reading the value (in seconds)
    • The value must be an integer.
    • For example, to read the value every 30 seconds: local period = 30

 

Starting the script

After configuring all the parameters and saving the script, the NETIO smart sockets device needs to be restarted. After the system reboots, the script is started and the signaling output starts indicating the status of the monitored IP address. If the script doesn’t start, please check the settings.

 

 

FAQ:

1) Is it possible to check the response to the SNMP request in any way?

Yes. Delete the comment mark at the beginning of the line marked as FAQ1 to log each received response.
 

2) Is it possible to signal, e.g. with another output, the device beeper or an e-mail, that the target SNMP device is unreachable?

At this time, a sound signal function is not available. It is planned for a future firmware version.
 

3) Is it possible to use SNMP v3?

No, Lua scripts support SNMP v1 and v2 only.

 

 

Supported FW versions:

3.1.0 and higher (Archiv firmware)

 

Ask for a price or technical parameters

For device testing use name/password demo/demo