luascript - Lua Script Processing Record
Table of contents
- Introduction
- Scan Parameters
- Read Parameters
- Output Parameters
- Operator Display Parameters
- Alarm Parameters
- Monitor Parameters
- Run-time Parameters
- Record Support Routines
- Record Processing
Introduction
The lua script processing record or “luascript” record is derived from the Calcout record in EPICS base, but replaces the calc operation engine with the lua scripting language. The record has 10 string fields (AA…JJ) and 10 double fields (A…J) whose values are retrieved every time the record is processed and those values are pushed into lua as global variables with the same name as the field.
The luascript record has both a VAL and SVAL output field. If the return operator is used within a lua expression, the returned value is placed into one of these fields. Booleans or Numbers that are returned get their value put into the VAL field, while Strings will be put into the SVAL field.
When writing to a string PV (any of DBF_STRING, DBF_ENUM, DBF_MENU, DBF_DEVICE, DBF_INLINK, DBF_OUTLINK, DBF_FWDLINK) the record (actually, device support) writes its string value (SVAL). When writing to any other kind of PV, the record writes its numeric value (VAL).
To write successfully to a DBF_MENU or DBF_ENUM (for example, the VAL field of a bo
or mbbo
record) the record’s string value must be one of the possible strings for the PV, or it must an integer specifying the string number [0..N] for the PV. For example, when writing to a bo
record whose ZNAM is “No” and whose ONAM is “Yes”, the string value must be one of the following: “No”, “Yes”, “0”, or “1”. To ensure that numeric values are converted to integers, set the precision (the PREC field) to zero.
Scan Parameters
The luascript record has the standard fields for specifying under what circumstances the record will be processed. These fields are listed in Scan Fields. In addition, Scanning Specification explains how these fields are used. Since the luascript record supports no direct interfaces to hardware, it cannot be scanned on I/O interrupt, so its SCAN field cannot be I/O Intr
.
Read Parameters
The read parameters for the luascript record consist of 20 input links: 10 to numeric fields (INPA -> A, INPB -> B, . . . INPJ -> J); and 10 to non-numeric fields (INAA -> AA, INBB -> BB, …INJJ -> JJ). The fields can be database links, channel access links, or constants. If they are links, they must specify another record’s field. If they are constants, they will be initialized with the value they are configured with and can be changed via dbPuts
. Non-numeric input links check the field type of the link provided and fetch data as either strings or as an array of values.
In addition, the luascript record contains the fields INAV, INBV, . . . INJV, which indicate the status of the links to numeric fields, and the fields IAAV, IBBV, . . . IJJV, which indicate the status of the links to string fields. These fields indicate whether or not the specified PV was found and a link to it established. See Section 5, Operator Display Parameters for an explanation of these fields.
See the EPICS Record Reference Manual for information on how to specify database links.
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor |
---|---|---|---|---|---|---|---|
INPA | Input Link A | INLINK | Yes | 0 | Yes | Yes | N/A |
INPB | Input Link B | INLINK | Yes | 0 | Yes | Yes | N/A |
… | … | … | … | … | … | … | … |
INPL | Input Link J | INLINK | Yes | 0 | Yes | Yes | N/A |
INAA | Input Link AA | INLINK | Yes | 0 | Yes | Yes | N/A |
INBB | Input Link BB | INLINK | Yes | 0 | Yes | Yes | N/A |
… | … | … | … | … | … | … | … |
INJJ | Input Link JJ | INLINK | Yes | 0 | Yes | Yes | N/A |
Expressions
The luascript record has a CODE field into which you can enter an expression for the record to evaluate when it processes. The return operator can be used to return either a numeric or string variable for writing to the VAL or SVAL field respectively. Either VAL and SVAL can also be written to the output link. (If you elect to write an output value, the record will choose between VAL and SVAL, depending on the data type of the field at the other end of the output link.)
The CODE expression can also be used to reference a file containing the description of at least a single lua function. If the CODE field starts with the symbol ‘@’ followed by the name of said file, the luascript record will search through a list of directories given by the environment variable ‘LUA_SCRIPT_PATH’ (default: current directory) for the given file. A space character and then the name of a function defined in the file lets the luascript record know what function to call when the record processes. Optionally, a set of parameters can be provided that the function will be called with each processing by including a comma separated list enclosed by parentheses.
When changing the CODE field, the luascript record’s RELO field controls whether or not the record will recompile the string into a new lua state, resetting any variables in the global scope. The field is a menu with three choices:
Every New File
– Recompile only if the file referenced is changed, the record can be changed to point to a new function within that file without losing any prior state.Every New Change
– Recompile on any change to the CODE field.Every Processing
– Recompile before each time the record is processed.
There is also the FRLD field which forces the record to recompile a new lua state when a non-zero value is written to it.
Finally, the ERR field contains a string representation of the last error encountered during processing.
The record also has a second set of calculation-related fields described in `Section 4, Output Parameters
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
CODE | Script | STRING [120] | Yes | ”” | Yes | Yes | Yes | No |
VAL | Value | DOUBLE | No | 0 | Yes | Yes | Yes | No |
SVAL | String value | STRING [40] | No | ”” | Yes | Yes | Yes | No |
RELO | When to reload state? | Menu | Yes | 0 | Yes | Yes | No | No |
FRLD | Force Reload | Short | Yes | 0 | Yes | Yes | No | No |
ERR | Last Error | String [200] | No | ”” | Yes | Yes | No | No |
Examples
field(CODE, "return A + B")
- Sets VAL to the result of A + B
field(CODE, "return AA .. BB")
- Sets SVAL to the concatenation of AA and BB
field(CODE, "@test.lua example")
- Runs the function ‘example’ from the file test.lua with zero parameters.
field(CODE, "@test.lua example(1, 'foo')")
- Runs the function ‘example’ from the file test.lua with two parameters, one a number, the other a string.
Output Parameters
These parameters specify and control the output capabilities of the luascript record. They determine when to write the output, where to write it, and what the output will be. The OUT link specifies the Process Variable to which the result will be written. The OOPT field determines the condition that causes the output link to be written to. It’s a menu field that has six choices:
Every Time
– write output every time record is processed.On Change
– write output every time VAL/SVAL/AVAL changes, i.e., every time the result of the expression changes to a value different than the one immediately previous.When Zero
– when record is processed, write output if VAL is zero, if SVAL is an empty string, or if AVAL is a 0-sized array.When Non-zero
– when record is processed, write output if VAL is non-zero, SVAL is a non-empty string, or if AVAL has any elements.Transition to Zero
– when record is processed, write output only if VAL is zero and last value was non-zero. If SVAL was changed, write output only if SVAL is an empty string and the last value was a non-empty string. If AVAL was changed, write output only if AVAL has zero elements and the last array had at least one element.Transition to Non-zero
– when record is processed, write output only if VAL is non-zero and last value was zero. If SVAL was changed, write output only if SVAL is a non-empty string and the last value was a empty string. If AVAL was changed, write output only if AVAL has at least one element and the last value had no elements.Never
– Don’t write output ever.
The SYNC field controls whether the record processes in a synchronous or asynchronous manner. It is a menu field with two choices:
Sync
– process the record’s lua code synchronously.Async
– process the record’s lua code in a separate thread.
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
OUT | Output Specification | OUTLINK | Yes | 0 | Yes | Yes | N/A | No |
OOPT | Output Execute Option | Menu | Yes | 0 | Yes | Yes | No | No |
SYNC | Synchronicity | Menu | Yes | 0 | Yes | Yes | No | No |
The luascript record uses device support to write to the OUT
link. Soft device supplied with the record is selected with the .dbd specification
field(DTYP,"Soft Channel")
Operator Display Parameters
These parameters are used to present meaningful data to the operator. Some are also meant to represent the status of the record at run-time. An example of an interactive MEDM display screen that displays the status of the luascript record is located here.
The HOPR and LOPR fields only refer to the limits of the VAL, HIHI, HIGH, LOW, and LOLO fields. PREC controls the precision of the VAL field.
The INAV-INJV and IAAV-IJJV fields indicate the status of the link to the PVs specified in the INPA-INPJ and INAA-INJJ fields, respectively. The fields can have three possible values:
Ext PV NC | the PV wasn’t found on this IOC and a Channel Access link hasn’t been established. |
Ext PV OK | the PV wasn’t found on this IOC and a Channel Access link has been established. |
Local PV | the PV was found on this IOC. |
Constant | the corresponding link field is a constant. |
The OUTV field indicates the status of the OUT link. It has the same possible values as the INAV-INJV fields.
See the EPICS Record Reference Manual, for more on the record name (NAME) and description (DESC) fields.
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
PREC | Display Precision | SHORT | Yes | 0 | Yes | Yes | No | No |
HOPR | High Operating Range | FLOAT | Yes | 0 | Yes | Yes | No | No |
LOPR | Low Operating Range | FLOAT | Yes | 0 | Yes | Yes | No | No |
INAV | Link Status of INPA | Menu | No | 1 | Yes | No | No | No |
INBV | Link Status of INPB | Menu | No | 1 | Yes | No | No | No |
… | … | … | … | … | … | … | … | … |
INJV | Link Status of INPJ | Menu | No | 1 | Yes | No | No | No |
OUTV | OUT PV Status | Menu | No | 0 | Yes | No | No | No |
NAME | Record Name | STRING [29] | Yes | ”” | Yes | No | No | No |
DESC | Description | STRING [29] | Yes | ”” | Yes | Yes | No | No |
IAAV | Link Status of INAA | Menu | No | 1 | Yes | No | No | No |
IBBV | Link Status of INBB | Menu | No | 1 | Yes | No | No | No |
… | … | … | … | … | … | … | … | … |
IJJV | Link Status of INJJ | Menu | No | 1 | Yes | No | No | No |
Alarm Parameters
The possible alarm conditions for the luascript record are the SCAN, READ, Calculation, and limit alarms. The SCAN and READ alarms are called by the record support routines. The Calculation alarm is called by the record processing routine when the CALC expression is an invalid one, upon which an error message is generated.
The following alarm parameters which are configured by the user define the limit alarms for the VAL field and the severity corresponding to those conditions.
The HYST field defines an alarm deadband for each limit. See the EPICS Record Reference Manual for a complete explanation of alarms and these fields.
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
HIHI | Hihi Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
HIGH | High Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
LOW | Low Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
LOLO | Lolo Alarm Limit | FLOAT | Yes | 0 | Yes | Yes | No | Yes |
HHSV | Severity for a Hihi Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
HSV | Severity for a High Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
LSV | Severity for a Low Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
LLSV | Severity for a Lolo Alarm | Menu | Yes | 0 | Yes | Yes | No | Yes |
HYST | Alarm Deadband | DOUBLE | Yes | 0 | Yes | Yes | No | No |
Monitor Parameters
These parameters are used to determine when to send monitors for the value fields. The monitors are sent when the value field exceeds the last monitored field by the appropriate deadband, the ADEL for archiver monitors and the MDEL field for all other types of monitors. If these fields have a value of zero, every time the value changes, monitors are triggered; if they have a value of -1, every time the record is scanned, monitors are triggered.
Field | Summary | Type | DCT | Default | Read | Write | Rec Proc Monitor | PP |
---|---|---|---|---|---|---|---|---|
ADEL | Archive Deadband | DOUBLE | Yes | 0 | Yes | Yes | No | No |
MDEL | Monitor, i.e. value change | DOUBLE | Yes | 0 | Yes | Yes | No | No |
Run-time Parameters
These fields are not configurable using a configuration tool and none are modifiable at run-time. They are used to process the record.
Record Support Routines
init_record
For each constant input link, the corresponding value field is initialized with the constant value if the input link is CONSTANT or a channel access link is created if the input link is PV_LINK.
The CODE field is processed and either compiled into bytecode directly, or the record will search for a given file and compile that file into bytecode.
process
See section 11.
special
This is called if CODE is changed.
get_precision
Retrieves PREC.
Record Processing
process()
The process()
routine implements the following algorithm:
-
Recompile the CODE field if the RELO field is set to “Every Processing”.
-
Push the values of all input links to global lua variables.
-
Run the compiled code in a separate thread. Process the returned value from the code to determine if it is a numeric value or a string value. Update VAL or SVAL accordingly.
-
Determine if the Output Execution Option (OOPT) is met. If it is met, execute the output link (and output event).
-
Check to see if monitors should be invoked.
Monitors for A-J and AA-JJ are set whenever values are changed.
-
Set PACT FALSE.