Javascript/Node.js

This GEMHost JavaScript example uses the code generated from TransSECS using the Java/Javascript deployment option. This is Node.js code.

To install Node.js on Windows follow the instructions here: https://docs.microsoft.com/en-us/windows/nodejs/setup-on-windows

Install Python: https://www.python.org/downloads/release/python-2716/ (this is required by “npm install”)

Download the node.js sample code from: www.ergotech.com/docs/nodejs.zip

Unzip the sample into the “GEMHost” sample project. Build the GEMHost project in TransSECS. Start the StandAloneGEMTool by double-clicking the run.bat in that folder.

In the nodejs folder run:

npm install 

Once that completes successfully, to run the sample run:

npm start

As you interact with the StandAloneGEMTool - sending events and alarms and choosing responses to the host command - you should see various log messages output to the terminal.

> node-java-gemhost@1.0.0 start C:\Users\Public\ErgoTech\TransSECSProgrammaticTrial\Projects\GEMHost\nodejs
> node GEMHostExample.js
 
at ip address localhostGEMHost connecting to tool on IP Address "localhost" and port 5010 and device id 1
GEMHost is running
Event received: GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
Event Received GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
PPID "<A 'REC0'>"
VID Received GemVariable [name=WaferCount, id=1510]
Host Command Message Status: Successful - No Error
Host Command Successful 0
Event received: GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
Event Received GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
PPID "<A 'RecipeName'>"
VID Received GemVariable [name=WaferCount, id=1510]
Host Command Message Status: Successful - No Error
Host Command Successful 0
Host Command Message Status: Successful - No Error
Host Command Successful 4
Host Command Message Status: Successful - No Error
Host Command Failed 3 Reason [[??BADPARM, 1]]
Event received: GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
VID Received GemVariable [name=WaferCount, id=1510]
Event Received GemReportVariable [associatedIDs=[103], configured=false, name=LOADED, id=7503]
PPID "<A 'REC8'>"
Event received: GemReportVariable [associatedIDs=[100], configured=false, name=STARTED, id=7501]
VID Received GemVariable [name=WaferCount, id=1510]
Host Command Message Status: Successful - No Error
Host Command Failed 3 Reason [[??BADPARM, 1]]
Event received: GemReportVariable [associatedIDs=[120], configured=false, name=COMPLETED, id=7502]
VID Received GemVariable [name=WaferCount, id=1510]
Host Command Message Status: Successful - No Error
Host Command Failed 3 Reason [[??BADPARM, 1]]

The sample code demonstrates all the important aspects of a host - listening for values, alarms, reports and events and sending messages - here the “START” host command.

const java = require("java");
 
// Add our TransSECS runtime jar to the classpath
java.classpath.push("../JAVA/GEMHostJavaScriptRuntime.jar")
// Add current directory, so that log4j.xml is on the classpath to configure logging
java.classpath.push(".")
 
var host;
 
