Contents
- Introduction
- CS-Shell Server Distribution Bundle
- The Application Server Configuration File
- Server Modules
- Glossary of Terms
Introduction
This is core CS-Shell library, which is used in KARA and by extention in FLUTE. See under Project in menu to access both documentation.
The CS-Shell is EPICS business logic server, which provides easy way to implement server side logic in Java and offer it to various application through EPICS and CA interface and communication protocol. It has similar role as EPICS Database has for IOC, yet does not replaces it. The CS-Shell application server is not intended for writing device drivers, this is efficiently and sufficiently covered by EPICS IOC. The CS-Shell application server is designed for implementing of algorithms and complex procedures as server process using capacity of JAVA programming language and supporting Java libraries.
The Application Server and CSS
The CS-Shell application server works well together and supplements functionality of CSS. Perfect example is complete ANKA alarm server solution, which is build around CSS BEAST alarm.
The CS-Shell alarm server is implemented on top of CS-Shell EPICS application server with focus on supporting functionality of CSS BEAST alarm engine.
The Application Server at IBPT
Following are integral parts of the installation of the complete alarm solution at IBPT accelerators (KARA and FLUTE) :
- The CSS BEAST alarm server
- The CSS BEAST panels for viewing alarms
- The CSS BEAST alarm utility for managing configuration
- The CSS BEAST prescribed and configured PostgreSQL and JMS
- The CSS BEAST jms2rdb server
- The ANKA alarm server for intercepting and filtering alarms and as well generating own alarms. It is a special instance of the ANKA application server.
- EPICS IOCs with enabled alarm capabilities as source of device-based alarm events.
Most of the alarms are intercepted by the CS-Shell alarm server and if some criteria is met, like machine operation is in correct state, then they are sent further to the BEAST alarm engine in form of standard CA alarms. The alarm server also monitors some vital signals of the machine and generates appropriate alarm signals to BEAST. The BEAST is configured by configuration generated by ANKA alarm server.
The CS-Shell alarm server works with existing CA and CSS BEAST communication and and interface standards. There is no new interface and no patching done to CA or CSS BEAST. The alarm server listens to existing EPICS alarms through CA and provides further alarms to CSS BEAST as standard CA channels. JCA library with CAS is used for this purpose.
The CS-Shell Application and Alarm Server
This server is implemented on top of Java CA server (CAS).
CS-Shell application server has following functionality:
- Provides extensive set of reusable server components, that can be use to build CA server functionality.
- Provides XML based configuration, which supports efficiently configuring large number of server components and CS channels with support of capabilities such as XML injection, parameter substitution and templates.
- Provides facility and container to implement complex server side applications and reusable modules and configure them from XML.
- Allows sever implementation and running in embedded mode.
Alarm part of CS-Shell application server has following functionality:
- Listens to other EPICS PVs and alarms. It relays alarms further if conditions (for example operation state) this allows.
- It hosts alarms, which are not directly connected to devices readout. This is equivalent to Soft records.
- Checks various device statuses.
- Provides a watchdog functionality for monitoring important services and processes.
- Filters alarms so particular alarms are generated or forwarded only when machine is in appropriate state.
- Provides alarms and alarm configuration for BEAST alarm server transparently as typical EPICS CS alarms.
CS-Shell Server Distribution Bundle
The CS-Shell has flexible startup configuration, which is by default setup organized around a distribution bundle, which contains configuration files, executables and libraries and tools needed to start alarm and application servers.
The bundle can be found in IBPT SVN repository: https://scm.ibpt.kit.edu/scm/svn/kara/distro/ANKA-Servers/trunk and is distributes and updated trough SVN version control mechanism.
Following is directory and file structure of the distribution bundle:
bat
- folder contains MS Windows scripts for running serversconfig
- folder containing configuration files for application serversbundle.properties
- defines home and configuration folders for serverslog4j.properties
- log4j configuration fileAppServer
- contains common configurations for the ANKA application server. Applications running within the server might use additional configuration folders, which are located in config folder.server.xsd
- schema file for validating the application server configuration XML.var
- a folder where application server stores files needed at runtime or for saving persistency information
lib
- contains libraries, tools and executableslib/java
- Java JAR libraries fileslib/lin
- Linux executables, such as JRE/JDKlib/win
- MS Windows executables, such as JRE/JDKlib/resources
- General folder for resources, such as icons.
log
- contains log filessh
- contains Linux scripts for running servers
Startup Script
The application servers finds resources located within the distribution bundle trough runtime configuration in the startup scripts.
The alarm server for example is started by sh/AlarmServer.sh
script. The script makes three important declarations
export AS_NAME="AlarmServer"
- this tells what should be the name of log file. It must be declared before main initialization happens.. "$(dirname "$0")/_init.sh"
- call to the main bundle initialization script which sets up runtime environment variables, such as Java JRE and classpath.$AS_JAVA -classpath $AS_CLASSPATH -Dlog4j.debug=false -DAppServer.init=AppServer-alarms.properties org.scictrl.csshell.epics.server.Server
- this line starts the serverThe startup line contains following elements:
$AS_JAVA
- is java executable as defined in the_init.sh
script,$AS_CLASSPATH
- is classpath as defined in the_init.sh
script,-DAppServer.init=AppServer-alarms.properties
- is name of properties file, which defines initialization properties for the server.
The Application Server Initialization Configuration
Once the application server org.scictrl.csshell.epics.server.Server
is started it will try to load a bootstrap file bundle.properties
(by a way of system parameters or classloader), which is in our case located in config/bundle.properties
. This file tells server where home and config folders can be found.
The application server will get assigned own configuration folder, which is by default in folder config/AppServer/
.
The server receives instructions what to load and start with the AppServer.init
System property:
System Property | Description | Required | Default value |
---|---|---|---|
AppServer.init |
Application server initialization file, for example AppServer-alarms.properties . |
No | AppServer.properties |
Following properties could be provided either through this initialization file (in case of KARA alarm server config/AppServer/AppServer-alarms.properties
) or could be optionally defined as System properties. System properties take precedence.
The main set of properties (in AppServer.init
file):
Property | Description | Required | Default value | Example value for Alarm server |
---|---|---|---|---|
AppServer.input |
Application server input XML file with definitions of EPICS records to be started. Location is relative to the server configuration folder (provided by bundle: config/AppServer/ ). |
Yes | alarms.xml |
|
AppServer.configName |
The application server input file could have several configuration. This property tells name of the configuration to be loaded. | No | default | Alarms |
AppServer.alarmExport |
Optional, relevant only for Alarm server, where exporting BEAST alarms in required. The name of XML file into which BEAST configuration is exported. This is relative to the config/AppServer/ folder. If missing, nothing is exported. |
No | alarms_export.xml | |
AppServer.alarmConfigName |
Optional, relevant only for Alarm server, where exporting BEAST alarms in required. The name of BEAST alarm configuration, if exported. | No | ANKA Machine |
ANKA Machine |
AppServer.persistencyFile |
The name of "persistency" file, where last known values are stored for PV records, which are used, when server is restarted. By bundle convention should be placed in var folder inside the application configuration folder. |
No | persistency.xml |
var/persistency-alarms.xml |
The additional (optional) special purpose properties:
Property | Description | Required | Default value |
---|---|---|---|
AppServer.exportOnly |
If True than application server just exports BEAST xml file and quits, does not start the server. | No | False |
AppServer.passphrase |
A secret word, which is used to authorise remote shutdown trough management interface. | No | please |
The Application Server Configuration File
At application server initialization this file is declared in AppServer.input
property (in server initialization file or System property).
Is is an XML file where it is defined how application server will be managed and what PVs and EPICS records and applications will export. The declared EPICS records and applications can be configured from this file within own XML tag space.
This records definition file can be validated with XML Schema found here: config/AppServer/server.xsd
. This enables validation of the file and XML writing aides and tag-completion in advanced XML editor, like on used in CSS or Eclipse.
In case of our Alarm server this file is alarms.xml
. Below is example (simplified) snippet of the alarms.xml
with some simple alarm records.
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="server.xsd"> <server name="Alarms"> <management> <name>A:${host}:${server}</name> </management> <group name="SR PS Main" path="A:SR:PS:"> <record> <name>MB-01:DiffCheck</name> <type>DBR_BYTE</type> <alarmConf> <path>Storage Ring,PS Diff Check</path> <description>PS setpoint/readback mismatch</description> <latching>true</latching> </alarmConf> <processor instance="org.scictrl.csshell.epics.server.processor.SummaryAlarmProcessor"> <input><links>A:SR:PSStatus:MB-01:Status</links></input> <gate><link>A:SR:OperationStatus:01:Mode</link><mask>0b001111</mask></gate> </processor> </record> <!-- ... more records --> </group> <!-- ... more groups --> </server> <!-- ... more servers --> </config>
EPICS records are defined are defined in to main ways:
- with XML element called record, where declared each PV has own configuration tags in XML,
- or with XML element called application, where PVs are created by the application itself and have same PV prefix as declared for application (same namespace as application).
The record element defines single PV with value provided by own ValueProcessor instance.
The application element loads an Application instance, which can further load several additional records trough server's API.
Element: <config>
The element <config> is XML Document root element. It defines the schema file. It can contain one or more server elements.
Element: <server>
The <config>
element can contain one or more <server>
elements. Server has one required parameter: name
. When application server is started it loads server element, which name is provided as startup parameter.
The server element can contain management element and number of any of following elements: <group>
, <record>
or <application>
.
Element: <management>
The element <management>
is first sub-element of <server>
. It defines how server can be managed from remote trough set of PVs.
At minimum an empty <management>
tag must be present to enable management with default parameters. If there is no <management>
tag, then management functionality is not activated.
The <management>
element can contain following sub-elements:
XML Element | Description | Required | Default value |
---|---|---|---|
<name> |
This name is prefix of PVs, which offer management access to this server. If omitted, default value is used. Name can contain two macro substitutions: * ${host} - valid network host name of current machine, if this can not be resolved, then "localhost" is used * ${server} - server name, as defined in server element with name attribute. |
No | ${host}:${server} |
<shutdown> |
Shutdown string is suffix part of management PV, which provides shutdown functionality for server. Full shutdown PV for server by default is: ${host}:${server}:Shutdown . To actually shutdown use passphrase as argument in CA set call. |
No | :Shutdown |
<ping> |
Ping string is suffix part of management PV, which provides ping functionality for the server. Full shutdown PV for server by default is: ${host}:${server}:Ping . |
No | :Ping |
<list> |
List string is suffix part of management PV, which provides list functionality for the server. Calling this PV will return array of strings with all PV names hosted by the server. Full list PV for server by default is: ${host}:${server}:List . |
No | :List |
Element: <group>
Basic function of the <group>
element is to provide logical container for <record>
elements and help provide hierarchical unique name for the records. Also trough groups are introduced configuration enhancements, like substitution and templates.
The group element can contain any of following elements: <group>
, <record>
or <application>
.
Following attributes are supported by the <group>
element:
Attribute | Description | Required | Default value |
---|---|---|---|
name |
The name of the group, it should be human-friendly name, unique within server configuration. Has no special meaning for the application server, it helps organize the XML file. | Yes | |
path |
Path contributes to the suffix part of PV names for records, which are defined within the group. Full record PV name is assembled from hierarchy of previous paths and ends with the record name. | Yes |
Element: <record>
The <record>
XML element (XML tag) is in many ways synonym to records as known in EPICS IOC database. It constitutes from following important parts:
- name, which defines record's PV, it has
- properties, which are equivalent to record fields, it has
- processing part, which provides/calculates record's value.
The full PV name of an record consist of hierarchically appended all parent group paths and record name at the end.
For example full EPICS PV name of the record defined in the upper server configuration example is:
A:SR:PS:MB-01:DiffCheck
.Following is a table of sub-elements (sub-tags in XML) to the
<record>
element:XML Element Description Required Default value Allowed values <name>
Name of the record, becomes ending part of the record's PV name. Yes <type>
DBR type of the record. If possible the correct type will be provided by the processor and will override this setting. If type is not defined and processor does not provide one, then DBR_DOUBLE
will be used.No DBR_DOUBLE
DBR_STRING
,DBR_SHORT
,DBR_FLOAT
,DBR_ENUM
,DBR_BYTE
,DBR_INT
,DBR_DOUBLE
<description>
Description of the record. No <persistent>
If true then upon alarm application server restart the record will be initialized to last known value. No False
<count>
Array size for the record's value. No 1 <units>
Units of the record's value. No <upperDispLimit>
Value limits, as in CTRL DBR. No <lowerDispLimit>
Value limits, as in CTRL DBR. No <upperWarningLimit>
Value limits, as in CTRL DBR. No <lowerWarningLimit>
Value limits, as in CTRL DBR. No <upperAlarmLimit>
Value limits, as in CTRL DBR. No <lowerAlarmLimit>
Value limits, as in CTRL DBR. No <upperCtrlLimit>
Value limits, as in CTRL DBR. No <lowerCtrlLimit>
Value limits, as in CTRL DBR. No <precision>
The record's value precision. No <enumLabels>
Comma separated list of names for enum states. No <alarm>
Initial alarm state of the record. It has no value but two further sub-elements. No <alarm>
<severity>
Initial record alarm severity. No NO_ALARM
* NO_ALARM
*MINOR_ALARM
*MAJOR_ALARM
*INVALID_ALARM
<alarm>
<status>
Initial record alarm status. No NO_ALARM
* NO_ALARM
*READ_ALARM
*WRITE_ALARM
*HIHI_ALARM
*HIGH_ALARM
*LOLO_ALARM
*LOW_ALARM
*STATE_ALARM
*COS_ALARM
*COMM_ALARM
*TIMEOUT_ALARM
*HW_LIMIT_ALARM
*CALC_ALARM
*SCAN_ALARM
*LINK_ALARM
*SOFT_ALARM
*BAD_SUB_ALARM
*UDF_ALARM
*DISABLE_ALARM
*SIMM_ALARM
*READ_ACCESS_ALARM
*WRITE_ACCESS_ALARM
<alarmConf>
This elements contains other elements as they would appear in BEAST configuration XML. When BEAST XML is exported, then these elements are injected into it. Except for the <alarmConf.path>
sub-element.No <alarmConf>
<path>
Path is comma separated list of hierarchy node names in BEAST XML configuration, to which this record/alarm should be injected. Yes <alarmConf>
<description>
The description, copied to BEAST configuration. No value of <description>
element<alarmConf>
<enabled>
If corresponding BEAST alarm should appear enabled in CSS. No True
<alarmConf>
<latching>
If BEAST alarm should latch. No True
<alarmConf>
<display>
<title>
The title for the BEAT display property. No <alarmConf>
<display>
<details>
The details for the BEAT display property. No <processor>
The processor elements defines programming object, a Java class, which processes and provides value of the record. It has one attribute instance, which defines Java class name of that processor object. Sub-elements depend on selected processor object. No Any Java class name, where Class implements org.scictrl.csshell.epics.server.processor.ValueProcessor interface. NOTE! The configuration element <alarmConf>
is important for integration with BEAST CSS alarm handler. If record does not have this element, then this record is not included in exported BEAST configuration. The alarm record and PV will still run and be accessible over EPICS, just not included in BEAST CSS alarm tree. All sub-elements of<alarmConf>
are injected into BEAST CSS XML, the path sub-element is converted to tree location and name of record is used as alarm PV in resulting XML.
Element: <processor>
A <processor>
is an element inside a <record>
declaration, which defines how the record value is created or processed by a ValueProicessor
class implementation.
For example a processor that can check if a network ping to certain host returns OK, a processor will look something like this:
...<record ...>... <processor instance="org.scictrl.csshell.epics.server.processor.HostPingAlarmProcessor"> <trigger>60000</trigger> <host>acc-pc-lx01.anka-acc.kit.edu</host> </processor> </record>...
The instance attribute define Java class name, which provides implementation of the processor and does the actual processing work. The processor Java class must by convention implement the interface org.scictrl.csshell.epics.server.ValueProcessor
.
The contents of <processor>
element is used as XML sub-section to initialize the actual processor instance and provide parameter for it's operation. In our example parameters are ping repetition trigger time 6000ms and remote host name to make a ping to.
Various processors will be discussed further in documentation.
A Record without a processor
It is possible to entirely skip <processor>
declaration when declaring record element. Such record will not be loaded into the application server and there will be no associate PV to operate.
But still configuration will be processed and the alarmConf element of the record configuration will be processed and corresponding BEAST configuration will be generated for this record, as described in the application server configuration.
This means that a record element without a <processor>
but with <alarmConf>
element can be used as placeholder which help generate BEAST alarm configuration element for certain PV without starting an application server record for this PV.
Element: <application>
The <application>
element (XML tag) defines an application object, that is performs complex tasks, that require with more than one record to control and provide results.
The the <application>
element (XML tag) has an attribute called instance
, that defines Java class name, that provides implementation of the application.
The contents of <application>
element is used as XML sub-section to initialize the actual application instance and provide parameter for it's operation.
Here are common sub-elements to the <application>
element (configuration parameters) valid for any application:
XML Element | Description | Required | Default value | Allowed values |
---|---|---|---|---|
<name> |
Name of the application, combined together with parent group names it provides PV name base for all application's child records (PVs). | Yes | Valid EPICS name characters | |
<nameDelimiter> |
Delimiter, which is used to join combined application name and partial child record (PV) names. | No | : |
A specific application can use have more own specific sub-elements used for configuration.
An application provides functionality and results in form of child records. All child records have PV name constructed in following way:
<path elements from one or more parent Group elements><application name><application delimiter, usually :><record name>
All applications, which extend from org.scictrl.csshell.epics.server.application.AbstractApplication
base class, create following child records by default:
Record name | Description | Processor |
---|---|---|
Status:LinkError |
If any of links (internal or external PVs) made within application is having problem or alarm, then it is summarized in this record. | MemoryValueProcessor , DBRType.BYTE |
Status:LinkError:String |
This is additional string describing nature of Status:LinkError record. |
MemoryValueProcessor , DBRType.STRING |
Status:ErrorSum |
If there is any error or interlock status active in application, it should be summarized in this record. | MemoryValueProcessor , DBRType.BYTE |
Advanced XML Concepts
Typical application server configuration definition file, such as alarms.xml
contain a lot of similar or almost same record definitions, with only slight changes in some details, like obligatory unique names of records and PVs. This means a lot of copy&paste of same text is required to prepare the document or later change common parameter.
To make tasks of managing such file easier two concepts are introduced: substitution and template insertion. They simplify writing the XML file, but they make more complex cognitive model of the configuration to understand.
I addition it is possible to split large XML configuration files into smaller units and connect them together with XInclude XML statement.
Substitution
The substitution uses in XML parser build-in capability to replace macro keyword with provided substitute.
How to make a substitution:
- Place
<substitutions>
element as first sub-element inside<server>
or<group>
element. - Place substitution macros as sub-elements to
<substitutions>
element, for example<macro1>
...</macro1>
macro2...</macro2>
... , their element value will be used as substitute for the macro name. - On same level or deeper where needed reference to a substitution macro use
$macro1
macro.Scope of substitution is within the parent element (
<group>
or<server>
). If more than one substitution macros with same name are defined, then the last defined takes precedence.IMPORTANT: Do not use for substitution macros names, which are same as element (tag or attribute) names found inside same scope (parent group element). This can cause infinite loop in substitution routine.
It is possible to reference with macro a name of another element, which is defined within same immediate parent. Then macro will be substituted with that element (tag or attribute) value.
Build-in Substitutions
There are two special build-in substitutions by the application server, which are valid within each group:
$path
- a full path until current current point in XML: it is combination of all paths from all groups within which substitution is found.$path1
- a single path element of immediate group in which substitution is located.IMPORTANT: Do not declare macros with these two names.
Here is an example:
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="server.xsd"> <server name="Alarms"> <management> <group name="SR PS Main" path="A:SR:PS:"> <substitutions> <status_alarm_desc>Device status indicates errors or inconsistencies - check device panel!</status_alarm_desc> </substitutions> <record> <name>MB-01:Status:Alarm</name><type>DBR_BYTE</type> <alarmConf> <path>Storage Ring,PS Status Check</path><description>${status_alarm_desc}</description> </alarmConf> <processor instance="org.scictrl.csshell.epics.server.processor.StatusCheckAlarmProcessor"> <!-- ... --> </processor> </record> <record> <name>MQ1-01:Status:Alarm</name> <type>DBR_BYTE</type> <alarmConf> <path>Storage Ring,PS Status Check</path><description>${status_alarm_desc}</description> </alarmConf> <processor instance="org.scictrl.csshell.epics.server.processor.StatusCheckAlarmProcessor"> <!-- ... --> </processor> </record> </group> </server> </config>
Template Insertion
As with substitution, the XML parser has capability to insert XML snippets into main XML three. This capabilities is used to insert specially declared groups into declared insertion point.
To make a template insertion:
- Declare a
<group>
of repetitive substructure of sub-groups, records or applications at beginning of parent group. - Mark the
<group>
element mark as a template by adding template attribute and by providing unique name to the group:<group name="uniqueID" template="true">
. - In records and applications replace declarations or parts of declarations that should be unique for each instance template of with macro reference.
- Insert templates with formula:
<group><substitutions>macro value</substitutions><insert>template name</insert></group>
Here is an example:
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="server.xsd"> <server name="Alarms"> <management> <group name="HostPing" path="A:GL:HostPing:"> <substitutions><interval>60000</interval></substitutions> <group name="host_ping_template" template="true"> <record> <name>${hname}-01:PingOK</name> <type>DBR_BYTE</type> <count>1</count> <alarmConf> <path>Infrastructure,Hosts</path><description>Host name resolution or ping failed</description> </alarmConf> <processor instance="com.kriznar.csshell.epics.server.processor.HostPingAlarmProcessor"> <trigger>${interval}</trigger> <host>${hname}.anka-acc.kit.edu</host> </processor> </record> </group> <group><substitutions><hname>acc-bpm-lib01</hname></substitutions><insert>host_ping_template</insert></group> <group><substitutions><hname>acc-bpm-lib02</hname></substitutions><insert>host_ping_template</insert></group> <group><substitutions><hname>acc-bpm-lib03</hname></substitutions><insert>host_ping_template</insert></group> </group> </server> </config>
Server Modules
Application server provides means to develop, configure, load and run modular server components, which are of two distinct types:
- Records / ValueProcessors - they are more simple, provide single PV which is accessible to clients to connect.
Encapsulates simple atomic tasks. - Applications - they are way to implement more complex logic. They can connect to other PVs and provide own set of PVs, through which clients can configure, control, monitor and obtain results of an application.
Records
A record provides a single EPICS PV, can be configured and can connect to other PVs.
TBD list of record.
Modular Applications
Application module is more complex then Record. It is confibured trough XML, it can connect to several PVs to get data, it can provide several PVs as means of controlling the application or providing it's results.
TBD list of applications
Other Servers and Applications
Other servers which are hosted by EPICS Java installation bundle and consist of more elements than just Record or Application.
- OrbitServer
- OrbitCorrection
Glossary of Terms
Term | Description |
---|---|
CA | Channel Access protocol, part of EPICS |
CAS | Java implementation of CA protocol on server side |
CSS BEAST | Control system studio implementation of EPICS archiver called BEAST |
JCA | Java implementation of CA protocol on client side |