esi-objects

A library for simple and efficient upserting of the system objects of any type. Additionally, the library supplies functions to simplify access to custom properties and basic functions to check for objects and pathes in the models of the system. The library can be used in script objects running in all service components and functions on all model and object types.

Changes

version date description

1.72.0

2020-12-08

TFS code synchronisation

0.1.5

2020-10-03

Fix links in the Available Functions section

1.62.5

2020-09-21

Fix GETCUSTOM error handling

1.62.4

2020-02-06

Fix getobject replacement

1.1.4

2018-05-29

added a unit test covering most functions

0.1.3

2018-04-26

PATHOBJECTS function added, tested and documented

0.1.2

2018-04-26

Small rework to be fully ESI compliant

0.1.1

2018-04-17

Initial release

Known Issues

  • Documentation (this markdown file) is not completed

  • Some functions not covered in the unit test

Documentation

EXISTS

EXISTS(args)

Checks existence of an object.

Parameters

args (table, required)

A lua table containing one of the following field combinations:

Field Data Type meaning

path

string

The path at which object existence is to be checked.

Field Data Type meaning

parentpath

string

The path at which the object is supposed to be upserted.

objectname

string

The object name at the path specified whose existence is to be checked.

Field Data Type meaning

object

table

An object reference (lua table) whose validity is to be checked.

Usage

The function returns a boolean indicating existence of the object. If it is true, the object reference is returned as a second argument.

local exists, object = O:EXISTS{ path = o:path() } --path including objectname
local exists, object = O:EXISTS{ parentpath = o:parent():path(), objectname=o.ObjectName }
local exists, object = O:EXISTS{ object = o }

GETCUSTOM

GETCUSTOM(args)

Reads one or multiple custom properties of an object. Note: In case of duplicated properties, only the first match will be returned

Parameters

args (table, required)

The following example demonstrates all possible useage combinations of this function:

Possibility 1: Read only one key. The args table has the following structure:

Field Data Type meaning

object

table

An object reference (lua table)

key

string

The custom key whose value is to be read

Example:

--val is nil if custom key 'asd' does not exist or has no value
local val = O:GETCUSTOM{ object = o, key = "asd"}

The first return argument is a value, if it was read successfully, otherwise nil. The second return argument is the key if it could not be read successfully, otherwise nil.

Possibility 2: Read multiple keys. In this case, custom keys which could not be found are returned as a second return argument

Field Data Type meaning

object

table

An object reference (lua table)

key

table

An ordered lua table (array) holding the keys to be read

Example:

--assume the value for key 'asd1' is 'v1' and for keys 'asd2' is 'v2'
local vals, nilkeys = O:GETCUSTOM { object = o, key = {"asd1", "asd2"} }
if vals[1]~="v1" or vals[2]~="v2"  then --check nilkeys
    error("invalid values: " .. tostring(vals[1]) .. " " .. tostring(vals[2]) .. " " .. tostring(table.concat(nilkeys)))
end

The first return argument is a ordered lua table/array holding the values which were read successfully in the ordered given in the 'key' argument in the args table. The second return argument is nil if all keys could be read successfully, otherwise it is an ordered lua table containing the keys which could not be found.

Usage

Was demonstrated before.


SETCUSTOM

SETCUSTOM(args)

Sets one or multiple custom properties of an object. Note: In case of duplicated properties, only the first matched property will be set

Parameters

args (table, required)

The following example demonstrates all possible useage combinations of this function based in the input argument table:

Possibility 1: Set only one key. The args table has the following structure:

Field Data Type meaning

object

table

An object reference (lua table)

key

string

The custom key whose value is to be read

value

string

The value which is to be assigned for this key

Example:

-- key and value always have to be strings!
O:SETCUSTOM{object = obj, key = "asd", value = "asd"}

Possibility 2: Set multiple keys at once. In this case the args table has the following structure:

Field Data Type meaning

object

table

An object reference (lua table)

key

table

The custom keys whose value is to be read as an ordered lua table.

value

table

The values which are to be assigned for this key as an ordered lua table.

Example:

O:SETCUSTOM{object = obj, key = {"asd1", "asd2"}, value = {"v1, v2"}}

Usage

Was demonstrated before.


INFO

INFO()

This is a mandatory function for any ESI library. See ESI Coding Standards for more information.


PATHOBJECTS

PATHOBJECTS(path_or_object, json)

Splits the given path according to the system standard (also reflecting on escape sequences in case the ObjectName property contains forward slashes, such as "Not/So/Good/ObjectName"), and returns a table with object information for each hierarchy level in the model tree.

The PATHOBJECTS function can be helpful in case certain model hierarchies of certain expected node types are required for a particular use case. This is often the case when populating the Equipment Model or the KPI Model, because such models may vary in their node types and programmatic extensions of the model may want to reflect on the parent types.

Parameters

path_or_object (string or object, required)

The parameter specifies either an object path as a string or the object at the very leaf node of the hierarchy (In the second case, given the object is valid, it is guaranteed that all "higher-up" objects do exist).

json (boolean, optional)

If provided and set to true, the returned table will be encoded in a JSON document (string).

PATHOBJECTS returns table or JSON document (string) \{#PATHOBJECTS returns table or JSON document }
Field Data Type Description

EXIST

boolean

true, if the object was found in the model, false otherwise. If false, some of the other fields are not set.

PATH

string

The fully qualified path of the object at model hierarchy location, whether EXIST is true or not

NAME

string

The ObjectName property, if EXIST is true

TYPE

string

The string representation of the object type, if EXIST is true

TYPECODE

number

The numerical representation of the object type, if EXIST is true

The table holds one entry for each object in the given path.

PATHOBJECTS throws

a hard error if it detects to be in an endless loop. The likeliness of this ever to happen is close to zero, and would point to a corruption in the model tree itself.

Usage

local O=require('esi-objects')
return O:PATHOBJECTS(syslib.getself(),true)

image

If we would rename the "Run Test" ActionItem into "Not/So/Good/ObjectName", the result of the call looks like

image

Given we ask for a partially non-existing object hierarchy like in this code snippet:

local O=require('esi-objects')
local t=O:PATHOBJECTS(syslib.getself())
if 2<=#t then
    s=t[2].PATH.."/Fantasy1/NotThere2/Test3"
    return O:PATHOBJECTS(s,true)
end

the result would look like

image


GETCUSTOM

GETCUSTOM(args)

Reads one or multiple custom properties of an object

Parameters

args (table, required)

The following example demonstrates all possible useage combinations of this function:

Possibility 1: Read only one key. The args table has the following structure:

Field Data Type meaning

object

table

An inmation object reference (lua table)

key

string

The custom key whose value is to be read

Example:

--val is nil if custom key 'asd' does not exist or has no value
local val = O:GETCUSTOM{ object = o, key = "asd"}

Possibility 2: Read multiple keys. In this case, custom keys which could not be found are returned as a second return argument

Field Data Type meaning

object

table

An inmation object reference (lua table)

key

table

An ordered lua table (array) holding the keys to be read

Example:

--assume the value for key 'asd1' is 'v1' and for keys 'asd2' is 'v2'
local vals, nilkeys = O:GETCUSTOM { object = o, key = {"asd1", "asd2"} }
if vals[1]~="v1" or vals[2]~="v2"  then --check nilkeys
    error("invalid values: " .. tostring(vals[1]) .. " " .. tostring(vals[2]) .. " " .. tostring(table.concat(nilkeys)))
end

The first return argument is a ordered lua table/array holding the keys which were read successfully in the ordered given in the 'key' argument in the args table. The second return argument is nil if all keys could be read successfully, otherwise it is an ordered lua table containing the keys which could not be found.

Usage

Was demonstrated before.


SORTCUSTOM

SORTCUSTOM(args)

Sorts all custom properties in an object alphabetically.


UPSERTOBJECT

UPSERTOBJECT(args)

Upserts an object with minimal required count of commits.

Parameters

args (table, required)

A lua table containing the following fields:

Field Data Type meaning

path

string

The path at which the object is supposed to be upserted.

properties

table

The inmation properties which are to be set/upserted. The table keys are the property names, the table values are the required property values.

class

string

The inmation MODEL_CLASS_…​ of the object to be upserted (https://inmation.com/wiki/index.php?title=ClassModel/en)

Usage

The following code snippets demonstrate the useage of the function, including custom properties. The general syntax is compatible with what you get when rightclicking an object in inmation and clicking 'admin → generate lua → upsert object' in inmation, with the exception of the 'class', 'operation' and 'path' fields:

syslib.mass({
    {
        class = syslib.model.classes.Chart, --not supported
        operation = syslib.model.codes.MassOp.UPSERT, --not supported
        path = "/Example/Test Functions/testtrendchart", --not supported
        ObjectName = "testtrendchart",
        ObjectDescription = "testdesc",
        ["CustomOptions.CustomProperties.CustomPropertyValue"] = {
            "customvalue1",
            "customvalue",
        },
        ["CustomOptions.CustomProperties.CustomPropertyName"] = {
            "customkey1",
            "customkey",
        },
        ["TrendChart.KPIYAxisLabel"] = "°C",
        ["TrendChart.KPIPenSettings.KPIPenTrendType"] = {
            1,
            1,
        },
        ["TrendChart.KPIPenSettings.KPIPenMaxYAxis"] = {
            0,
            100,
        },
        ["TrendChart.KPIPenSettings.KPIPenMinYAxis"] = {
            0,
            100,
        },
        ["TrendChart.KPIPenSettings.KPIPenName"] = {
            "test1",
            "test2",
        },
        ["TrendChart.KPIPenSettings.KPIPenColor"] = {
            8,
            8,
        },
        ["TrendChart.KPIPenSettings.KPIPenOffset"] = {
            " ",
            " ",
        },
        ["TrendChart.KPIPenSettings.AggregateSelection"] = {
            40,
            40,
        },
        ["TrendChart.KPIPenSettings.KPIPen"] = {
            "/System/Core/Core Logic/Tests/New ESI Objects/holder1",
            "/System/Core/Core Logic/Tests/New ESI Objects/thisnamewaschanged1527183733456",
        },
        ["TrendChart.VisualKPIObject"] = "Trend"
    }
})

Upserting a folder:

local properties =
{
  ObjectName = "testfolder", --both syntaxes are allowed for
  [".ObjectDescription"] = "testdesc", -- properties which do not contain dots
  Custom =
  {
    ["customkey"] = "customvalue",
    ["customkey1"] = "customvalue1"
  }
}

local o, changed = O:UPSERTOBJECT(
  {path=syslib.getself():parent():path(),
    class = "MODEL_CLASS_GENFOLDER",
    properties = properties})

Chart creation examples:

--test a pareto chart creation
local prop =
{
  [".ObjectName"] = "testparetochart",
  [".ObjectDescription"] = "testdesc",
  [".ChartType"] = syslib.model.codes.SelectorChartType.CHART_PARETO, -- paretochart
  [".ParetoChart.KPIYAxisLabel"] = "Signal Contribution [%]",
  [".ParetoChart.KPIXAxisLabel"] = "xlabel",
  [".ParetoChart.KPIBarSettings.KPIBar"] = {h1:path(), h2:path()},
  [".ParetoChart.KPIBarSettings.AggregateSelection"] = {40, 40},
  [".ParetoChart.KPIBarSettings.KPIBarName"] = {"test1", "test2"},
  [".ParetoChart.KPIBarSettings.KPIBarColor"] = {syslib.model.codes.KPIColors.RED, syslib.model.codes.KPIColors.RED},
  [".ParetoChart.KPIBarSettings.KPIBarOffset"] = {" ", " "},
  Custom =
  {
    ["customkey"] = "customvalue",
    ["customkey1"] = "customvalue1"
  }
}

local o, changed = O:UPSERTOBJECT
{
    path = "/Example/Test Functions",
    class = "MODEL_CLASS_CHART",
    properties=prop
}


--test a xy chart creation
local properties =
{
  [".ObjectName"] = "testxychart",
  [".ObjectDescription"] = "testdesc",
  [".ChartType"] =  syslib.model.codes.SelectorChartType.CHART_XYPLOT,
  [".XYPlotChart.KPIStartTime"] = "*-3d",
  [".XYPlotChart.KPIEndTime"] = "*",
  [".XYPlotChart.KPIXAxisLabel"] = "X",
  [".XYPlotChart.KPIYAxisLabel"] = "Y",
  [".XYPlotChart.KPIPlotYAxis"] = syslib.model.codes.TrendYAxis.AUTOSCALE,
  [".XYPlotChart.KPIMinYAxis"] = 0,
  [".XYPlotChart.KPIMaxYAxis"] = 10,
  [".XYPlotChart.KPIXYPlotPenSettings.PenX"] = {h1:path()},
  [".XYPlotChart.KPIXYPlotPenSettings.AggregateSelectionX"] = {syslib.model.codes.Aggregates.AGG_TYPE_BESTFIT},
  [".XYPlotChart.KPIXYPlotPenSettings.PenY"] = {h2:path()},
  [".XYPlotChart.KPIXYPlotPenSettings.AggregateSelectionY"] = {syslib.model.codes.Aggregates.AGG_TYPE_BESTFIT},
  [".XYPlotChart.KPIXYPlotPenSettings.KPIPenColor"] = {syslib.model.codes.KPIColors.RED},
  [".XYPlotChart.KPIXYPlotPenSettings.KPIPenName"] = {"testpen"},
  [".XYPlotChart.KPIXYPlotPenSettings.PenIsTimeSeries"] = {true},
  [".XYPlotChart.KPIXYPlotPenSettings.PenPlotContents"] =  {syslib.model.codes.KPIPlotContent.YDATA},
  [".XYPlotChart.KPIXYPlotPenSettings.PenYDataLineType"] =  {syslib.model.codes.KPIDataLineType.SYMBOL},
  Custom =
  {
    ["customkey"] = "customvalue",
    ["customkey1"] = "customvalue1"
  }
}
local o, changed = O:UPSERTOBJECT{
    path = "/Example/Test Functions",
    class = "MODEL_CLASS_CHART",
    properties = prop
}

--test trend chart creation
local properties =
{
  [".ObjectName"] = "testtrendchart",
  [".ObjectDescription"] = "testdesc",
  [".ChartType"] =  syslib.model.codes.SelectorChartType.CHART_TREND,
  [".TrendChart.KPITrendScale"] = syslib.model.codes.KPITrendScale.SINGLESCALE,
  [".TrendChart.TrendYAxis"] = syslib.model.codes.TrendYAxis.AUTOSCALE, --PENMINANDMAXYAXIS
  [".TrendChart.KPIYAxisLabel"] = "°C",
  [".TrendChart.KPIPenSettings.KPIPen"] = {h1:path(), h2:path()},
  [".TrendChart.KPIPenSettings.AggregateSelection"] = {syslib.model.codes.Aggregates.AGG_TYPE_BESTFIT, syslib.model.codes.Aggregates.AGG_TYPE_BESTFIT},
  [".TrendChart.KPIPenSettings.KPIPenOffset"] = {" ", " "},
  [".TrendChart.KPIPenSettings.KPIPenColor"] = {syslib.model.codes.KPIColors.RED, syslib.model.codes.KPIColors.RED},
  [".TrendChart.KPIPenSettings.KPIPenName"] = {"test1", "test2"},
  [".TrendChart.KPIPenSettings.KPIPenMinYAxis"] = {0, 100},
  [".TrendChart.KPIPenSettings.KPIPenMaxYAxis"] = {0, 100},
  [".TrendChart.KPIPenSettings.KPIPenTrendType"] = {syslib.model.codes.KPIPenTrendType.INTERPOLATED,    syslib.model.codes.KPIPenTrendType.INTERPOLATED},
  Custom =
  {
    ["customkey"] = "customvalue",
    ["customkey1"] = "customvalue1"
  }
}
local o, changed = O:UPSERTOBJECT
{
  path = "/Example/Test Functions",
  class = "MODEL_CLASS_CHART",
  properties = prop
}

Breaking changes

  • Not Applicable