Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
gem300_scripts [2021/07/12 12:25] wikiadmin |
gem300_scripts [2025/02/28 20:17] (current) wikiadmin |
||
---|---|---|---|
Line 2: | Line 2: | ||
- | GEM300 standards consist of state models. | + | GEM300 standards consist of state models. |
+ | |||
+ | Implementation of these standards will require reference to the appropriate standard and state model in the standard. | ||
+ | |||
+ | ===== TransSECS implementation ===== | ||
+ | |||
+ | |||
+ | In all the TransSECS GEM300 implementations there are two, fundamental part. | ||
+ | |||
+ | - " | ||
+ | - " | ||
+ | |||
+ | Individual standards have other components, E40 Process Jobs, E87 Carriers, E90 Substrates, E94 Control Jobs, etc. | ||
+ | |||
+ | **Note:** You do not need to implement, or parse SECS messages. | ||
+ | |||
+ | ==== E39 ==== | ||
+ | |||
+ | E39 is a required standard to support GEM300, however the implementation and operation of E39 is completely transparent to the TransSECS GEM300 operation. | ||
+ | |||
+ | ==== E40 ==== | ||
+ | |||
+ | Provides a model of the process state within the tool, primarily through the management of " | ||
+ | |||
+ | * Allocated - state transition 2 - the Process Job is removed from the queue in preparation for execution - processJob.allocated(); | ||
+ | * Material Arrived - no state transition - indicate that the material for the Process Job is at the tool - processJob.materialArrived(); | ||
+ | * Start the Job - state transition 4 - start execution of the Process Job - processJob.readyToStart(); | ||
+ | * Processing Complete - state transition 6 - The material processing is complete - processJob.complete(); | ||
+ | * Material Departed - state transition 7 - The material has been removed from the tool. The process job is complete and will be deleted - processJob.materialDeparted(); | ||
+ | * | ||
+ | === E40 Service Wrapper === | ||
+ | |||
+ | The E40 Service Wrapper provides access to control the flow of E40. Most importantly, | ||
+ | |||
+ | A listing of all process jobs is provided by: | ||
+ | < | ||
+ | E40ServiceWrapper.getInstance().getAllPRJobs(); | ||
+ | </ | ||
+ | A particular process job can be obtained by the job id: | ||
+ | < | ||
+ | E40ServiceWrapper.getInstance().getPRJob(jobID) | ||
+ | </ | ||
+ | |||
+ | === E40 Callback Interface === | ||
+ | |||
+ | The E40 Callback Interface provides notification of activity from the host. There are four methods: | ||
+ | |||
+ | | ||
+ | Indicates that the state of a process job has change. | ||
+ | | ||
+ | A request to create a process job. No action is required if the creation of the process job is acceptable. | ||
+ | This method provides recipe variable. | ||
+ | | ||
+ | Set the order in which process jobs should be processed. Possible options are: | ||
+ | 1 = ARRIVAL | ||
+ | 2 = OPTIMIZE | ||
+ | 3 = LIST | ||
+ | | ||
+ | Called when the host requests that a command be executed on the process job. Possible commands are ABORT, | ||
+ | Only ABORT must be supported. If the command is not supported, throw an E40Exception | ||
+ | |||
+ | == Sample Implementation == | ||
+ | |||
+ | <code javascript> | ||
+ | var E39MessageHandler = Java.type(" | ||
+ | var E40MessageHandler = Java.type(" | ||
+ | var E40ServiceWrapper = Java.type(" | ||
+ | var E40CallbackInterface = Java.type(" | ||
+ | var ProcessJob = Java.type(" | ||
+ | var TransSecsController = Java.type(" | ||
+ | var Thread = Java.type(" | ||
+ | |||
+ | // create the callback interface. | ||
+ | var E40Callback = new E40CallbackInterface() { | ||
+ | |||
+ | | ||
+ | print (" | ||
+ | // send the new state for the process job to the PLC | ||
+ | / | ||
+ | / | ||
+ | }, | ||
+ | | ||
+ | // a request to create a process job. It;s possible to query the PLC (or any other subsystem | ||
+ | // to determine if this process job is allowable. | ||
+ | // reason it's not acceptable. | ||
+ | print ("Job Creation of " + prJob.getPrJobId() + " permitted" | ||
+ | // indicate that this job is not allocated | ||
+ | / | ||
+ | // record the id | ||
+ | / | ||
+ | }, | ||
+ | | ||
+ | // set the provided recipe variables on the job id. | ||
+ | // that is, send the recVarList to the PLC | ||
+ | if ( recVarList != null ) { | ||
+ | for ( counter = 0 ; counter < recVarList() ; counter++ ){ | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | }, | ||
+ | | ||
+ | // Set the order in which process jobs should be processed | ||
+ | // possible options are: | ||
+ | //1 = ARRIVAL | ||
+ | //2 = OPTIMIZE | ||
+ | //3 = LIST | ||
+ | |||
+ | }, | ||
+ | | ||
+ | print(" | ||
+ | |||
+ | // called when the host reequests that a command be executed on the process job | ||
+ | // possible commands are ABORT, | ||
+ | cmds = [' | ||
+ | // A different PLC register could be used for each of these and so the command | ||
+ | // could be indicated by, for example: | ||
+ | // / | ||
+ | // Here we use a single register and indicate the commands, ABRORT=1, STOP=2, etc. | ||
+ | |||
+ | // first indicate which process job the command is being executed on | ||
+ | / | ||
+ | // send the parameters - here we just print them | ||
+ | if ( prCmdParameterList != null ) { | ||
+ | for ( counter = 0 ; counter < prCmdParameterList.size() ; counter++ ){ | ||
+ | | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // get the index of the command | ||
+ | cmdId = cmds.indexOf(prCmd); | ||
+ | / | ||
+ | } | ||
+ | }; | ||
+ | |||
+ | /// START OF MAIN JAVASCRIPT CODE /// | ||
+ | print(" | ||
+ | |||
+ | var controller = null; | ||
+ | do { | ||
+ | // | ||
+ | Thread.sleep(50); | ||
+ | controller = TransSecsController.findController(" | ||
+ | } while (controller == null); | ||
+ | |||
+ | try { | ||
+ | E39MessageHandler.addMessageHandler(controller.getControllerName()); | ||
+ | E40MessageHandler.addMessageHandler(); | ||
+ | } catch ( e) { | ||
+ | print (e); | ||
+ | } | ||
+ | E40ServiceWrapper.getInstance().registerCallback(E40Callback); | ||
+ | |||
+ | print(" | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </ | ||
+ | |||
+ | As noted above, if the process job is not set to auto start, you will need to start the job at the tool after the host sends the start command. | ||
+ | < | ||
+ | | ||
+ | |||
+ | if (newState == ProcessJobStates.PROCESSING.getStateId() && oldState == ProcessJobStates.WAITINGFORSTART.getStateId() ) { | ||
+ | // send the commands to the control system to start executing the process job | ||
+ | } | ||
+ | // similar checks may be needed for transitions from PAUSED | ||
+ | // additional state-change related code. | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | ==== E40 Java Example ==== | ||
+ | === E40 Java Using the Service wrapper calls to process a job === | ||
+ | Executing a job through E40 requires indicating to the process job the current state of the process. For example: | ||
+ | <code java> | ||
+ | Initialize the handlers: | ||
+ | try { | ||
+ | E39MessageHandler.addMessageHandler(equipmentController.getControllerName()); | ||
+ | E40MessageHandler.addMessageHandler(); | ||
+ | E94MessageHandler.addMessageHandler(); | ||
+ | E87MessageHandler.addMessageHandler(2, | ||
+ | } catch (BadParameterException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | E40ServiceWrapper.getInstance().registerCallback(new E40Callback()); | ||
+ | [...] | ||
+ | /** Process a Job. */ | ||
+ | protected void processJob() { | ||
+ | ProcessJob[] allProcessJobs = E40ServiceWrapper.getInstance().getAllPRJobs(); | ||
+ | if ( allProcessJobs.length > 0 ) { | ||
+ | ProcessJob processJob = allProcessJobs[0]; | ||
+ | processJob.allocated(); | ||
+ | processJob.materialArrived(); | ||
+ | wait500(); | ||
+ | processJob.readyToStart(); | ||
+ | while ( processJob.getPrJobState() == ProcessJobStates.WAITINGFORSTART.getStateId() ) { | ||
+ | wait500(); | ||
+ | } | ||
+ | wait500(); | ||
+ | try { | ||
+ | processJob.complete(); | ||
+ | processJob.materialDeparted(); | ||
+ | } catch (InvalidStateTransitionException e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | Notification of changes in process are sent through the | ||
+ | <code java> | ||
+ | import com.ergotech.secs.e39.E39MessageHandler; | ||
+ | import com.ergotech.secs.e40.E40MessageHandler; | ||
+ | import com.ergotech.secs.e40.E40ServiceWrapper; | ||
+ | import com.ergotech.secs.e40.E40CallbackInterface; | ||
+ | import com.ergotech.secs.e40.ProcessJob; | ||
+ | import com.ergotech.transsecs.secs.TransSecsController; | ||
+ | |||
+ | public class E40Callback { | ||
+ | public E40Callback() { | ||
+ | System.out.println(" | ||
+ | |||
+ | TransSecsController controller = TransSecsController.findController(" | ||
+ | } while (controller == null); | ||
+ | |||
+ | try { | ||
+ | E39MessageHandler.addMessageHandler(controller.getControllerName()); | ||
+ | E40MessageHandler.addMessageHandler(); | ||
+ | } catch (Exception e) { | ||
+ | System.out.println(e); | ||
+ | } | ||
+ | |||
+ | E40ServiceWrapper.getInstance().registerCallback(new E40CallbackInterface() { | ||
+ | @Override | ||
+ | public void prStateChange(ProcessJob prJob, int oldState, int newState) { | ||
+ | System.out.println(" | ||
+ | ProcessJob.getStateName(oldState) + " to " + ProcessJob.getStateName(newState)); | ||
+ | |||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void prJobCreate(ProcessJob prJob) { | ||
+ | System.out.println(" | ||
+ | |||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void prSetRecipeVariable(ProcessJob prJob, List<?> | ||
+ | if (recVarList != null) { | ||
+ | for (Object recVar : recVarList) { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void prSetMtrlOrder(int prCurrentMtrlOrder, | ||
+ | // Handle material order settings | ||
+ | } | ||
+ | |||
+ | @Override | ||
+ | public void prCommandCallback(ProcessJob prJob, String prCmd, List<?> | ||
+ | System.out.println(" | ||
+ | |||
+ | String[] cmds = {" | ||
+ | int cmdId = Arrays.asList(cmds).indexOf(prCmd); | ||
+ | |||
+ | |||
+ | // Send the parameters | ||
+ | if (prCmdParameterList != null) { | ||
+ | for (Object param : prCmdParameterList) { | ||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | }); | ||
+ | |||
+ | System.out.println(" | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | ==== E40 Python Example ==== | ||
+ | <code python> | ||
+ | # | ||
+ | import jpype | ||
+ | from jpype import JProxy, JArray, JInt | ||
+ | import jpype.imports | ||
+ | from jpype.types import * | ||
+ | |||
+ | jpype.startJVM(classpath=[' | ||
+ | |||
+ | # Importing the necessary Java classes | ||
+ | from com.ergotech.secs.e39 import E39MessageHandler | ||
+ | from com.ergotech.secs.e40 import E40MessageHandler, | ||
+ | from com.ergotech.transsecs.secs import TransSecsController | ||
+ | from java.lang import Thread | ||
+ | |||
+ | # Create the callback interface using a proxy | ||
+ | class E40CallbackImplementation(E40CallbackInterface): | ||
+ | def prStateChange(self, | ||
+ | print(f" | ||
+ | # Send the new state for the process job to the PLC | ||
+ | # / | ||
+ | # / | ||
+ | |||
+ | def prJobCreate(self, | ||
+ | print(f" | ||
+ | # Indicate that this job is not allocated | ||
+ | # / | ||
+ | # Record the id | ||
+ | # / | ||
+ | |||
+ | def prSetRecipeVariable(self, | ||
+ | if recVarList is not None: | ||
+ | for counter in range(recVarList.size()): | ||
+ | print(f" | ||
+ | |||
+ | def prSetMtrlOrder(self, | ||
+ | # Set the order in which process jobs should be processed | ||
+ | pass | ||
+ | |||
+ | def prCommandCallback(self, | ||
+ | print(f" | ||
+ | cmds = [' | ||
+ | # First indicate which process job the command is being executed on | ||
+ | # / | ||
+ | |||
+ | if prCmdParameterList is not None: | ||
+ | for counter in range(prCmdParameterList.size()): | ||
+ | print(f" | ||
+ | |||
+ | # Get the index of the command | ||
+ | cmdId = cmds.index(prCmd) | ||
+ | # / | ||
+ | |||
+ | # Instantiate the callback | ||
+ | E40Callback = E40CallbackImplementation() | ||
+ | |||
+ | # Main Python code | ||
+ | print(" | ||
+ | |||
+ | controller = None | ||
+ | while controller is None: | ||
+ | Thread.sleep(50) | ||
+ | controller = TransSecsController.findController(" | ||
+ | |||
+ | try: | ||
+ | E39MessageHandler.addMessageHandler(controller.getControllerName()) | ||
+ | E40MessageHandler.addMessageHandler() | ||
+ | except Exception as e: | ||
+ | print(e) | ||
+ | |||
+ | # Register the callback | ||
+ | E40ServiceWrapper.getInstance().registerCallback(E40Callback) | ||
+ | |||
+ | print(" | ||
+ | |||
+ | </ | ||
+ | ==== E94 ==== | ||
+ | |||
+ | Provides a model of a " | ||
+ | |||
+ | === E94 Service Wrapper === | ||
+ | |||
+ | The E94 Service Wrapper provides access to control the flow of E94, however there are no actions required by the tool controller to manage a control job. | ||
+ | |||
+ | === E94 Callback Interface === | ||
+ | |||
+ | The E94 Callback Interface provides notification of activity from the host. A sample implementation of the interface is provided below. The tool control system should implement as many of the methods are required to progress the Control Job through the tool. Each of the control job actions acts on the underling Process Jobs. | ||
+ | |||
+ | <code javascript> | ||
+ | // create the callback interface. | ||
+ | var E94Callback = new E94CallbackInterface() { | ||
+ | |||
+ | // objID is the ID of the control job | ||
+ | // cntrlJob is the control job instance. | ||
+ | |||
+ | cjStart : function (objID, cntrlJob) { | ||
+ | // Host has sent the CJStart Message | ||
+ | |||
+ | }, | ||
+ | |||
+ | cjPause : function (objID, cntrlJob) { | ||
+ | // Host has sent the CJPause Message | ||
+ | }, | ||
+ | |||
+ | cjResume : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjResume Message | ||
+ | }, | ||
+ | |||
+ | cjCancel : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjCancel Message | ||
+ | }, | ||
+ | |||
+ | cjDeselect : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjDeselect Message | ||
+ | }, | ||
+ | |||
+ | cjStop : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjStop Message | ||
+ | }, | ||
+ | |||
+ | cjAbort : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjAbort Message | ||
+ | }, | ||
+ | |||
+ | cjHOQ : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjHOQ Message | ||
+ | }, | ||
+ | |||
+ | cjCreate : function (objID, cntrlJob) { | ||
+ | // Host has sent the cjCreate Message | ||
+ | }, | ||
+ | |||
+ | cjStateChange : function (objID, oldState, newState) { | ||
+ | // The control job has changed states. | ||
+ | // specification and the defined constants in ControlJob | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== E87 ==== | ||
+ | |||
+ | Provides control of a carrier. | ||
+ | |||
+ | === E87 Service Wrapper === | ||
+ | |||
+ | The E87 Service Wrapper provides access to control the flow of E87. Because there are many paths through the tool, E87 must provide for all these options, however, a particular tool is unlikely to require all the features. | ||
+ | |||
+ | < | ||
+ | e87ServiceWrapper = E87ServiceWrapper.getInstance(); | ||
+ | // mark the carrier as arrived... | ||
+ | e87ServiceWrapper.carrierArrived(carrier.getCarrierId(), | ||
+ | |||
+ | // set the slot map. This slot map and the host slotmap will match | ||
+ | carrier.setSlotMap(slotMap); | ||
+ | if ( carrier.getSlotMapStatus().getIntValue() != Carrier.SlotMapE87State.SLOT_MAP_VERIFICATION_OK.getSlotmapE87StateId() ) { | ||
+ | System.out.println (" | ||
+ | } | ||
+ | |||
+ | // start processing the carrier | ||
+ | e87ServiceWrapper.accessCarrier(carrier.getCarrierId(), | ||
+ | wait500(); | ||
+ | // carrier access is complete | ||
+ | e87ServiceWrapper.accessCarrier(carrier.getCarrierId(), | ||
+ | // ending access is not the same as the carrier being ready to unload. | ||
+ | e87ServiceWrapper.setLoadPortTransferState(1, | ||
+ | wait500(); | ||
+ | // when unloading starts (manual or auto) transition to " | ||
+ | e87ServiceWrapper.setLoadPortTransferState(1, | ||
+ | // | ||
+ | // could also be the " | ||
+ | // | ||
+ | // carrier has departed | ||
+ | e87ServiceWrapper.carrierDeparted(carrier.getLoadPortId(), | ||
+ | </ | ||
+ | |||
+ | The most commonly used methods to manage an E87 carrier are contained in the Facade interface: | ||
+ | <code java> | ||
+ | package | ||
+ | |||
+ | |||
+ | import com.ergotech.secs.SecsException; | ||
+ | import com.ergotech.secs.SecsFormat00; | ||
+ | import com.ergotech.secs.e39.InvalidStateTransitionException; | ||
+ | import com.ergotech.secs.e87.E87ServiceWrapper.CMStatus; | ||
+ | import com.ergotech.vib.exceptions.BadParameterException; | ||
+ | |||
+ | |||
+ | |||
+ | /** This implements the E87 services. It is normally called from E39. */ | ||
+ | public interface E87ServiceWrapperFacadeInterface { | ||
+ | /** Creates the load port object for the specific id. | ||
+ | * @param loadPortId the id of the load port to create | ||
+ | * @param readyForService true if the load port is ready for service, otherwise false. | ||
+ | * If this parameter is true then the load port will transition to "IN SERVICE" | ||
+ | * and so to "READY TO LOAD" as soon as it is created. | ||
+ | * @return a new LoadPort | ||
+ | * @throws BadParameterException thrown if a load port with the given id already exists. | ||
+ | */ | ||
+ | public void createLoadPort(int loadPortId, boolean readyForService)throws BadParameterException; | ||
+ | |||
+ | /** This service shall associate a CarrierID to a load port and shall cause | ||
+ | * the load port to transition to the RESERVED state. | ||
+ | * @param portId the port id where the carrier is expected. | ||
+ | * @param carrierId the expected carrierID. | ||
+ | * @return CMStatus information concerning the result of the service | ||
+ | */ | ||
+ | public CMStatus bind ( int portId, String carrierId); | ||
+ | |||
+ | |||
+ | /** This service cancels a CarrierID to load port association and shall cause | ||
+ | | ||
+ | * @param loadPortId the portID for which to cancel the load port to carrier | ||
+ | * association. | ||
+ | * @param carrierId the CarrierId for which to cancel the load port to carrier | ||
+ | * association. | ||
+ | * @return information concerning the result of the service | ||
+ | */ | ||
+ | public CMStatus cancelBind ( int loadPortId, String carrierId ); | ||
+ | |||
+ | /** This service shall Cancel the current carrier related action, and the | ||
+ | * production equipment shall return the carrier to the unload position | ||
+ | * of the load port. | ||
+ | * @param carrierId the carrierID to cancel | ||
+ | * @param portId the PortID where the carrier object is located. | ||
+ | * parameter is not required if the carrier object has previously been | ||
+ | * instantiated. | ||
+ | | ||
+ | */ | ||
+ | public CMStatus cancelCarrier ( int portId, String carrierId); | ||
+ | |||
+ | /** This service shall Cancel the current carrier related action, | ||
+ | * and the production equipment shall return the carrier to the unload | ||
+ | * position of the load port. | ||
+ | * @param portId any carrier that exist on the load port specified shall be | ||
+ | | ||
+ | * @return information concerning the result of the service | ||
+ | */ | ||
+ | public CMStatus cancelCarrierAtPort ( int portId ); | ||
+ | |||
+ | /** Create a carrier. | ||
+ | * @throws BadParameterException thrown if a Carrier with the given ID already | ||
+ | * exists. | ||
+ | * @throws SecsException thrown if the properties list contains a slot map | ||
+ | * or a content map who's size does not match the capacity of the carrier. | ||
+ | */ | ||
+ | public Carrier createCarrier (String carrierId, int loadPortId, | ||
+ | |||
+ | /** Stores the callback object. | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public void registerCallBack(E87CallbackInterface callback); | ||
+ | |||
+ | /** Attempt the state transition on the port. The port is not checked for | ||
+ | * validity and an attempt to call this method on an invalid port will cause | ||
+ | * a null pointer exception. | ||
+ | */ | ||
+ | public void setLoadPortTransferState(int port, int stateTransition) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** Return the transfer state of the port. The port is not checked for | ||
+ | * validity and an attempt to call this method on an invalid port will cause | ||
+ | * a null pointer exception. | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public int getLoadPortTransferState(int port); | ||
+ | |||
+ | /** Attempt the state transition on the port. The port is not checked for | ||
+ | * validity and an attempt to call this method on an invalid port will cause | ||
+ | * a null pointer exception. | ||
+ | */ | ||
+ | public void setLoadPortAccessState(int port, int state) throws InvalidStateTransitionException, | ||
+ | |||
+ | /** Returns the current access state of the port. The port is not checked for | ||
+ | * validity and an attempt to call this method on an invalid port will cause | ||
+ | * a null pointer exception. | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public int getLoadPortAccessState(int port); | ||
+ | |||
+ | /** | ||
+ | * Change the carrier access status. | ||
+ | | ||
+ | | ||
+ | | ||
+ | * The carrier is not checked for validity and an attempt to access an invalid | ||
+ | * carrier will result in a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException thrown if the access attempt is invalid | ||
+ | * @throws SecsException thrown if the status is an invalid request. | ||
+ | */ | ||
+ | public void accessCarrier(String carrierID, Carrier.CarrierAccessE87State state) throws InvalidStateTransitionException, | ||
+ | |||
+ | /** Request to put the port in service. | ||
+ | * validity and an attempt to call this method on an invalid port will cause | ||
+ | * a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public void requestInService(int port) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** Request to put the port in service. | ||
+ | * The port is not checked for validity and an attempt to call this | ||
+ | * method on an invalid port will cause a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public void requestOutOfService(int port) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** | ||
+ | * The application will invoke this when a carrier has arrived at a given port, | ||
+ | * after it has read the carrier id. | ||
+ | * | ||
+ | * @param carrierId | ||
+ | * @param port The load port. The port is not checked for validity and an | ||
+ | | ||
+ | | ||
+ | * @param readOK the carrier id read is valid. | ||
+ | * @param bypassReadId if this is true, the carrierID and readOK flags | ||
+ | | ||
+ | | ||
+ | * @return 0:verified, 2:waiting for host proceed (or cancel), 3: duplicate id | ||
+ | * @throws InvalidStateTransitionException | ||
+ | * @throws BadParameterException | ||
+ | */ | ||
+ | public int carrierArrived(String carrierId, int port, boolean readOK, boolean bypassReadId, | ||
+ | |||
+ | /** When the carrier arrives, the LoadPort may already be in the " | ||
+ | * This method will check the current state of the load port. If it is not in " | ||
+ | * the transition 6. If that transition is invalide, the method will throw. | ||
+ | * | ||
+ | * @param loadPort the load port on which to execute the transition. | ||
+ | * @throws InvalidStateTransitionException thrown if load port transition 6 is not a valid transition. | ||
+ | */ | ||
+ | public void conditionalLoadPortTransition6(LoadPort loadPort) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** When the carrier departs, the LoadPort may not be in the " | ||
+ | * This method will check the current state of the load port. If it is not in " | ||
+ | * the transition 6. If that transition is invalide, the method will throw. | ||
+ | * | ||
+ | * @param loadPort the load port on which to execute the transition. | ||
+ | * @throws InvalidStateTransitionException thrown if load port transition 6 is not a valid transition. | ||
+ | */ | ||
+ | public void conditionalLoadPortTransition8(LoadPort loadPort) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** Execute transition21 to indicate that the carrier has departed. | ||
+ | * carrier instance. | ||
+ | * Set the carrier to null to indicate that it has departed. | ||
+ | * The port is not checked for validity and an attempt to call this | ||
+ | * method on an invalid port will cause a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public void carrierDeparted(int port, String carrierId ) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** | ||
+ | * The port is not checked for validity and an attempt to call this | ||
+ | * method on an invalid port will cause a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException | ||
+ | * @see com.ergotech.secs.e87.E87Interface# | ||
+ | */ | ||
+ | public void carrierDeparted(int port) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** Cancel the carrier at the port. | ||
+ | * The port is not checked for validity and an attempt to call this | ||
+ | * method on an invalid port will cause a null pointer exception. | ||
+ | * @throws InvalidStateTransitionException | ||
+ | */ | ||
+ | public void cancelCarrier(int port) throws InvalidStateTransitionException; | ||
+ | |||
+ | /** Returns all carriers | ||
+ | * @return | ||
+ | */ | ||
+ | public Carrier[] getAllCarriers(); | ||
+ | |||
+ | /** Return the carrier instance for the ID, or null if the carrier does not exist. | ||
+ | * | ||
+ | * @param carrierId the carrier id | ||
+ | */ | ||
+ | public Carrier getCarrier ( String carrierId ); | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | === E87 Callback Interface === | ||
+ | |||
+ | The E87 Callback Interface provides notification of activity from the host. A sample implementation of the interface is provided below. The tool control system should implement as many of the methods are required to progress the carrier through the tool. | ||
+ | |||
+ | < | ||
+ | var E87Callback = new E87CallbackInterface() { | ||
+ | |||
+ | |||
+ | | ||
+ | //Host has requested to cancel carrier notification. | ||
+ | }, | ||
+ | | ||
+ | //Host has requested to cancel the carrier. | ||
+ | }, | ||
+ | bind : function (portID, carrierID) { | ||
+ | // The host has sent a carrier bind message. | ||
+ | }, | ||
+ | | ||
+ | // The host has sent a cancel carrier message for the given port. | ||
+ | }, | ||
+ | | ||
+ | // The host has sent a carrier release message. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a carrier read tag request. | ||
+ | // locationId the id for the location of the carrier. | ||
+ | // carrierId the carrierID ofthe carrier. Either the locationID or the carrier ID must be used. | ||
+ | // dataSeg Indicates a specific section of the data | ||
+ | // dataSize Indicates the number of bytes to read | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a cancel all carrier out message. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a change service status message. | ||
+ | }, | ||
+ | | ||
+ | // The Host has canceled its previous carrier out message. | ||
+ | }, | ||
+ | | ||
+ | // Host has requested a carrier out | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a reserve at port message. | ||
+ | }, | ||
+ | | ||
+ | // The Host has canceled its previous bind message. | ||
+ | }, | ||
+ | | ||
+ | // request to instantiate a carrier | ||
+ | }, | ||
+ | | ||
+ | // The Host has canceled its previous reserve at port message. | ||
+ | }, | ||
+ | | ||
+ | // request to recreate a carrier. | ||
+ | }, | ||
+ | | ||
+ | // request to change the access mode for the port . Modes are MANUAL =0 or AUTO = 1 | ||
+ | }, | ||
+ | | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a carrier read tag request. | ||
+ | // locationId the id for the location of the carrier. | ||
+ | // carrierId the carrierID ofthe carrier. Either the locationID or the carrier ID must be used. | ||
+ | // dataSeg Indicates a specific section of the data | ||
+ | // dataSize Indicates the number of bytes to read | ||
+ | // data the data to write | ||
+ | public void carrierTagWriteData(String locationID, String carrierID, String dataSeg, int dataLength, String data) throws CallbackException; | ||
+ | |||
+ | }, | ||
+ | | ||
+ | // carrier ID has been verified by the host | ||
+ | }, | ||
+ | | ||
+ | // slot map for the carrier has been verifed by the host | ||
+ | }, | ||
+ | | ||
+ | // slot map and carrier have been verifed by the host | ||
+ | }, | ||
+ | | ||
+ | // an E87 alarm has been set or cleared | ||
+ | }, | ||
+ | | ||
+ | // An E87 State has changed | ||
+ | // stateModel will be one of the following indicate which state model has changed state. | ||
+ | // 1: LoadPortTransferStateMachine | ||
+ | // 2: Carrier ID | ||
+ | // 3: Carrier Slot Map | ||
+ | // 4: Carrier Accessing State | ||
+ | // 5: Access Mode (Manual/ | ||
+ | // 6: Load Port Reservation. | ||
+ | // 7: Load Port Carrier Association | ||
+ | // The state will be a valid state for the provided state model | ||
+ | }, | ||
+ | | ||
+ | // Carrier creation. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a new capacity for the carrier. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a new content map for the carrier. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a new slot map for the carrier. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a new substrate count for the carrier. | ||
+ | }, | ||
+ | | ||
+ | // The Host has sent a new usage for the carrier. | ||
+ | // Usage is equipment defined, examples: " | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ | ||
+ |