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)