After building a GEM Host in TransSECS you can register to receive the current status of the connection:
host.addConnectionStatusListener(new ConnectionStatusListener() { @Override public void connectionStatusChanged(int connectionStatus, String comment) { System.out.println ("Current Connection Status " + connectionStatus + " Status String \"" + comment + "\""); } });
For this code snippet to work correctly, host must not be null. This can happen if this code is run in an initialization process, such as in a StartupTrigger script, because the StartupTrigger code could be (and probably will be) run before the normal TransSECS/MIStudio startup sequence which starts the host controller. See the Thread code example below Threaded Example to solve this issue.
TransSECS GEM Host Connection States
The GEM Host can have one of these connection states depending on the status of the connection to the tool:
/** Possible connection states */ public static enum ConnectionStates { ENABLE_ALL_EVENTS_FAILED(-80), ENABLE_EVENTS_FAILED(-70), LINK_REPORTS_FAILED(-60), CREATE_REPORTS_FAILED(-50), ENABLE_ALARMS_FAILED(-40), ONLINE_FAILED(-30), COMMUNICATION_FAILED(-20), CONNECT_FAILED(-10), DISCONNECTED(-1), OPERATIONAL(0), // connection complete and ready CONNECTED(10); // connection to tool. Configuration starting
For normal operation, the status must be OPERATIONAL - 0 Any other state is an either an error (negative numbers) or transient (CONNECTED). The description of the states, with corrective action (if any) are:
This code example is run from a StartupTrigger script in TransSECS (or a script triggered by the StartupTrigger in MIStudio) to set up the ConnetionStatusListener. For MIStudio, this script pushes data to two BroadcastServers (StatusListenerCommand and StatusListenerValue) whenever there is a connection status change.
//sets up a listener to handle connection status changes var TransSecsController = Java.type("com.ergotech.transsecs.secs.TransSecsController"); var ConnectionStatusListener = Java.type("com.ergotech.transsecs.secs.host.ConnectionStatusListener"); var statusListener = new ConnectionStatusListener() { connectionStatusChanged : function(connectionStatus,comment) { print ("Current Connection Status " + connectionStatus + " Status String \"" + comment + "\""); StatusListenerComment->setStringValue(comment); StatusListenerValue->setIntValue(connectionStatus); } } host=TransSecsController.findController("GEMHost"); //use your GEM Host name host.addConnectionStatusListener(statusListener);
In the code below, which is run from a StartupTrigger script in TransSECS (or a script triggered by the StartupTrigger in MIStudio), a Thread is started which waits for the host not to be null and then sets up the ConnectionStatusListener.
//sets up a listener to handle connection status changes var TransSecsController = Java.type("com.ergotech.transsecs.secs.TransSecsController"); var ConnectionStatusListener = Java.type("com.ergotech.transsecs.secs.host.ConnectionStatusListener"); var Thread = Java.type("java.lang.Thread"); function waitForHost() { print("wait for host THREAD started"); host=TransSecsController.findController("GEMHost"); //use your host name here while (host==null) { //print("host is still null"); Thread.sleep(50); //wait 50 ms host=TransSecsController.findController("GEMHost"); } host=TransSecsController.findController("GEMHost"); // print("host is not null, setting up connection status listener"); var connectionStatusListener = new ConnectionStatusListener() { connectionStatusChanged : function (connectionStatus, comment) { //updateToolStatus(connectionStatus,comment);//optional, if you want to store this information somewhere //below is for MIStudio projects, two BroadcastServers are written to with the connection status values StatusListenerComment->setStringValue(comment); StatusListenerValue->setIntValue(connectionStatus); print ("Current Connection Status " + connectionStatus + " Status String \"" + comment + "\""); } }; // add this listener to the host host.addConnectionStatusListener(connectionStatusListener); print("Connection Status Trigger Registered"); }//end of function to wait for host /// START OF MAIN JAVASCRIPT CODE /// print("Startup Trigger"); var r = new java.lang.Runnable() { run: function() { waitForHost(); } } new Thread(r).start();
This is an example of setting up an “alarm listener” which will be called for any S5F1 message received by the host.
It also stores the alarm data to a table in a database.
A simple Devices setup may be something such as:
where Historical might be configured as such (as used in this example):
Use this code in the same script (e.g. StartupTrigger) where you have waited for the “host” variable to not be null (see script above). This way you will be able to add the alarm listener to the host controller during initialization phase of the interface.
//additional class imports needed by this script var DataSource = Java.type("com.ergotech.vib.servers.DataSource"); var ValueChangedEvent = Java.type("com.ergotech.vib.valueobjects.ValueChangedEvent"); var AlarmListener = Java.type("com.ergotech.transsecs.secs.host.AlarmListener"); var StringValueObject = Java.type("com.ergotech.vib.valueobjects.StringValueObject"); var LongValueObject = Java.type("com.ergotech.vib.valueobjects.LongValueObject"); var LinkedHashMap = Java.type("java.util.LinkedHashMap"); //make sure that the "host" variable is not null by using the threaded script above to wait for the initialization to be complete //set up alarm listener var alarmHandler = new AlarmListener() { alarmReceived : function(alarmValues) { //prepare to log alarm data to the database id = alarmValues.getAlid(); alcd = alarmValues.getAlcd();//alcd plus set/cleared bit altx = alarmValues.getAltx(); isSet = alarmValues.isSet(); // boolean, whether this alarm is set (true) or cleared (false) print ("alarm received -- id="+id+" altx="+altx+" alcd="+alcd+" set? "+isSet); DataSource.logMessage("alarm received -- id="+id+" altx="+altx+" alcd="+alcd+" set? "+isSet); //make a LinkedHashMap of the alarm data so it can be saved in the database alarmDataMap = new LinkedHashMap(); alarmDataMap.put("alid",new StringValueObject(id)); alarmDataMap.put("altx",new StringValueObject(altx)); alarmDataMap.put("alcd",new LongValueObject(alcd & 0x7F)); // remove the set/clear bit alarmDataMap.put("setorclear",new LongValueObject(isSet)); //add this alarm data to a valueobject alarmData = new StringValueObject("alarm data"); //this string value will be ignored alarmData.setProperty("MAP",alarmDataMap); //alarmDataMap has the data to be stored //write to database //This assumes you have a database connection manager for your database set up in Devices called "AlarmDatabase" //"Historical" is the name of the TriggeredHistorical server added to "AlarmDatabase". The table name is set in this server, and the "create table" property should be set to true. /Devices/AlarmDatabase_Servers/Historical->mapTrigger(new ValueChangedEvent(this,alarmData)); } }; host.addAlarmListener(alarmHandler); print("Alarm Listener set up and registered");
Alternate Alarm Listener using a SQL Statement rather than a Historical
//additional class imports needed by this script var DataSource = Java.type("com.ergotech.vib.servers.DataSource"); var AlarmListener = Java.type("com.ergotech.transsecs.secs.host.AlarmListener"); var ArrayValueObject = Java.type("com.ergotech.vib.valueobjects.ArrayValueObject"); var StringValueObject = Java.type("com.ergotech.vib.valueobjects.StringValueObject"); var LongValueObject = Java.type("com.ergotech.vib.valueobjects.LongValueObject"); //make sure that the "host" variable is not null by using the threaded script above to wait for the initialization to be complete //set up alarm listener var alarmHandler = new AlarmListener() { alarmReceived : function(alarmValues) { //prepare to log alarm data to the database id = alarmValues.getAlid(); alcd = alarmValues.getAlcd();//alcd plus set/cleared bit altx = alarmValues.getAltx(); isSet = alarmValues.isSet(); // boolean, whether this alarm is set (true) or cleared (false) print ("alarm received -- id="+id+" altx="+altx+" alcd="+alcd+" set? "+isSet); DataSource.logMessage("alarm received -- id="+id+" altx="+altx+" alcd="+alcd+" set? "+isSet); //make a ArrayValueObject of the alarm data so it can be saved in the database alarmData = new ArrayValueObject(); alarmData.add(new StringValueObject(id)); alarmData.add(new StringValueObject(altx)); alarmData.add(new LongValueObject(alcd & 0x7F)); // remove the set/clear bit alarmData.add(new LongValueObject(isSet)); //write to database //This assumes you have a database connection manager for your database set up in Devices called "AlarmDatabase" //"AlarmStore" is the name of the Database Write server added to "AlarmDatabase". // the SQL statement must include ?'s for each of the parmeters in the long value object (alix, altx, alcd and isSet // for example: // insert into SECSAlarms (alid, altx, alcd, isset) values (?,?,?,?) /Devices/AlarmDatabase_Servers/AlarmStore->setValueObject(alarmData); } }; host.addAlarmListener(alarmHandler); print("Alarm Listener set up and registered");