Working with the Demo Data Example
The Demo Data Example illustrates different use cases of Lua scripting, such as Lua libraries, event based script execution, object references and model actions.
Automatic Example Setup
You can then have the Demo Data example automatically set up in system:inmation, by running the following Lua script in the Console Display. All objects which are relevant for this example will be created in the 'Examples > Demo Data' subtree underneath your Core object.
local exm = require('esi-examples')
-- Populate I/O Model and create random historical data in one step:
exm:SETUP({{"demodata", "iomodel", "history"}})
-- Populate KPI Model:
exm:SETUP({{"demodata", "kpimodel"}})
Demo Data Using a Script Library
The general purpose of this example is to provide objects that create data similar to a real process. The Demo Data contains ten GenericItems that are configured individually to match the physical entity they are representing.

There are two objects for simulation of density (D), flow (F), pressure (P), quality (Q), and temperature (T), with different Generation Periods and Limit Settings. Although the main objective of this example is not the Lua script that calculates the simulation data, it is a good show case of how libraries can be used in the Lua scripting engine.
Objects with Scripts Using a Script Library
The Lua Script Body of the simulation objects are identical.
local libHelpers = require("SampleHelpers")
return libHelpers.GetNextRandomValue(syslib.getselfpath(), nil)
Firstly, the library SampleHelpers
is embedded into the script. Then it calls the GetNextRandomValue
function from
the embedded library whose returned value becomes the new current value of the object. The library is located in one of
the predecessor tree nodes, in this case it is hosted by the Examples folder.

Script libraries can be hosted by different objects, and are available to all
descendants in the tree hierarchy. As you can see in the first line of the script, the
embedding call require
uses the Script Library Id to refer to the library
that will be embedded.
Although it is recommended for consistency to keep _Script Library Id_s
unique, this is not mandatory. A script will search for the ID specified in
the require command upwards the tree, and use the first library that matches it.
|
Lua Library Syntax
A Lua library follows a certain syntax that describes the functions (and/or variables) that are provided by it.
SimpleMathLib = {
Add = function(a,b)
return a+b
end,
Subtract =function(a,b)
return a-b
end
}
return SimpleMathLib
The above example declares two functions called Add
and Subtract
, that each
take two parameters, and perform a simple math operation with those two. Note
how the Add
and Subtract
functions are separated with a comma from each other, and how
the script returns the library.
Event Based Script Calculation
The Demo Data Example also provides some objects that run scripts based on events triggered by the value change of other objects. Using the Lua scripting engine, data from sources in remote locations can be read and processed regardless of the system they are running. Processed data can then be written to any selected object (for instance to an operational control center system) in another remote location. In the DataDemo example, an object reads data from two different data sources, using them as inputs to perform a calculation. Data is then written to a target object with the value written depending on the outcome of the calculation.

Looking at the script of the object 'Average Quality Check', we can see that:
-
It is of the type ActionItem, meaning it is executed on an event based trigger, not periodically.
-
It uses one passive object references (DI_Out), that is used to simplify the script code (highlighted by the yellow boxes).
-
It uses two triggering object references, both causing the script to run whenever they change value, quality, timestamp or any property (highlighted by the orange boxes).
The script returns a string value (the avQ value plus a quality indication) and writes a binary value to the passively linked Q_LOW data holder object.
Note in the script how the script uses the object references' names in the code
when using the functions getvalue
and setvalue
of the system’s Lua extension.
For more details about how to create references, refer to the DataStudio documentation.
Create History
The Process Data GenItems in the Demo Data example generate random values using
the GetNextRandomValue function from the SampleHelpers
script library in the
Examples folder. We use this function again, alongside the syslib.sethistory
function to create a year’s worth of historical data for the Process Data items.
With this historical data you can start to use the HistoryGrid and HistoryTrend
displays in DataStudio. The CreateHistory ActionItem that runs the Lua script to
create the historical data can be found in the Logic Folder in the Demo Data Node.

Select the CreateHistory ActionItem and open the embedded Lua script.
The script sets the time to start the history. In this case it is a year prior
to the current time in milliseconds (variable old) and the variable step
sets the time interval between each written history data point to 1 min or 60000
ms. The for loop calls the get_children_paths function in the
SampleHelpers
library to cycle through each simulation item in the Process Data
folder. The History values are then set by stepping through each time point from
old to now with a time interval of 1 min between points. The first value
is calculated from the limit values of the Process Data item, then new
random values are calculated from the last set value by again using the
GetNextRandomValueFunction in the SampleHelpers
library. The script
then disables the CreateHistory item to prevent accidental re-execution of the
script. Open a HistoryTrend display for one of the items and select Entire Data
to see that the History was set for time period has been set.

Create KPI Model
The Demo Data example creates a set of simulation items in the I/O model including items that make calculations when new data is produced. So far, all the items described (including Lua scripts and script libraries) were created in the I/O model using the MassConfig display. For the KPI model the items are instead created using Lua scripting.
Objects can be created in any of the models using either MassConfig, Lua scripting or the external API to make SCI calls. You can also create objects manually using the Create wizard in DataStudio. |
Select the CreateKPIModel ActionItem in the I/O Model tree (it is in the same Logic folder as the CreateHistory item) and open the Lua script body by clicking on "…" in the object properties panel.

The first part of the script embeds the KpiHelpers
library in the
script using the require call. The KpiHelpers library is held as a script
library in the Examples folder like the SampleHelpers
library described
in an earlier section. The
paths to the folders in the I/O tree hierarchy are then set using the
syslib.getparentpath
and syslib.getobject
commands.
Because the script is being executed by the CreateKPIModel object then the paths
to these folders are all relative toits position in the tree.
The first objects are created in the KPI model, starting with the top-level Enterprise object (More information about KPI Model objects is available here). The call of the obj:children() method on the Process Data folder object returns all its children as Lua table. The KPI objects are created using the createGroup function in the KpiHelpers script library that takes object name, class and parent path as arguments. The function first checks if the object already exists before creating the object.
To create an Enterprise object in the KPI model, the root path for the KPI Model - "/" is used (see the 'grp'
variable definition using the syslib.getobject() call in the Create KPI Model script).
|
The second part of the CreateKPIModel script cycles through the returned table
of Process Data items and creates GenKPI items in the KPI Model accordingly. The
Process Data simulation items belong to either Reactor 4711 or Reactor 666 and we
create "Plant" objects in the KPI model to order the KPI items
in terms of location. Under each reactor the KPIs are arranged into either
"Measurements" or "LabData" dependent on the object name being a Density(D),
Pressure(P), Flow(F), Quality(Q) or Temperature(T) measurement (using the Lua
string.sub
function, the first letter of the object name object name is
identified). The "Measurements" and "LabData" folders are created followed by
the GenKPIs which are linked to the appropriate simulation item in the I/O Model.
Functions in the KpiHelpers script library are used to create the objects and set the properties.
After executing the script, the CreateKPIModel object disables itself to prevent accidental re-execution. View the KPI Model to see the created objects and KPI structure.
