gem300_scripts

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
gem300_scripts [2021/07/12 13:21]
wikiadmin
gem300_scripts [2024/09/19 14:54] (current)
wikiadmin
Line 3: Line 3:
  
 GEM300 standards consist of state models.  This [[https://slideplayer.com/slide/13207475/|Intel transcript]] provides an overview. As you move product, or carriers through your tool the control system must update the current state to ensure that the host can correctly manage tool operation. GEM300 standards consist of state models.  This [[https://slideplayer.com/slide/13207475/|Intel transcript]] provides an overview. As you move product, or carriers through your tool the control system must update the current state to ensure that the host can correctly manage tool operation.
 +
 +Implementation of these standards will require reference to the appropriate standard and state model in the standard.  The implementations will vary based on your needs and the capabilities of the tool.  A wide range of possible scenarios are provide in the SEMATECH document [[https://www.ergotech.com/files/guides/ISMI%20Operational%20Flows%20and%20Scenarios.pdf|300 mm Operational Flowcharts and Scenarios, V. 10]]
 +
 +===== TransSECS implementation =====
 +
  
 In all the TransSECS GEM300 implementations there are two, fundamental part.   In all the TransSECS GEM300 implementations there are two, fundamental part.  
Line 40: Line 45:
 </code> </code>
  
-== E40 Callback Interface ==+=== E40 Callback Interface ===
  
 The E40 Callback Interface provides notification of activity from the host.  There are four methods: The E40 Callback Interface provides notification of activity from the host.  There are four methods:
Line 72: Line 77:
 var E40Callback = new E40CallbackInterface() { var E40Callback = new E40CallbackInterface() {
        
- prStateChange : function (prJob, oldState, newState) {+ prStateChange : function (prJob, oldState, newState ) {
   print ("State Change for " + prJob.getPrJobId() + " From: " + ProcessJob.getStateName(oldState) + " to " + ProcessJob.getStateName(newState));   print ("State Change for " + prJob.getPrJobId() + " From: " + ProcessJob.getStateName(oldState) + " to " + ProcessJob.getStateName(newState));
   // send the new state for the process job to the PLC   // send the new state for the process job to the PLC
-  /E40Modbus/ProcessJobId->setStringValue(prJob.getPrJobId()); +  /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId()); 
-  /E40Modbus/CurrentProcessJobState->setIntValue(newState);+  /GEM300PLC/CurrentProcessJobState->setIntValue(newState);
  },  },
  prJobCreate : function (prJob) {  prJobCreate : function (prJob) {
Line 84: Line 89:
    print ("Job Creation of " + prJob.getPrJobId() + " permitted");    print ("Job Creation of " + prJob.getPrJobId() + " permitted");
    // indicate that this job is not allocated    // indicate that this job is not allocated
-   /E40Modbus/Allocated->setIntValue(0);+   /GEM300PLC/Allocated->setIntValue(0);
    // record the id    // record the id
-   /E40Modbus/ProcessJobId->setStringValue(prJob.getPrJobId());+   /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId());
  },  },
  prSetRecipeVariable : function (prJob, recVarList) {  prSetRecipeVariable : function (prJob, recVarList) {
Line 117: Line 122:
      
   // first indicate which process job the command is being executed on   // first indicate which process job the command is being executed on
-  /E40Modbus/ProcessJobId->setStringValue(prJob.getPrJobId());+  /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId());
   // send the parameters - here we just print them   // send the parameters - here we just print them
   if ( prCmdParameterList != null ) {   if ( prCmdParameterList != null ) {
Line 127: Line 132:
   // get the index of the command   // get the index of the command
   cmdId = cmds.indexOf(prCmd);   cmdId = cmds.indexOf(prCmd);
-  /E40Modbus/PrCmd->setIntValue(cmdId);+  /GEM300PLC/PrCmd->setIntValue(cmdId);
  }  }
   };   };
      
-   + /// START OF MAIN JAVASCRIPT CODE /// 
-/// START OF MAIN JAVASCRIPT CODE /// +print("Register GEM300"); 
-    print("wait for controller THREAD started"); + 
     var controller = null;     var controller = null;
     do {      do { 
         //print("host is still null");           //print("host is still null");  
         Thread.sleep(50); //wait 50 ms         Thread.sleep(50); //wait 50 ms
-        controller = TransSecsController.findController("E40PLCTool");+        controller = TransSecsController.findController("GEM300PLCTool");
     } while (controller == null);     } while (controller == null);
              
Line 151: Line 156:
     print("E40 Registered");     print("E40 Registered");
        
 +   
 +
    
 </code> </code>
Line 166: Line 173:
  }  }
 </code> </code>
-        +==== E40 Python Example ==== 
 +<code python> 
 +#!/usr/bin/python3 
 +import jpype 
 +from jpype import JProxy, JArray, JInt 
 +import jpype.imports 
 +from jpype.types import * 
 + 
 +jpype.startJVM(classpath=['.', './GEMTool.jar']) 
 + 
 +# Importing the necessary Java classes 
 +from com.ergotech.secs.e39 import E39MessageHandler 
 +from com.ergotech.secs.e40 import E40MessageHandler, E40ServiceWrapper, E40CallbackInterface, ProcessJob 
 +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, prJob, oldState, newState): 
 +        print(f"State Change for {prJob.getPrJobId()} From: {ProcessJob.getStateName(oldState)} to {ProcessJob.getStateName(newState)}"
 +        # Send the new state for the process job to the PLC 
 +        # /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId()); 
 +        # /GEM300PLC/CurrentProcessJobState->setIntValue(newState); 
 + 
 +    def prJobCreate(self, prJob): 
 +        print(f"Job Creation of {prJob.getPrJobId()} permitted"
 +        # Indicate that this job is not allocated 
 +        # /GEM300PLC/Allocated->setIntValue(0); 
 +        # Record the id 
 +        # /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId()); 
 + 
 +    def prSetRecipeVariable(self, prJob, recVarList): 
 +        if recVarList is not None: 
 +            for counter in range(recVarList.size()): 
 +                print(f"Host Requested Recipe Variable \"{recVarList.get(counter).getStringValue()}\" on {prJob}"
 + 
 +    def prSetMtrlOrder(self, prCurrentMtrlOrder, prNewMtrlOrder): 
 +        # Set the order in which process jobs should be processed 
 +        pass 
 + 
 +    def prCommandCallback(self, prJob, prCmd, prCmdParameterList): 
 +        print(f"Host Requested \"{prCmd}\" on {prJob} with parameters {prCmdParameterList}"
 +        cmds = ['NONE', 'ABORT', 'STOP', 'CANCEL', 'PAUSE', 'RESUME', 'STARTPROCESS'
 +        # First indicate which process job the command is being executed on 
 +        # /GEM300PLC/ProcessJobId->setStringValue(prJob.getPrJobId()); 
 + 
 +        if prCmdParameterList is not None: 
 +            for counter in range(prCmdParameterList.size()): 
 +                print(f"Host Requested Parameter \"{prCmdParameterList.get(counter).getStringValue()}\" on {prJob}"
 + 
 +        # Get the index of the command 
 +        cmdId = cmds.index(prCmd) 
 +        # /GEM300PLC/PrCmd->setIntValue(cmdId); 
 + 
 +# Instantiate the callback 
 +E40Callback = E40CallbackImplementation() 
 + 
 +# Main Python code 
 +print("Register GEM300"
 + 
 +controller = None 
 +while controller is None: 
 +    Thread.sleep(50)  # wait 50 ms 
 +    controller = TransSecsController.findController("GEM300PLCTool"
 + 
 +try: 
 +    E39MessageHandler.addMessageHandler(controller.getControllerName()) 
 +    E40MessageHandler.addMessageHandler() 
 +except Exception as e: 
 +    print(e) 
 + 
 +# Register the callback 
 +E40ServiceWrapper.getInstance().registerCallback(E40Callback) 
 + 
 +print("E40 Registered"
 + 
 +</code> 
 +==== E94 ==== 
 + 
 +Provides a model of a "Control Job" Control Jobs are created and managed by the host, or on rare occasions by the tool.  Control Jobs contain Process Jobs (E40) which perform that actual processing of product. 
 + 
 +=== 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.  states can be as defined in the E94 
 +        // specification and the defined constants in ControlJob 
 +    } 
 +  
 +
 + 
 +</code> 
 + 
 +==== E87 ==== 
 + 
 +Provides control of a carrier.  Carriers can be entered manually or automatically and can be verified at the tool - for example by reading an RFID tag, or by the host.  The slot map of the carrier can be read by the tool and verified by the host or provided by the host. 
 + 
 +=== 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.  A basic flow, might looks something like this 
 + 
 +<code> 
 +      e87ServiceWrapper = E87ServiceWrapper.getInstance(); 
 +        // mark the carrier as arrived... 
 +        e87ServiceWrapper.carrierArrived(carrier.getCarrierId(), carrier.getLoadPortId(), true, false); 
 + 
 +      // set the slot map.  This slot map and the host slotmap will match 
 +      carrier.setSlotMap(slotMap);  // transition 11 - the host and equipment slot map match. 
 +      if ( carrier.getSlotMapStatus().getIntValue() != Carrier.SlotMapE87State.SLOT_MAP_VERIFICATION_OK.getSlotmapE87StateId() ) { 
 +        System.out.println ("Failed To Verify SlotMap"); 
 +      } 
 + 
 +      // start processing the carrier 
 +      e87ServiceWrapper.accessCarrier(carrier.getCarrierId(), Carrier.CarrierAccessE87State.IN_ACCESS); 
 +      wait500(); 
 +      // carrier access is complete 
 +      e87ServiceWrapper.accessCarrier(carrier.getCarrierId(), Carrier.CarrierAccessE87State.CARRIER_COMPLETE); 
 +      // ending access is not the same as the carrier being ready to unload.   
 +      e87ServiceWrapper.setLoadPortTransferState(1,9);  // transition the load port to "ready to unload" 
 +      wait500(); 
 +      // when unloading starts (manual or auto) transition to "TransferBlocked - 7 
 +      e87ServiceWrapper.setLoadPortTransferState(1,7);  // transition the load port to "ready to unload" 
 +      //carrier.transition21(); // carrier is removed from tool 
 +      // could also be the "cancelBind" service which simply executes transition21 after verifying the carrier and port. 
 +      //e87ServiceWrapper.cancelBind(carrier.getLoadPortId(),carrier.getCarrierId()); 
 +      // carrier has departed 
 +      e87ServiceWrapper.carrierDeparted(carrier.getLoadPortId(), carrier.getCarrierId()); 
 +</code> 
 + 
 +=== 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. 
 + 
 +<code> 
 +var E87Callback = new E87CallbackInterface() { 
 +   
 + 
 + cancelCarrierNotification : function (carrierID) { 
 + //Host has requested to cancel carrier notification. 
 +}, 
 + cancelCarrier : function (portID, carrierID) { 
 +  //Host has requested to cancel the carrier.  We will move to ready to unload. 
 +}, 
 + bind : function (portID, carrierID) { 
 + // The host has sent a carrier bind message. 
 +}, 
 + cancelCarrierAtPort : function (portID) { 
 + // The host has sent a cancel carrier message for the given port. 
 +}, 
 + carrierRelease : function (locationID, carrierID) { 
 + // The host has sent a carrier release message. 
 +}, 
 + carrierTagReadData : function (locationID, carrierID, dataSeg, dataLength, pData) { 
 + // The Host has sent a carrier read tag request. 
 +   // locationId the id for the location of the carrier.  Either the locationID or the carrier ID must be used. 
 +   // 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 
 +}, 
 + cancelAllCarrierOut : function () { 
 + // The Host has sent a cancel all carrier out message. 
 +}, 
 + changeServiceStatus : function (portID, status) { 
 + // The Host has sent a change service status message. 
 +}, 
 + cancelCarrierOut : function (carrierID) { 
 + // The Host has canceled its previous carrier out message. 
 +}, 
 + carrierOut : function (portID, carrierID) { 
 + // Host has requested a carrier out 
 +}, 
 + reserveAtPort : function (portID) { 
 + // The Host has sent a reserve at port message.  We will reserve the port or nack this message. 
 +}, 
 + cancelBind : function (portID, carrierID) { 
 + // The Host has canceled its previous bind message. 
 +}, 
 + carrierNotification : function (carrierID) { 
 +   // request to instantiate a carrier 
 +}, 
 + cancelReserveAtPort : function (portID) { 
 + // The Host has canceled its previous reserve at port message. 
 +}, 
 + carrierRecreate : function (carrierID, propertiesList) { 
 + // request to recreate a carrier.  propertiesList is a SecsFormat00  
 +}, 
 + changeAccessMode : function (newMode, portID) { 
 +  // request to change the access mode for the port .  Modes are MANUAL =0 or AUTO = 1 
 +}, 
 + proceedWithCarrier : function (portID, carrierID, propertiesList) { 
 +}, 
 + carrierTagWriteData : function (locationID, carrierID, dataSeg, dataLength, pData) { 
 + // The Host has sent a carrier read tag request. 
 +   // locationId the id for the location of the carrier.  Either the locationID or the carrier ID must be used. 
 +   // 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; 
 + 
 +}, 
 + carrierIDVerified : function (portID, carrierID, carrier) { 
 + // carrier ID has been verified by the host 
 +}, 
 + slotMapVerified : function (portID, carrierID, carrier) { 
 + // slot map for the carrier has been verifed by the host 
 +}, 
 + carrierIDAndSlotMapVerified : function (portID, carrierID, carrier) { 
 + // slot map and carrier have been verifed by the host 
 +}, 
 + alarmChanged : function (alarmID, isSet) { 
 + // an E87 alarm has been set or cleared 
 +}, 
 + stateChange : function (stateModel, state, portID, carrierID) { 
 +     // 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/Auto) 
 + // 6: Load Port Reservation.  One per port.  Distinguished by port ID. 
 + // 7: Load Port Carrier Association 
 + // The state will be a valid state for the provided state model 
 +}, 
 + createCarrier : function (carrierID, portID, propertiesList, transition) { 
 + // Carrier creation.   propertiesList is a SecsFormat00 representing host-provided properties for the carrier 
 +}, 
 + capacityUpdated : function (carrier, capacity) { 
 + // The Host has sent a new capacity for the carrier. 
 +}, 
 + contentMapUpdated : function (carrier, propertiesList) { 
 +  // The Host has sent a new content map for the carrier.   propertiesList is a SecsFormat00 representing host-provided properties for the carrier 
 +}, 
 + hostSlotMapUpdated : function (carrier, hostSlotMap) { 
 +  // The Host has sent a new slot map for the carrier.  
 +}, 
 + substrateCountUpdated : function (carrier, substrateCount) { 
 +   // The Host has sent a new substrate count for the carrier.  
 +}, 
 + usageChangeRequest : function (carrier, usage) { 
 +  // The Host has sent a new usage for the carrier.  
 +  // Usage is equipment defined, examples: "TEST", "DUMMY", "PRODUCT" 
 + } 
 +
 + 
 +</code> 
  
  • gem300_scripts.1626114098.txt.gz
  • Last modified: 2021/07/12 13:21
  • by wikiadmin