User Tools

Site Tools

This is an old revision of the document!

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
  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" )
      ERROR ( "something wrong with time ... " )
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 decsribed in their respective sections below.

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

In the example above, this name “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");

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. In the event that any errors occur during its execution, they will be displayed in communication log (Maintenance→WebHMI Log).

For example, once this script will be executed, an error will occur because variable random is 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);

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 number 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 script editor.

Page Tools