Implementing a GEM equipment¶
This package can be used to create a GEM equipment implementation.
This is done by subclassing the secsgem.gem.equipmenthandler.GemEquipmentHandler
class:
import secsgem.gem
import code
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
h = SampleEquipment("127.0.0.1", 5000, False, 0, "sampleequipment")
h.enable()
code.interact("equipment object is available as variable 'h', press ctrl-d to stop", local=locals())
h.disable()
Using your own name¶
To use your own modelname and version for S1F14 reply you can override the secsgem.gem.handler.GemHandler.MDLN
and secsgem.gem.handler.GemHandler.SOFTREV
members of the GemHandler:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.MDLN = "gemequp"
self.SOFTREV = "1.0.0"
Adding status variables¶
A status variable can be added by inserting an instance of the secsgem.gem.equipmenthandler.StatusVariable
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.status_variables
dictionary:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.status_variables.update({
10: secsgem.gem.StatusVariable(10, "sample1, numeric SVID, SecsVarU4", "meters", secsgem.secs.variables.U4, False),
"SV2": secsgem.gem.StatusVariable("SV2", "sample2, text SVID, SecsVarString", "chars", secsgem.secs.variables.String, False),
})
self.status_variables[10].value = 123
self.status_variables["SV2"].value = "sample sv"
Alternatively the values can be acquired using a callback by setting the use_callback parameter of the constructor to True:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.sv1 = 123
self.sv2 = "sample sv"
self.status_variables.update({
10: secsgem.gem.StatusVariable(10, "sample1, numeric SVID, SecsVarU4", "meters", secsgem.secs.variables.U4, True),
"SV2": secsgem.gem.StatusVariable("SV2", "sample2, text SVID, SecsVarString", "chars", secsgem.secs.variables.String, True),
})
def on_sv_value_request(self, svid, sv):
if sv.svid == 10:
return sv.value_type(value=self.sv1)
elif sv.svid == "SV2":
return sv.value_type(value=self.sv2)
return []
Adding equipment constants¶
An equipment constant can be added by inserting an instance of the secsgem.gem.equipmenthandler.EquipmentConstant
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.status_variables
dictionary:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.equipment_constants.update({
20: secsgem.gem.EquipmentConstant(20, "sample1, numeric ECID, SecsVarU4", 0, 500, 50, "degrees", secsgem.secs.variables.U4, False),
"EC2": secsgem.gem.EquipmentConstant("EC2", "sample2, text ECID, SecsVarString", "", "", "", "chars", secsgem.secs.variables.String, False),
})
self.status_variables[20].value = 321
self.status_variables["EC2"].value = "sample ec"
Alternatively the values can be acquired and updated using callbacks by setting the use_callback parameter of the constructor to True:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.ec1 = 321
self.ec2 = "sample ec"
self.equipment_constants.update({
20: secsgem.gem.EquipmentConstant(20, "sample1, numeric ECID, SecsVarU4", 0, 500, 50, "degrees", secsgem.secs.variables.U4, True),
"EC2": secsgem.gem.EquipmentConstant("EC2", "sample2, text ECID, SecsVarString", "", "", "", "chars", secsgem.secs.variables.String, True),
})
def on_ec_value_request(self, ecid, ec):
if ec.ecid == 20:
return ec.value_type(value=self.ec1)
elif ec.ecid == "EC2":
return ec.value_type(value=self.ec2)
return []
def on_ec_value_update(self, ecid, ec, value):
if ec.ecid == 20:
self.ec1 = value
elif ec.ecid == "EC2":
self.ec2 = value
Adding collection events¶
A collection event can be added by inserting an instance of the secsgem.gem.equipmenthandler.CollectionEvent
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.collection_events
dictionary.
Data values can be added by inserting an instance of the secsgem.gem.equipmenthandler.DataValue
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.data_values
dictionary.
The data values for a collection event can be passed while creating the secsgem.gem.equipmenthandler.CollectionEvent
instance:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.dv1 = 31337
self.data_values.update({
30: secsgem.gem.DataValue(30, "sample1, numeric DV, SecsVarU4", secsgem.secs.variables.U4, True),
})
self.collection_events.update({
50: secsgem.gem.CollectionEvent(50, "test collection event", [30]),
})
def on_dv_value_request(self, dvid, dv):
if dv.dvid == 30:
return dv.value_type(value=self.dv1)
return []
def trigger_sample_collection_event():
self.trigger_collection_events([50])
Adding alarms¶
An alarm can be added by inserting an instance of the secsgem.gem.equipmenthandler.Alarm
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.alarms
dictionary.
The collection events for the alarm must be provided when adding the alarm. For an example see the section above:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.collection_events.update({
100025: secsgem.gem.CollectionEvent(100025, "test collection event alarm set", []),
200025: secsgem.gem.CollectionEvent(200025, "test collection event alarm clear", []),
})
self.alarms.update({
25: secsgem.gem.Alarm(25, "test alarm", "test text", secsgem.secs.data_items.ALCD.PERSONAL_SAFETY | secsgem.secs.data_items.ALCD.EQUIPMENT_SAFETY, 100025, 200025),
})
def set_sample_alarm():
self.set_alarm(25)
def clear_sample_alarm():
self.clear_alarm(25)
Adding remote commands¶
A remote command can be added by inserting an instance of the secsgem.gem.equipmenthandler.RemoteCommand
class to the secsgem.gem.equipmenthandler.GemEquipmentHandler.remote_commands
dictionary.
The collection event and parameters for the remote command must be provided when adding it. For an example see the section above:
class SampleEquipment(secsgem.gem.GemEquipmentHandler):
def __init__(self, address, port, active, session_id, name, custom_connection_handler=None):
secsgem.gem.GemEquipmentHandler.__init__(self, address, port, active, session_id, name, custom_connection_handler)
self.collection_events.update({
5001: secsgem.gem.CollectionEvent(5001, "TEST_RCMD complete", []),
})
self.remote_commands.update({
"TEST_RCMD": secsgem.gem.RemoteCommand("TEST_RCMD", "test rcmd", ["TEST_PARAMETER"], 5001),
})
def on_rcmd_TEST_RCMD(self, TEST_PARAMETER):
print "remote command TEST_RCMD received"