This GEM Python host example uses the code generated from TransSECS using the Java/Javascript deployment option.

Most of the complexity is removed by the definitions you created in TransSECS.

The python wrapper uses the JPype library to directly interface with the Java code.

For the tool,copy the GEMToolRuntime.jar from the TransSECS GEMTool project into the build folder

For the host,copy the GEMHostRuntime.jar from the TransSECS GEMHost project into the build folder

The sample, demonstrates all the features required to build a tool. It can be extended to include any features available in the Java host or tool.

Here's the code sample from the python wrapper archive:

#!/usr/bin/python3
import jpype
from jpype import JProxy
import jpype.imports
from jpype.types import *
 
jpype.startJVM(classpath=['.', './GEMToolRuntime.jar'])
 
from com.ergotech.util import SimulationManager
from deploy.GEMTool import EquipmentController, HostCommandReply
from com.ergotech.transsecs.secs.gem import GemHandler
from com.ergotech.vib.valueobjects import DoubleValueObject, LongValueObject, StringValueObject
 
import time
import random
 
# Configuration
port = 5010
deviceid = 1
online = 1  # Online state
remote = 1  # Remote state
 
# Initialize the equipment controller
SimulationManager.getSimulationManager().setSimulating(False)
equipment = EquipmentController()
host.setPort(port)
host.setDeviceId(deviceid)
host.init()
host.start()
 
# Set initial VID values
host.setIntValue(33006, online)  # Go Online
host.setIntValue(33005, remote)  # Allow Local-Remote transition
 
# Get the gemHandler for setting VID values using names
gemHandler = controller.getGemHandler()
gemHandler.setValue("MDLN", StringValueObject("Test 123  456"))
gemHandler.setValue("WaferCount", LongValueObject(1))
 
# Example of setting OnlineOfflineState using VID name
gemHandler.setValue("OnlineOfflineState", LongValueObject(1))
 
# Get data source container for accessing VIDs (this may need additional jars/classes)
# container = DataSourceContainer.getRootContainer().getContainer("GEMTool")
 
# Event and Alarm setup
gemEvent = gemHandler.getServerForName("CEID.Completed")
alarm = gemHandler.getServerForName("ALID.TemperatureProblem")
 
# Host Command START Notifier
class HostCommandSTARTNotifier:
    def messageReceived(self, status, message):
        print(f"Message Received in Host Command START Notifier: {message}")
        hostCommand = message
        command = hostCommand.getCommand()
        print(f"Host Command is {command}")
        if command != "START":
            print("Host Command Rejected")
            self.sendErrorResponse(1)  # 1 = bad command
            return
 
        print("Host Command START Accepted")
        self.sendOKResponse()
 
    def sendErrorResponse(self, hcack):
        connection = GemIDConnection.createConnection("GEMTool")
        response = connection.getController().getMessageBean("HostCommandReply")
        response.setHCACK([hcack])
        response.sendMessage()
 
    def sendOKResponse(self):
        connection = GemIDConnection.createConnection("GEMTool")
        response = connection.getController().getMessageBean("HostCommandReply")
        response.sendMessage()
 
# Register the notifier
notifier_proxy = JProxy("com.ergotech.transsecs.secs.host.MessageNotifier", inst=HostCommandSTARTNotifier())
controller.registerForReceiveNotification("HostCommandSTART", notifier_proxy)
 
print("Simple GEM Tool set up on Port 5010 and Device ID 1")
 
# Main loop to change some SVID values and trigger alarms/events periodically
cycles = 0
waferCount = 0
alarm_set = False
 
while True:
    cycles += 1
    # Update process variables
    gemHandler.setValue("ProcessTemperature", DoubleValueObject(random.random() * 10 + 120.0))
    gemHandler.setValue("GasFlow", DoubleValueObject(random.random() * 1 + 1))
 
    # Increment the wafer count every 20 cycles
    if cycles % 20 == 0:
        waferCount += 1
        gemHandler.setValue("WaferCount", LongValueObject(waferCount))
 
    # Trigger the event every 120 cycles
    if cycles % 120 == 0:
        gemEvent.setBooleanValue(True)
        print("Event Triggered")
    else:
        gemEvent.setBooleanValue(False)
 
    # Check for alarm conditions
    temperature = gemHandler.getServerForName("VID.ProcessTemperature").getFloatValue()
    if temperature > 128.5 and not alarm_set:
        alarm.set()
        alarm_set = True
        print("Alarm Triggered")
    elif alarm_set:
        alarm.clear()
        alarm_set = False
        print("Alarm Cleared")
 
    # Wait for next cycle
    time.sleep(0.5)