User Tools

Site Tools


Introduction to Lua programming

WebHMI allows you to create custom programs (scripts) in Lua 5.1 language. The scripts are managed in the Setup → Scripts menu item.

If you have no experience with Lua language read this tutorial at first Lua in 15 minutes.

Each WebHMI script should contain a function named main. It will be called at the right time (depending on the settings of the script - in each cycle, when you act on the dashboard or when changing the value of the register, etc). Also, the entire script will be executed once when the daemon is started. This is necessary to compile the Lua script and validate it. This means that all the code from the global scope (that is, outside the main function, the main function will not be called) will be executed. This can be useful for initializing some variables, etc.

Each script has its own global scope. It is impossible to access global variables and functions from one script in another.

The main function will receive one special parameter userId. This is ID of the user that executed this script. If the script is being executed in each loop or when the register is changed, userId will be zero. If script is being executed from any dashboard then userId will contain user's id.

Here is an example of a simple script for WebHMI:

--[[
 these vars will be assigned only once
 global var will keep their values between scans
 BUT NOT between project restarts!!! -- for saving data between project restarts use D or DSxxx registers  or key-value storage
--]]
first_scan = true -- first scan flag 
GLOBAL_CONSTANT_1 = 100 -- UPPER case preferrable for constants
 
local now1 = 0 -- global because outside scope of main 
 
function main (userId)
 
  now2 = 0 -- also global because no "local" before 
 
  if first_scan then 
      first_scan = false 
      -- some actions only made once upon project restart
  end 
 
  now1 = os.time () -- get time from Lua function 
  now2 = GetReg ( "systemTime" ) -- get time form register with "systemTime" alias 
 
  if (now1 == now2) then 
      DEBUG ( "both time are equal" )
  else 
      ERROR ( "something wrong with time ... " )
  end 
end -- main 

WebHMI imposes the following restrictions on standard Lua functions and libraries:

  • such functions and tables are not available: require, print, loadfile, dofile, os.execute, os.getenv, os.remove, os.rename, os.tmpname, package, debug.debug, debug.getfenv, debug.getregistry, arg
  • libraries are not available: io

In addition to the standard Lua functions, WebHMI also defines additional functions which are described in this manual.

For the convenience of working with registers from Lua programs, each register can be assigned a symbolic name and be accessed from Lua with this name. This name is specified in the register settings in the Script alias field:

In the example above, alias “systemTime” was used in GetReg function to read system time from internal WebHMI register with id = 1.

An example of a simple script that shows the calls of some WebHMI functions:

function main (userId)
    local randomVal = GetReg("random_val");
    SetReg("random_val_copy", randomVal);
    WriteReg("result", randomVal + 2);
 
    AddInfoMessage("This is a Lua script", userId);
    AddWarningMessage("Warning. This is a Lua script", userId);
    AddAlertMessage("Alert! This is a Lua script", userId);
 
    SendSMS("380501234567", "This is a test SMS");
 
    ERROR("This message will be added to communication log with ERROR level");
    INFO("This message will be added to communication log with INFO level");
    DEBUG("This message will be added to communication log with DEBUG level");
    TRACE("This message will be added to communication log with TRACE level");
end

Despite the fact that the built-in editor checks the syntax of the program, it is not able to detect all the errors that can occur during the execution of the script. If any error occurs during script execution, it will be displayed in communication log (Maintenance→WebHMI Log).

For example, once this script will be executed, an error will occur because variable random was not declared.

function main (userId)
 
  local v1 = GetReg("Drying_Humidity1_Value");
  v1 = v1 + random; -- error is here, without random everything is ok
 
  SetReg("Drying_Humidity1_Value", v1);
  WriteReg("Drying_Humidity1_Value", v1); 
 
  AddInfoMessage(v1, userId);
end

There will be such records in WebHMI Log:

Jan 23 12:09:27.047: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')
Jan 23 12:09:27.551: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')
Jan 23 12:09:28.051: ERROR: LUA scripts: Can't execute LUA script #1. Error #2: [string "Calculate humidity"]:4: attempt to perform arithmetic on a nil value (global 'random')

Here we see that the error occurred while trying to perform an arithmetic operation with an undefined variable (value is nil). The error occurred in script with id=1, its name was 'Calculate humidity', the error occurred in line number 4 at 12:09:27.047. The variable that caused the error is called 'random'.

Thus, using this log you can find all runtime errors in your scripts. Also for debugging you can use watch console window, which is available in scripts editor.


Page Tools