This GEMHost Java example uses the code generated from TransSECS using the Java/Javascript deployment option.
package com.ergotech.transsecs.examples.gemhost;
import java.util.Date;
import java.util.List;
import java.util.Random;
import com.ergotech.secs.SecsException;
import com.ergotech.secs.SecsMsg;
import com.ergotech.secs.gem.GemHostModel.GemValueVariable;
import com.ergotech.secs.gem.GemToolModelSnapshot.GemReportVariable;
import com.ergotech.transsecs.secs.VIBMessageBean;
import com.ergotech.transsecs.secs.host.AlarmListener;
import com.ergotech.transsecs.secs.host.AlarmValues;
import com.ergotech.transsecs.secs.host.EventListener;
import com.ergotech.transsecs.secs.host.ReportListener;
import com.ergotech.transsecs.secs.host.ReportValues;
import com.ergotech.transsecs.secs.host.VidListener;
import com.ergotech.util.NTPDate;
import com.ergotech.vib.exceptions.BadParameterException;
import com.ergotech.vib.exceptions.VIBUpdateFailedException;
import deploy.GEMHost.EquipmentController;
import deploy.GEMHost.HostCommandSTART;
import deploy.GEMHost.HostCommandReply;
public class GEMHost {
//you must have your TransSECS generated jar on the classpath for EquipmentController
public EquipmentController host = null;
public GEMHost(String[] args) {
//set environment so that we are not simulating
com.ergotech.util.SimulationManager.getSimulationManager().setSimulating(false);
//set up parameters for the tool connection
String hostname = "localhost"; //"192.168.5.104"; //IP Address of the tool
int portNumber = 5010; //tool's port number
int deviceID = 1; //tool's device id
// Connect to the tool, change parameter values here if needed
host = new EquipmentController();
host.setEquipmentHostName(hostname);
host.setActivePort(portNumber);
host.setDeviceId(deviceID);
try {
host.init();
host.start();
} catch (BadParameterException e1) {
e1.printStackTrace();
} catch (VIBUpdateFailedException e1) {
e1.printStackTrace();
}
System.out.println(host.getControllerName()+" connecting to tool on IP Address " +hostname+" and port " + portNumber + " and device id " + deviceID);
host.addConnectionStatusListener(new ConnectionStatusListener() {
@Override
public void connectionStatusChanged(int connectionStatus, String comment) {
System.out.println ("Current Connection Status " + connectionStatus + " Status String \"" + comment + "\"");
//note: see https://www.ergotech.com/wiki/doku.php?id=host_connection_status for connectionStatus values
}
});
host.setGlobalEventListener(new EventListener() {
@Override
public void eventReceived(GemReportVariable ceid, List event) {
System.out.println ("Event Received " + ceid );
}
});
// The host wants to know when an alarm occurs.
// add a listener for all alarms
host.addAlarmListener(new AlarmListener() {
@Override
public void alarmReceived(AlarmValues alarmValues) {
System.out.println ("Alarm Received " + alarmValues );
}
});
// add a listener for a report configured in the TransSECS host.
host.addReportListener(1001, new ReportListener() {
@Override
public void reportUpdated(ReportValues report) {
System.out.println ("Report Received " + report.getVidValues() );
}
});
// add a listener for an event configured in the transsecs host.
host.addEventListener(7502, new EventListener() {
@Override
public void eventReceived(GemReportVariable ceid, List event) {
System.out.println ("Event Received " + event );
System.out.println ("PPID \"" + host.getGemHostModel().getVID("PPID").getCurrentValue() + "\"");
}
});
// add a listener for a particular vid configured in the transsecs host.
host.addVidListener(1510, new VidListener() {
@Override
public void vidUpdated(GemValueVariable value) {
System.out.println ("VID Received " + value );
}
});
System.out.print("GEMHost is running ");
//Keep the program running until stopped
long counter=0;
while ( true ) {
try {
Thread.sleep(1000);//sleep for a second
counter++;
//We can add code here to do something periodically
System.out.print(".");
//every 20 seconds we can send a host command for testing purposes
if(counter%20 == 0){
System.out.println("\nCount: " + counter + " " + NTPDate.toString(new Date()));
//sendHostCommand();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/** Send the host command to the tool. Sends the message and waits for a reply.
*/
public void sendHostCommand() {
HostCommandSTART s2f41=null;
try {
s2f41 = (HostCommandSTART)host.getMessageBean("HostCommandSTART");
} catch (BadParameterException e1) {
e1.printStackTrace();
}
//change a command parameter value for testing
Random r = new Random();
s2f41.setPPID("PPID"); //only one of the real CNAMES must be used here (if more than one CNAME in the message, you can use any one)
s2f41.setRecipeName("REC"+Integer.toString(r.nextInt(10)));
//System.out.println("Sending Host Command to Tool");
try {
HostCommandReply response = s2f41.sendMessageAndWait();
System.out.println("Host Command Message Status: " + responseStatus(s2f41.getDataSource(VIBMessageBean.RESPONSE_STATUS_NAME).getIntValue()));
if ( response != null && s2f41.getDataSource(VIBMessageBean.RESPONSE_STATUS_NAME).getIntValue() == 0 ) { // successful response
if ( response.getHCACK()[0] == 0 ) {
System.out.println("Host Command Successful");
} else {
System.out.println("Host Command Failed" + response.getHCACK()[0] + " Reason " + response.getReasonList());
}
}
} catch (SecsException | BadParameterException e) {
e.printStackTrace();
}
}
/** Return a string describing the response to the message.
*
* Possible responses are constants in SecsMsg
*
*/
public String responseStatus ( int responseCode ) {
switch (responseCode ) {
case SecsMsg.NO_ERROR:
return "Successful - No Error"; // the message was sent and (if appropriate) the response was received.
case SecsMsg.TIMEOUT_ERROR:
return "Message Timed Out"; // no response to the message within T3 timeout
case SecsMsg.S9_ERROR:
return "S9 Message Reponse"; // the tool does not understand the primary and return an S9 message (probably S9F5 or S9F7)
case SecsMsg.F0_ERROR:
return "F0 Message Response"; // the tool return an SxF0 message. This usually means that the tool is offline or online local
case SecsMsg.CANNOT_SEND:
return "No Connection to Tool"; // there is no connection to the tool, the message cannot be sent.
case SecsMsg.UNSOLICITED:
return "Unsolicted Message"; // this is not a repsonse, but a primary message received
}
return "Unknown";
}
static public void main (String args[]) {
GEMHost gemHost = new GEMHost(args);
}
}
**Notifications**
The example above demonstrates the most common notification - received events, reports and messages. In most cases, receiving a notification of the message received and getting the values from the message is the easiest and most convenient approach. However, it is possible to register to receive notifications for individual elements in a message. In the element of the message the //"Publish"// checkbox must be checked. For example, here we choose to Publish the "ECID".
{{:pasted:20200513-184840.png}}
You can publish elements of any type. Here a list is being published.
{{:pasted:20200513-185052.png}}
To receive notification of the published list, create a method to receive the notification
public void ecidListUpdated ( ValueChangedEvent event ) {
System.out.println("List updated " + event);
[...]
}
Then create a connector that links from the //ECIDList// to the //ecidListUpdated// method.
Connector connector = DataSourceContainer.getConnectorFor(this, "ecidListUpdated");
The ECIDList is part of the ECIDListReply message. First get the ECIDListReply message and then the ECIDList data source and add the connector.
ECIDListReply ecidListReply = (ECIDListReply)host.getMessageBean("ECIDListReply");
ecidListReply.getDataSource("ECIDList").addConnector(connector);
Here's the full code:
try {
Connector connector = DataSourceContainer.getConnectorFor(this, "ecidListUpdated");
ECIDListReply ecidListReply = (ECIDListReply)host.getMessageBean("ECIDListReply");
ecidListReply.getDataSource("ECIDList").addConnector(connector);
} catch (Exception e1) {
e1.printStackTrace();
}
Every time the ECIDListReply (S2F30) message is received, the ecidListUpdate method will be called.
Normally, the notification would be called only once. However, here, the ECIDList is marked as "Repeat" which means that the ecidListUpdate will be called for each repeat of the list.
The ECIDList is the last notification in the "Repeat" parsing, and so when that is received, the ECIDListReply message will have the current values from the list in the ECID, ECIDName, etc. variables. These can then be retrieved with the "get" methods. Filling out our notifier a little we may have something like this:
public void ecidListUpdated ( ValueChangedEvent event ) {
System.out.println("List updated " + event.getSource());
try {
ECIDListReply ecidListReply = (ECIDListReply)host.getMessageBean("ECIDListReply");
System.out.println("ECID " + ecidListReply.getECID() + " Name " + ecidListReply.getECIDName() );
} catch (Exception e) {
e.printStackTrace();
}
}
Be sure to read the section **Advanced Message Matching** in [[Message Matching]] concerning Repeat and Optional before using this approach, but when required it can be a powerful tool.
**Characterization**
An alternative to the above approach to listing ECIDs is to use the characterization capabilities of TransSECS.
Characterization provides a list of all CEIDs, Reports (RPTIDs) and VIDs (SVIDs and ECIDs) available on the tool. Simply call the "characterize" method with the host controller.
Characterize.characterize(host);
This will populate the GEM Host Model maintained by the host. This can be retrieved with the call:
host.getGemHostModel();
Check the GemHostModel JavaDocs for details of the model.