Module | Name | Version | License | Source | Languages | Platforms | Type | Author | Description |
---|---|---|---|---|---|---|---|---|---|
JavaLikeCalc | Calculator on the Java-like language | 5.6 | GPL2 | daq_JavaLikeCalc.so | en,uk,ru,de | x86,x86_64,ARM | DAQ | Roman Savochenko Maxim Lysenko (2009-2010) — the page initial translation |
Provides a calculator and libraries engine on the Java-like language. The user can create and modify functions and their libraries. |
The data source module provides OpenSCADA for a mechanism of creating functions and their libraries on Java-like language. The writing of the function in the Java-like language is reduced to the binding of the parameters of the function by an algorithm.
Direct computations are provided by the creation of controller object and linking it with the function of this module. For linked function it is created the frame of values (context), with which the periodically calculating is carried out.
The module implements the functions of the horizontal redundancy, that is working in conjunction with the remote station of the same level. In addition to the synchronization of the archives of values and archives of attributes of parameters, the module implements synchronization of computational function, in order to shockless holding of the algorithms.
Parameters of functions can be freely created, deleted or modified. The current version of the module supports up to 65535 parameters of the function, in the sum with the internal variables. The view of editing functions in the OpenSCADA configurator is shown in Figure 1. The parameter name's rows after the first one treat as help.
After any change in the program text or parameter configuration, the program is recompiled by notifying the values objects TValCfg associated with the function. The language compiler is built using the well-known grammar generator "Bison", which is compatible with the no less well-known "Yacc" utility.
The language uses the implicit definition of local variables, which is to define a new variable in the case of assigning a value to it. This type of local variable is set according to the type of the assigning value. For example, the expression Qr=Q0*Pi+0.01; will define Qr variable with the type of variable Q0.
In working with various types of data the language uses the mechanism of casting the types in the places where such casting is appropriate.
To comment the sections of code in the language it is provided "//" and "/* ... */" characters. Everything that comes after "//" up to the end of the line and between "/* ... */", is ignored by the compiler.
During the code generation, the language compiler produces an optimization of constants and casting the types of the constants to the required type. The optimization of the constants means the calculation of two constants and the insertion of the result into the code in the process of constructing a byte-code. For example, the expression y=pi*10; reduces to a simple assignment y=31.4159;. Casting the types of constants to the required type means formation of the constant in the code which excludes the cast in the execution process. For example, the expression y=x*"10";, in the case of the real type of the variable x, is transformed into y=x*10;.
Assignment expressions can be recorded through symbol ',', for example:
var1 = 1, var2 = 3, var4 = var1+var2;
for(var1 = 0, var2 = 0, var3 = -1; var1 < 10; var1++, var2++) var3++;
The language supports calls of the external and internal functions. Name of any function in general is perceived as a character, which is tested to belong a particular category in the following order:
- does not begin with a point:
- keywords (if, else, while, ...);
- variables-attributes of that function;
- named-builtin constants (EVAL, pi, e, ...) and objects-constants (SYS, arguments)
- builtin functions (sin, cos, ...);
- internal, external functions, object functions and nodes of the object model OpenSCADA;
- previously registered automatic variables;
- global attributes of DAQ parameters and properties of variables;
- keywords (in, var);
- creating a new automatic variable, whose name does not have to intersect with the categories above, start with a digit and contain operations symbols.
- begins with a point:
- element of the path to the property and function of the object, whose name should not begin with a digit and contain operations symbols.
Calling an external function, like the global attribute of the DAQ parameter, is written as an address to the node of the object model OpenSCADA: "DAQ.JavaLikeCalc.lib_techApp.klapNotLin". For static functions you are allowed to the dynamic linking also in the following way:
function klapNotLin = "DAQ.JavaLikeCalc.lib_techApp.klapNotLin";
rez = klapNotLin(prm1, prm2, ..., prmN);
To provide the writing of custom control procedures for various components of OpenSCADA, this module provides the implementation of the precompiling API of custom procedures for individual components of OpenSCADA in the Java-like language. These components for example are: templates of the parameters of the subsystem "Data acquisition" and the visual control area (VCA).
Contents
1 The Java-like language
1.1 Elements of the language
Keywords: if, else, while, for, in, break, continue, return, function, using.
Constants:
- decimal: digits 0-9 (12, 111, 678);
- octal: digits 0-7 (012, 011, 076);
- hexadecimal: digits 0-9, letters a-f or A-F (0x12, 0XAB);
- real: 345.23, 2.1e5, 3.4E-5, 3e6;
- boolean: true, false;
- string: "hello", without going to the next line, however, with the support of direct concatenation of the string constants.
Types of variables:
- integer: -263 ... 263, EVAL_INT(-9223372036854775807);
- real: 3.4*10308, EVAL_REAL(-1.79E308);
- Boolean: false, true, EVAL_BOOL(2);
- string: a sequence of character-bytes (0...255) of any length, limited by the capacity of the memory and DB storage; EVAL_STR("<EVAL>").
Built-in constants: pi = 3.14159265..., e = 2.71828182..., EVAL_BOOL(2), EVAL_INT(-9223372036854775807), null,EVAL,EVAL_REAL(-1.79E308), EVAL_STR("<EVAL>")
Global attributes of the DAQ parameter (starting from the subsystem "DAQ", as follows {Type of DAQ module}.{Controller}.{Parameter}.{Attribute}).
The functions and parameters of the object model of OpenSCADA.
The EVAL (Error VALue) variants and null are processed specially in conversion one to one depending on used the base type, that is you are free in use only null or EVAL for any cases.
1.2 Operations of the language
The operations supported by the language are presented in the table below. Priority of the operations is reduced from top to bottom. Operations with the same priority are in the same color group.
Symbol | Description |
() | Call of function. |
{} | Program blocks. |
++ | Increment (post and pre). |
-- | Decrement (post and pre). |
- | Unary minus. |
! | Logical negation. |
~ | Bitwise negation. |
* | Multiplication. |
/ | Division. |
% | Remainder of integer division. |
+ | Addition |
- | Subtraction |
<< | Bitwise shift left |
>> | Bitwise shift right |
> | Greater |
>= | Greater than or equal to |
< | Less |
<= | Less than or equal to |
== | Equals |
!= | Unequal |
| | Bitwise "OR" |
& | Bitwise "AND" |
^ | Bitwise "Exclusive OR" |
&& | Boolean "AND" |
|| | Boolean "OR" |
?: | Conditional operation "i=(i<0)?0:i;" |
= | Assignment. |
+= | Assignment with addition. |
-= | Assignment with subtraction. |
*= | Assignment with multiplication. |
/= | Assignment with division. |
1.3 Embedded functions of the language
The virtual machine of the language provides the following set of built-in functions general-purpose:
- double max(double x, double x1) — maximum value of x and x1;
- double min(double x, double x1) — minimum value of x and x1;
- string typeof(ElTp vl) — type of the value vl;
- string tr(string base) — translation to the base message.
To provide high speed work in mathematical calculations, the module provides built-in mathematical functions that are called at the level of the commands of the virtual machine:
- double sin(double x) — sine x;
- double cos(double x) — cosine x;
- double tan(double x) — tangent x;
- double sinh(double x) — hyperbolic sine of x;
- double cosh(double x) — hyperbolic cosine of x;
- double tanh(double x) — hyperbolic tangent of x;
- double asin(double x) — arcsine of x;
- double acos(double x) — arc cosine of x;
- double atan(double x) — arctangent of x;
- double rand(double x) — random number from 0 to x;
- double lg(double x) — decimal logarithm of x;
- double ln(double x) — natural logarithm of x;
- double exp(double x) — exponent of x;
- double pow(double x, double x1) — erection of x to the power x1;
- double sqrt(double x) — the square root of x;
- double abs(double x) — absolute value of x;
- double sign(double x) — sign of x;
- double ceil(double x) — rounding the number x to a greater integer;
- double floor(double x) — rounding the number x to a smaller integer.
1.4 Operators of the language
The total list of the operators of the language:
- var — operator of initialization of a variable; specifying a variable without assigning a value sets it to null-EVAL, which allows for one-time initialization of complex data types, such as an object, through the direct comparing and checking by isEVal();
- if — operator "IF" of the condition;
- else — operator "ELSE" of the condition;
- while — definition of the "WHILE" loop;
- for — definition of the "FOR" loop;
- in — separator of the "FOR" cycle for object's properties scan;
- break — interruption of the cycle;
- continue — continue the cycle from the beginning;
- function — definition of the internal function;
- using — allows you to set the visibility space of the external functions of the often used libraries (using Special.FLibSYS;) for the next access only by the name of the function, has no effect for object access;
- return — interrupt function and return the result that is copied to an attribute marked as return one (return 123;); in the middle of the internal function it is completed with a definite result;
- new — creating an object, implemented for: the generic object "Object", massif "Array" and regular expressions "RegExp".
- delete — delete/free of an object or its properties, while: internal variables are set in null-EVAL, external ones are replaced by an empty object, and the properties of the object are cleared.
1.4.1 Conditional operators
The language supports two types of conditions. First — this is the operation of condition for use within the expression, second — a global, based on the conditional operators.
The condition inside an expression is based on the operations '?' and ':'. As an example we'll write the following practical expression:
st_open = (pos >= 100) ? true : false;
Which reads as — if the variable pos greater than or equal to 100, the variable st_open is set to true, otherwise — to false.
The global condition is based on the conditional operators "if" and "else". As an example, we can show the same expression, but recorded in another way:
if(pos > 100) st_open = true; else st_open = false;
1.4.2 Loops
Two types of the loops are supported: while, for and for-in. The syntax of the loops corresponds to the programming languages: C++, Java and JavaScript.
Loop while is written generally as follows: while({condition}) {body of the loop};
Loop for is written as follows: for({pre-initialization};{condition};{post-calculation}) {body of the loop};
Loop for-in is written as follows: for({variable} in {object}) {body of the loop};
Where:
- {condition} — expression, determining the condition;
- {body of the loop} — the body of the loop of multiple execution;
- {pre-initialization} — expression of pre-initialization of variables of the loop;
- {post-calculation} — expression of modification of parameters of the loop after next iteration;
- {variable} — variable, which will contain object's properties name at scan;
- {object} — object for which the properties are scanned.
1.4.3 Internal functions
The language supports definition and call of internal functions. To determine the internal function, the keyword "function" is used and in general, the definition has a syntax: function {fName} ({var1}, {var2}, ... {varN}) { {the function body} }. Defining an internal function inside another is not allowed but it is allowed to call a previously defined one.
Calling an internal function is done in a typical way as a procedure {fName}({var1}, {var2}, ... {varN}); or as a function {vRez} = {fName}({var1}, {var2}, ... {varN});. The call of internal functions is valid only after their declaration is higher!
All defined variables into the main body inaccessible into the internal function and can be pass in as two way arguments of the internal function call or as the main function arguments. All defined variables into the internal function have itself namespace and inaccessible from the main body or any other internal function and can be pass out to the main body as two way arguments, return of the internal function call or the main function arguments. The internal function variables are registered for saving/restoring their context after second and more entry to the function, so they completely support the recursive calls!
Operator "return" into the internal function makes controllable finishing of the function execution and places a pointed variable or an expression result as the internal function call result.
An example of the internal function declaration and using in typical way shown next:
function sum(a, b, c, d) { return a + ((b==null)?0:b) + ((c==null)?0:c) + ((d==null)?0:d); }
rez = sum(1, 2);
1.4.4 Special characters of the string variables
The language supports the following special characters of the string variables:
- "\n" — line feed;
- "\t" — tabulation symbol;
- "\b" — culling;
- "\f" — page feed;
- "\r" — carriage return;
- "\\" — the character itself '\'.
- "\041" — the '!' character, written in an octal number;
- "\x21" — the '!' character, written in a hex number.
1.5 Object
JavaLikeCalc provides support of the data type "Object". The data type "Object" is an associated container of properties and functions. The properties can support data of fourth basic types and other objects. Access to object properties can be done through the record of property names to the object obj.prop, through a dot, and also through the inclusion of the property name in square brackets obj["prop"]. It is obvious that the first mechanism is static, while the second lets you to specify the name of the property through a variable. The name of the property through the dot must not start with a digit and contain operations symbols; otherwise, for the first digit, the object prefix should be used — SYS.BD.SQLite.db_1s, or write in square brackets — SYS.BD.SQLite["1+s"], for operations symbols in the name. Object's properties removing you can perform by the operator "delete". Reading of an undefined property will return null-EVAL. Creating an object is carried by the keyword new: varO = new Object(). The basic definition of the object does not contain functions. Copying of an object is actually makes the reference to the original object. When you delete an object is carried out the reducing of the reference count, and when the count is set to zero then the object is removed physically.
Different components of OpenSCADA can define the basic object with special properties and functions. The standard extension of the object is an array "Array", which is created by the command varO = new Array(prm1,prm2,prm3,...,prmN). Comma-separated parameters are placed in the array in the original order. If the parameter is the only one the array is initiated by the specified number of empty elements. Peculiarity of the array is that it works with the properties as the indexes and the main mechanism of addressing is placing the index into square brackets arr[1] is accessible. Array stores the properties in its own container of the one-dimensional array. Digital properties of the array are used to access directly to the array, and the characters work as the object properties. For more details about the properties and functions of the array can be read here.
The object of regular expression "RegExp" is created by command varO = new RegExp(pat, flg), where pat — pattern of the regular expression, and flg — match flags. The object for work with regular expressions, based on the library "PCRE". In the global search set object attribute "lastIndex", which allows you to continue searching for the next function call. In the case of an unsuccessful search for the attribute "lastIndex" reset to zero. For more details about the properties and functions of the regular expression object can be read here.
For random access to the function arguments provided the arguments object, which you can refer to by the symbol "arguments". This object contains the property "length" with a number of arguments in the function and allows you to access to a value of the argument by its number or ID. Consider the enumeration of the arguments on the cycle:
args = new Array();
for(var i = 0; i < arguments.length; i++)
args[i] = arguments[i];
The basic types have the partial properties of the object. Properties and functions of the basic types are listed below:
- NULL type, functions:
- bool isEVal(); — returns "true".
- Logical type, functions:
- bool isEVal(); bool isNaN( ); — checks the value to null-EVAL.
- string toString(); — performs the value as the string "true" or "false".
- real toReal(); — reads this Boolean as a real number.
- int toInt(); — reads this Boolean as an integer number.
- Integer and real number:
- Properties:
- MAX_VALUE — maximum value;
- MIN_VALUE — minimum value;
- NaN — error value.
- Functions:
- bool isEVal(); bool isNaN( ); — checks the value to null-EVAL, and NaN for Real.
- string toExponential( int numbs = -1 ); — returns the string of the number, formatted in the exponential notation, and with the number of significant digits numbs. If numbs is missing the number of digits will have as much as needed.
- string toFixed( int numbs = 0, int len = 0, bool sign = false ); — returns the string of the number, formatted in the notation of fixed-point, and with the number of significant digits after the decimal point numbs, for minimum length len and compulsion to the presence of a sign. If numbs is missing, the number of digits after the decimal point is equal to zero.
- string toPrecision( int prec = -1 ); — returns the string of the number, formatted with the number of significant digits prec.
- string toString( int base = 10, int len = -1, bool sign = false ); — returns the string of the number of the integer type, formatted with the following representation base (2-36), for minimum length len and compulsion to the presence of a sign.
- real toReal(); — reads this integer-real as a real number.
- int toInt(); — reads this integer-real as an integer number.
- String:
- Properties:
- int length — string length.
- Functions:
- bool isEVal(); — checks value to null-EVAL.
- bool isNaN( bool whole = true ); — checks the string to Not A Number and in whole for whole.
- string charAt( int symb, string type = "" ); — extracts from the string the symbol symb for the type. These types of the symbol are supported: ""-ASCII and raw one byte code, UTF-8, UTF-16, UTF-32. In the case of UTF-8, the symbol position symb is changed to the next symbol position due to length of this symbols type is variable one.
- int charCodeAt( int symb, string type = "" ); — extracts from the string the symbol code symb for the type. These types of the symbol are supported: ""-ASCII and raw one byte code, UTF-8, UTF-16, UTF-16LE, UTF-16BE, UTF-32, UTF-32LE, UTF-32BE. In the case of UTF-8, the symbol position symb is changed to the next symbol position due to length of this symbols type is variable one.
- string concat( string val1, string val2, ... ); — returns a new string formed by joining the values val1 etc. to the original one.
- int indexOf( string substr, int start = 0 ); — returns the position of the required string substr in the original row from the position start. If the initial position is not specified then the search starts from the beginning. If the search string is not found then "-1" is returned.
- int lastIndexOf( string substr, int start = {end} ); — returns the position of the search string substr in the original one beginning from the position of start when searching from the end. If the initial position is not specified then the search begins from the end. If the search string is not found then "-1" is returned.
- int search( string pat, string flg = "" ); — searches into the string by the pattern pat and pattern's flags flg. Returns found substring position or "-1" for else.
var rez = "Java123Script".search("script","i"); // rez = 7
- int search( RegExp pat ); — searches into the string by the "RegExp" pattern pat. Returns found substring position or "-1" for else.
var rez = "Java123Script".search(new RegExp("script","i")); // rez = 7
- Array match( string pat, string flg = "" ); — calls match for the string by the pattern pat and flags flg. Returns matched substring (0) and subexpressions (>0) array. Sets "index" attribute of the array to the substring position. Sets the "input" attribute to the source string. Sets the "err" attribute to the operation error code.
var rez = "1 plus 2 plus 3".match("\\d+","g"); // rez = [1], [2], [3]
- Array match( TRegExp pat ); — calls match for the string and "RegExp" pattern pat. Returns matched substring (0) and subexpressions (>0) array. Sets the "index" attribute of the array to substring position. Sets the "input" attribute to the source string. Sets the "err" attribute to the operation error code.
var rez = "1 plus 2 plus 3".match(new RegExp("\\d+","g")); // rez = [1], [2], [3]
- string slice( int beg, int end ); string substring( int beg, int end ); — returns the string extracted from the original one starting from the beg position and ending before the end (not included), numbering from zero. If the begin or end is negative, then the count is conducted from the end of the line. If the end is not specified, then the end is the end of the line. For example, the construction substring(-2) return two last symbols of the string.
- Array split( string sep, int limit = 0 ); — returns the array of strings separated by sep with the limit of the number of elements (0 for no limit).
- Array split( RegExp pat, int limit = 0 ); — returns the array of strings separated by the RegExp pattern pat with the limit of the number of elements (0 for no limit).
rez = "1,2, 3 , 4 ,5".split(new RegExp("\\s*,\\s*")); // rez = [1], [2], [3], [4], [5]
- string insert( int pos, string substr ); — inserts the substring substr into this string's position pos.
- string replace( int pos, int n, string str ); — replaces substring into the position pos and length n to the string str.
rez = "Javascript".replace(4,3,"67"); // rez = "Java67ipt"
- string replace( string substr, string str ); — replaces all the substrings substr to the string str.
rez = "123 321".replace("3","55"); // rez = "1255 5521"
- string replace( RegExp pat, string str ); — replaces substrings by the pattern pat to the string str.
rez = "value = \"123\"".replace(new RegExp("\"([^\"]*)\"","g"),"``$1''")); // rez = "value = ``123''"
- real toReal(); — converts this string to a real number.
- int toInt( int base = 0 ); — converts this string to an integer number in accordance with base (from 2 to 36). If the base is 0, then the prefix will be considered a prefix for determining the base (123-decimal; 0123-octal; 0x123-hex).
- string {parse,parseEnd}( int pos, string sep = ".", int off = {0,{length}}, bool mergeSepSymb = false ); — gets a token with the number pos from the string when separated by sep and from the offset off (stopping on the next token begin, end for parseEnd). mergeSepSymb specifies of allowing of merging of the group of identical symbols to one separator. Result offset is returned back to off. parseEnd() does the same but from the end.
- string parseLine( int pos, int off = 0 ); — gets a line with the number pos from the string and from the offset off. Result offset is returned back to off (stopping on the next token begin).
- string parsePath( int pos, int offCmptbl = 0, int off = 0 ); — gets a path token with the number pos from the string and from the offset off (stopping on the next token begin) or offCmtbl (stopping on next symbol of the current token end — for compatibility). Result offset is returned back to off or offCmptbl.
- string parsePathEnd( int pos, int off = {length} ); — gets a path token with the number pos from the string end and from the offset off (stopping on the next token end). Result offset is returned back to off.
- string path2sep( string sep = "." ); — converts path into this string to separated by sep string.
- string trim( string cfg = " \n\t\r" ); — trims the string at the begin and the end for the symbols cfg.
For access to the system objects(nodes) of OpenSCADA the corresponding object is provided which is created simply by specifying the enter point "SYS" of the root object OpenSCADA, and then with the point separator the sub-objects in accordance with the hierarchy are specified. For example, the call of the request function over the output transport is carried out as follows: SYS.Transport.Sockets.out_testModBus.messIO(Special.FLibSYS.strEnc2Bin("15 01 00 00 00 06 01 03 00 00 00 05"));.
1.6 Examples of programs on this language
Here are some examples of programs on the Java-like language:
//Model of the course of the executive machinery of ball valve
if(!(st_close && !com) && !(st_open && com))
{
tmp_up = (pos>0&&pos<100) ? 0 : (tmp_up>0&&lst_com==com) ? tmp_up-1/frq : t_up;
pos += (tmp_up>0) ? 0 : (100*(com?1:-1))/(t_full*frq);
pos = (pos>100) ? 100 : (pos<0) ? 0 : pos;
st_open = (pos>=100) ? true : false;
st_close = (pos<=0) ? true : false;
lst_com = com;
}
//Valve model
Qr = Q0 + Q0*Kpr*(Pi-1) + 0.01;
Sr = (S_kl1*l_kl1+S_kl2*l_kl2)/100;
Ftmp = (Pi>2*Po) ? Pi*pow(Q0*0.75/Ti,0.5) : (Po>2*Pi) ? Po*pow(Q0*0.75/To,0.5) : pow(abs(Q0*(pow(Pi,2)-pow(Po,2))/Ti),0.5);
Fi -= (Fi-7260*Sr*sign(Pi-Po)*Ftmp)/(0.01*lo*frq);
Po += 0.27*(Fi-Fo)/(So*lo*Q0*frq);
Po = (Po<0) ? 0 : (Po>100) ? 100 : Po;
To += (abs(Fi)*(Ti*pow(Po/Pi,0.02)-To)+(Fwind+1)*(Twind-To)/Riz)/(Ct*So*lo*Qr*frq);
2 Controller object and its configuration
The controller object of the module, to provide immediate calculations, connects with the functions of libraries, built with his help, or with the data acquisition template. In the case of a data acquisition template, the possibility of external linking with other parameters and attributes of the subsystem "Data Collection" is added. In order to provide calculated data in OpenSCADA, parameters can be created in the controller object. Example of the configuration tab of the controller object of the given type shown in Figure 2.
From this tab you can set:
- State of the controller object, as follows: status, "Enabled", "Running" and the storage name containing the configuration.
- Identifier, name and description of the controller.
- The state "Enabled" and "Running", in which the controller object must be translated at start up.
- Address of the computational function or the data acquisition template.
- Policy of scheduling, priority of the data acquisition task and number of iterations in one cycle of calculation task.
Tab "Calculation" of the controller object (Fig. 3) contains parameters and a text of the program, are directly performed by the controller. Also, for monitoring of the execution, the time of calculating of the program is shown. The module provides processing a number of special options available in the controller program:
- f_frq — calculation frequency of the controller program, read-only.
- f_start — first calculation of the controller program — starting, read-only.
- f_stop — last calculation of the controller program — stopping, read-only.
- this — the controller object.
3 Parameter of the controller object and its configuration
The module provides only one the "Standard (std)" type of the parameters with the parameters table name "JavaLikePrm_{CntrId}".
Parameter of the controller object of the module performs the function of providing the access to the results of computation of the controller to OpenSCADA by attributes if the parameters. From the specific fields, the configuration tab of the parameter of the controller object contains only the field for listing the parameters of the computational function that must be reflected.
4 Libraries of functions of the module
The module provides a mechanism to create libraries of user's functions on the Java-like language. Example of the configuration tab of the library is shown in Figure 4. The tab contains the basic fields: accessing, address of the DB table (with tracking the availability of the data in different storages and providing the sequentially removing duplicates), date and time of modification, identifier, name and description.
- The object still supports of specifying the spare storage addresses with tables before you rename the table in the standard form "flb_{ObjID}".
5 User functions of the module
Function, as well as the library, contains the basic configuration tab, the tab of the formation of the program and the parameters of the function (Fig. 1), as well as the performance tab of the created function.
6 User programming API
Some objects of the module provides functions for user's programming.
The object "Functions library" (SYS.DAQ.JavaLikeCalc["lib_Lfunc"])
- ElTp {funcID}(ElTp prm1, ...) — calls the function "funcID" of the library "Lfunc" with the parameters prm{N}. Returns result of the called function. The prefix "lib_" before the library identifier is required!
The object "User function" ( SYS.DAQ.JavaLikeCalc["lib_Lfunc"]["func"] )
- ElTp call(ElTp prm1, ...) — calls the function "func" of the library "Lfunc" with the parameters prm{N}. Returns result of the called function. The prefix "lib_" before the library identifier is required!
7 Service commands-functions of the Control Interface
Service functions are an interface for accessing OpenSCADA from external systems through the Control Interface. This mechanism is the basis of all exchange within OpenSCADA, implemented through weak links and OpenSCADA's own exchange protocol.
Getting for values of the function IO of the controller object
REQ: <get path="/DAQ/JavaLikeCalc/{CNTR}/%2fserv%2ffncAttr" />
- CNTR — controller object.
RESP: <get path="/DAQ/JavaLikeCalc/{CNTR}/%2fserv%2ffncAttr" rez="0">{IOs}</get>
- IOs — IOs of the function execution context in the tags "a": <a id="{ID}">{value}</a>
- ID — identifier of the IO;
- value — value of the IO.
<get path="/DAQ/JavaLikeCalc/testCalc/%2fserv%2ffncAttr" rez="0" user="roman">
<a id="f_frq">0.1</a>
<a id="f_start">0</a>
<a id="f_stop">0</a>
<a id="this"><TCntrNodeObj path="/sub_DAQ/mod_JavaLikeCalc/cntr_testCalc/"/></a>
<a id="offset">100</a>
<a id="out">50</a>
<a id="test">1</a>
<a id="rez" />
<a id="inFarg">3</a>
</get>
Setting for values of the function IO of the controller object
REQ[root-DAQ]: <set path="/DAQ/JavaLikeCalc/{CNTR}/%2fserv%2ffncAttr">{IOs}</set>
- CNTR — controller object;
- IOs — IOs of the function execution context in the tags "a": <a id="{ID}">{value}</a>
- ID — identifier of the IO;
- value — value of the IO.
<set path="/DAQ/JavaLikeCalc/testCalc/%2fserv%2ffncAttr">
<a id="out">50</a>
<a id="test">1</a>
</set>
8 Productivity
Source text of the procedures on the language is compiled into a bytecode, which is then computed by the virtual machine. The bytecode is not native machine code and achieving to productivity of the hardware platform into the virtual machine that executing is theoretical unreal, sure if the virtual machine code is not executed directly by the CPU. That is, the productivity of the bytecode execution approximately low by ten to the hardware productivity due to the overhead of the virtual machine commands, the distribution of multithreaded data access, the transparent casting of types and the lack of strict typing, as well as the dynamic nature of the language and the presence of complex types "String" and "Object ".
28.01.2006:
Description: Initial estimation of the productivity of the OpenSCADA virtual machine in example of the expression y=x1+x2, where all the variables are global and in the float-point type.
Stage | Action | K7_1G-0, us |
---|---|---|
1 | The registers list initialization | 2.3 |
2 | Entry to the function exec() | 3 |
3 | The commands coming | 4.4 |
4 | Reading | 9 |
5 | Full time | 10.2 |
17.07.2013:
Description: Justification of the current performance evaluation and optimization. The measurements were made by sampling the minimum time from five calls to 1000 executions of the formula a -= b*(a-c) and its abbreviations in each call. All the variables are global and in the float-point type.
Formula | Time on AMDGeode-500 (the operation time), us | Notes |
---|---|---|
a -= b*(a-c) | 4.52 (0.74) | |
a -= b*c | 3.78 (0.72) | |
a -= b | 3.06 (0.56)
|
|
a = b | 2.5 (1.21)
|
Writing to the function IO is longer then reading from the local register for other context call and additional checking for NAN and real modification. |
Empty | 1.29 | the infrastructure and measurement method utilization time. |
24.04.2016:
Reason: Estimate performance of accessing to the low level IO lines on Raspberry Pi GPIO in different ways of the JavaLikeCalc language of OpenSCADA.
Conditions: Raspberry Pi 3, GPIO40, DAQ.GPIO (based on the library bcm2835)
Operation | Result, us |
---|---|
Sleep. Lag on sleep in 1ms measuring, which mostly limited by the realtime reaction about 100us. | |
SYS.sleep(); | +110 |
Special.FLibSYS.fnc_tmSleep(); | +70 |
Sleep. Lag on sleep in 100us measuring, which performs in the measuring cycle. | |
SYS.sleep(); | +17 |
Special.FLibSYS.fnc_tmSleep(); | +2 |
Get a level of the GPIO pin | |
From an attribute res = GPIO.io.pi.gpio17; | 5.4 |
By the static accessing function res = DAQ.GPIO.io.pi.fnc_get(17); | 1.6 |
By the static accessing function with the link preparation function get = "DAQ.GPIO.io.pi.fnc_get"; for(i = 0; i < 10000; i++) res = get(17); | 1.7 |
By the dynamic accessing function res = SYS.DAQ.GPIO.io.pi.fnc_get.call(17); | 80 |
By the dynamic accessing function with the end object preparation tO = SYS.DAQ.GPIO.io.pi.fnc_get; for(i = 0; i < 1000; i++) res = tO.call(17); | 14.3 |
Put a level to the GPIO pin | |
To an attribute GPIO.io.pi.gpio18 = true; | 2.1 |
By the static accessing function DAQ.GPIO.io.pi.fnc_put(18, true); | 1.4 |
By the static accessing function with the link preparation function put = "DAQ.GPIO.io.pi.fnc_put"; for(i = 0; i < 10000; i++) put(17, false); | 1.5 |
By the dynamic accessing function SYS.DAQ.GPIO.io.pi.fnc_put.call(18, true); | 79 |
By the dynamic accessing function with the end object preparation tO = SYS.DAQ.GPIO.io.pi.fnc_put; for(i = 0; i < 1000; i++) tO.call(18, true); | 14.3 |