/** 
 * Configure, init, and start the host, and add listeners.
*/
function init() {
	 //set environment so that we are not simulating
	java.import("com.ergotech.util.SimulationManager").getSimulationManagerSync().setSimulatingSync(false);
 
	//set up parameters for the tool connection
	let hostname =  "localhost"; // eg "192.168.5.104" -- IP Address of the tool
	let portNumber = 5010; //tool's port number
	let deviceID =  1; //tool's device id
 
	// Connect to the tool, change parameter values here if needed
	host = java.newInstanceSync("deploy.GEMHost.EquipmentController");
	host.setEquipmentHostNameSync(hostname);
	host.setActivePortSync(portNumber);
	host.setDeviceIdSync(deviceID);
	host.initSync();	
	host.startSync();
	console.log(host.getControllerNameSync()+" connecting to tool on IP Address \"" +hostname+"\" and port " + portNumber + " and device id " + deviceID);
 
	// Add a listener for all events
	host.setGlobalEventListenerSync(java.newProxy("com.ergotech.transsecs.secs.host.EventListener", {
		eventReceived: function(ceid, eventReportValues) {
			console.log("Event received: " + ceid);
		}
	}));
 
	// The host wants to know when an alarm occurs. 
    // Add a listener for all alarms
    host.addAlarmListener(java.newProxy("com.ergotech.transsecs.secs.host.AlarmListener", {
		alarmReceived: function(alarmValues) {
			console.log("Alarm Received " + alarmValues);
		}
	}));
 
    // Add a listener for a report configured in the TransSECS host.
    host.addReportListener(1001, java.newProxy("com.ergotech.transsecs.secs.host.ReportListener", {
		reportUpdated: function(report) {
			console.log("Report Received " + report.getVidValuesSync() );
		}
	}));
 
    // Add a listener for an event configured in the transsecs host.
    host.addEventListener(7503, java.newProxy("com.ergotech.transsecs.secs.host.EventListener", {
		eventReceived: function(ceid, eventReportValues) {
			console.log("Event Received " + ceid );
			console.log("PPID \"" + host.getGemHostModelSync().getVIDSync("PPID").getCurrentValueSync() + "\"");
		}
	}));
    // Add a listener for a particular vid configured in the transsecs host.
    host.addVidListener(1510, java.newProxy("com.ergotech.transsecs.secs.host.VidListener", {
		vidUpdated: function(value) {
			console.log("VID Received " + value );
		}
    }));
 
		// Send an s1f3 once the connection is operational
    // Add a listener for the connection status
    host.addConnectionStatusListener(java.newProxy("com.ergotech.transsecs.secs.host.ConnectionStatusListener", {
		connectionStatusChanged: function(connectionStatus, comment) {
			// Check if the connection status is operational
			if (connectionStatus == 0) {
				let s1f3 = host.getMessageBeanSync("SVIDRequest");
				s1f3.setSVIDSync(1516);
				let s1f3response = s1f3.sendMessageAndWaitSync();
				console.log(s1f3response.getSVIDListSync().getSync(0).toString());
			}
		}
	}));
 
     console.log("GEMHost is running ");
}
 
/** Send the host command to the tool. Sends the message and waits for a reply.
*/
function sendHostCommand() {
try {
	let s2f41 = host.getMessageBeanSync("HostCommandSTART");
	//change a command parameter value for testing
	s2f41.setPPIDSync("PPID"); //only one of the real CNAMES must be used here (if more than one CNAME in the message, you can use any one)
	// Generate a random int between 0-9
	let randInt = Math.floor(Math.random() * 10);
	s2f41.setRecipeNameSync("REC"+randInt);
 
	let response = s2f41.sendMessageAndWaitSync();
	const VIBMessageBean = java.import("com.ergotech.transsecs.secs.VIBMessageBean");
	console.log("Host Command Message Status: " + responseStatus(s2f41.getDataSourceSync(VIBMessageBean.RESPONSE_STATUS_NAME).getIntValueSync()));
	if ( response != null && s2f41.getDataSourceSync(VIBMessageBean.RESPONSE_STATUS_NAME).getIntValueSync() == 0 ) { // successful response 
		if ( response.getHCACKSync()[0] == 0 || response.getHCACKSync()[0] == 4 ) {
			console.log("Host Command Successful " + response.getHCACKSync()[0]);
		} else {
			console.log("Host Command Failed " + response.getHCACKSync()[0] + " Reason " + response.getReasonListSync());
		}
	}
	} catch (e) {
	 console.log("Error sending message " + e );
	}
}
 
/** Return a string describing the response to the message. 
 * 
 *  Possible responses are constants in SecsMsg
 * 
 */
function responseStatus (responseCode ) {
	const SecsMsg = java.import("com.ergotech.secs.SecsMsg");
	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 response, but a primary message received 
	}
	return "Unknown";
}
 
init();	
// Keep the program running until stopped
setInterval(sendHostCommand, 10000);