Examples and Best Practices for the CODESYS Trace Scripting API
CODESYS Scripting from CODESYS Trace
The following examples are intended as a supplement to the automatically generated API documentation from CODESYS Scripting to CODESYS Trace.
Creating a Trace
You can use the CODESYS Trace Scripting API to create a new Trace.
myApplication = projects.primary.find("Device", "PLC Logic", "Application")[0]
traceObject = trace.create(myApplication, "MyTraceName")
A task named Task must already exist here. If it does not exist, then this assignment throws a ValueError.
traceObject.task_name = "Task"
In the script, you can specify in which task the newly created trace should be executed.
myApplication = projects.primary.find("Device", "PLC Logic", "Application")[0]
traceObjectWithTaskSet = trace.create(myApplication, "NameOfMySecondTrace", "MainTask")
assert traceObjectWithTaskSet.task_name == "MainTask"Finding and Verifying an Existing Trace
To find an existing trace, you can use the project.find method.
For all other objects of the IScriptObject type, .is_trace_object equals FALSE.
foundObjects = projects.primary.find("Device", "PLC Logic", "Application", "MyTraceObject")
expectedTraceObject = foundObjects[0]
assert expectedTraceObject.is_trace_object, "Could not find trace object with the expected name"
Adding and Modifying Trace Variables
The add_variable() method is a simple method to add a new ScriptTraceVariable and set its properties during creation.
myTrace = projects.primary.find("Device", "PLC Logic", "Application", "MyTraceObject")[0]
addedVariable = myTrace.add_trace_variable(variableName="PLC_PRG.a1",
graphColor= 0xff000000,
graphType=GraphType.LINES,
activateMaxWarning=True,
maxWarningArea=9.0,
maxColor= 0xffff0000)
addedVariable.enabled = False
for i in range(2,11):
newVariable = myTrace.variable_list.add()
newVariable.variable_name = "PLC_PRG.a"+str(i)
newVariable.graph_type = GraphType.LINES_CROSSES
assert len(myTrace.variable_list) == 10Modifying the ScriptTrace Variable List
Removing a specific ScriptTrace variable
In the following code snippet, a variable with the specified name is first found and then removed from the ScriptTraceVariableList.
def remove_variable_by_name(traceObject, variableName):
index_to_remove = -1
for variable in traceObject.variable_list:
if variable.variable_name == variableName:
index_to_remove = traceObject.variable_list.index_of(variable)
break
if index_to_remove != -1:
traceObject.variable_list.remove(index_to_remove) Modifying the Recording Settings
Setting the resolution (ms/µs) of the trace recording
The following code snippet is based on the "Creating a Trace" snippet.
traceObject.resolution = Resolution.MicroSeconds
Use Resolution.MilliSeconds if you want recording based on milliseconds.
Setting the recording condition
The following code snippet is based on the "Creating a Trace" snippet.
traceObject.record_condition = "PLC_PRG.bDoRecord"
Setting a comment
The following code snippet is based on the "Creating a Trace" snippet.
traceObject.comment = "This trace records the ..."
Setting the AutoStart option
The following code snippet is based on the "Creating a Trace" snippet.
traceObject.auto_start = True
Setting the option to record only in every n-th cycle
The following code snippet is based on the "Creating a Trace" snippet.
traceObject.every_n_cycles = 10
Diagrams and Their Variables
Creating one ScriptTrace diagram with all ScriptTrace variables
The following script is an example for creating a simple diagram where all variables are used.
First, a ScriptTrace object and some ScriptTrace variables are created.
traceObject = projects.primary.find("Device","PLC Logic","Application","Trace")[0]
assert traceObject.is_trace_object
for i in range(5):
traceObject.add_trace_variable(variableName="PLC_PRG.a"+str(i))
Next, a ScriptTrace diagram is created and then all ScriptTrace variables are added.
traceDiagram = traceObject.diagrams.add()
for traceVar in traceObject.variable_list:
traceDiagram.add_diagram_variable(traceVar)Creating one ScriptTrace diagram per ScriptTrace variable
The following Python method takes one ScriptTrace object and adds a diagram per ScriptTrace variable.
def one_diagram_per_variable(traceObject):
assert traceObject.is_trace_object
for traceVar in traceObject.variable_list:
diagram = traceObject.diagrams.add(traceVar)
diagram.name = traceVar.variable_name
Copying the Settings of a ScriptTrace Diagram
The following script shows how to modify and copy the settings of a ScriptTrace diagram.
traceObject = projects.primary.find("Device","PLC Logic","Application","Trace")[0]
assert traceObject.is_trace_object
# apply settings for the first diagram
traceObject.diagrams[0].y_axis.mode = AxisScaleMode.FixedLength
traceObject.diagrams[0].y_axis.range = 10.0
traceObject.diagrams[0].y_axis.color = 0xffee0000
traceObject.diagrams[0].y_axis.draw_grid = True
traceObject.diagrams[0].y_axis.grid_color = 0xffee0000
traceObject.diagrams[0].tickmark_fixed_spacing = True
traceObject.diagrams[0].tickmark_fixed_distance = 5.0
traceObject.diagrams[0].tickmark_fixed_subdivisions = 4
# copy the settings from the first diagrams to all other diagrams
for i in range(1,len(traceObject.diagrams))
traceObject.diagrams[i].y_axis.copy_from(traceObject.diagrams[0])
Online Handling of Trace
Downloading and starting Trace
The following code snippet finds the Trace trace of the Application application, downloads it, and starts it.
proj = projects.open(r"<Path to the project file>")
app = proj.find("Device", "PLC Logic", "Application")[0]
with online.create_online_application(app) as onlineapp:
traceObject = proj.find("Device", "PLC Logic", "Application", "Trace")[0]
onlineapp.login(OnlineChangeOption.Never, True)
onlineapp.start()
editor = traceObject.open_editor()
editor.download()
editor.start()Saving the trace to a file
The following code snippet is based on the "Downloading and starting Trace" snippet.
A trace must be stopped before it can be saved. This can be done either by reaching the trigger condition or by an explicit call of stop().
It is assumed that a trace is already running.
editor.stop() editor.save(r"<File path to csv file>")
Querying various information about the trace recording
The following code snippet is based on the "Downloading and starting Trace" snippet.
It is assumed that a trace is already running.
print("Packet State: {}".format(editor.get_packet_state()))
print("Trace started at {} (absolute timestamp)".format(editor.get_trace_start_timetamp()))Trigger Handling
Configuring a Boolean trigger
traceObject = proj.find("Device", "PLC Logic", "Application", "Trace")[0]
traceObject.trigger_variable = "PLC_PRG.bVar"
traceObject.trigger_edge = TriggerEdge.Positive
traceObject.post_trigger_samples = 20
The trigger level is required only for numeric trigger variables. However, it is good coding style to explicitly set the trigger to None.
traceObject.trigger_level = None
Configuring a numeric trigger
traceObject = proj.find("Device", "PLC Logic", "Application", "Trace")[0]
traceObject.trigger_variable = "PLC_PRG.iTemperature"
traceObject.trigger_edge = TriggerEdge.Positive
traceObject.post_trigger_samples = 20If the trigger variable is of type REAL or LREAL, then the trigger level can also be specified as a floating-point number (for example, 80.5).
traceObject.trigger_level = 80
Waiting for the trigger and saving recorded data
The following code snippet is based on the "Downloading and starting Trace" snippet and "Configuring a * trigger".
triggerstate = editor.get_trigger_state()
while triggerstate != TriggerState.TriggerReached:
system.delay(200)
triggerstate = editor.get_trigger_state()
editor.save(r"<File path to csv file>")Querying timestamp information after reaching the trigger
The following code snippet is based on the "Downloading and starting Trace" snippet and "Configuring a * trigger".
print("Trigger reached at {} (absolute timestamp)".format(editor.get_trigger_timetamp()))
print("Trigger reached at {}".format(editor.get_trigger_startdate()))
print("Trace was running {}ms until trigger has been reached".format(editor.get_trigger_timetamp() - editor.get_trace_start_timetamp()))Resuming trace recording after reaching the trigger
The following code snippet is based on the "Downloading and starting Trace" snippet and "Configuring a * trigger".
editor.reset_trigger()
Device Trace
Creating a DeviceTrace
myDevice = projects.primary.find("Device")[0]
devicetrace = trace.create(myDevice, "DeviceTrace")Querying the current trace recordings on the device
The following code snippet is based on the "Creating a DeviceTrace" snippet.
traceObject = projects.primary.find("Device", "DeviceTrace")[0]
For application traces, the result of get_online_traces contains only traces of the application.
# traceObject = projects.primary.find("Device", "PLC Logic", "Application", "Trace")[0]
editor = traceObject.open_editor()
for tracepacket in editor.get_online_traces():
print(tracepacket)Uploading an existing trace as DeviceTrace
The following code snippet is based on the "Creating a DeviceTrace" snippet.
traceObject = projects.primary.find("Device", "DeviceTrace")[0]
editor = traceObject.open_editor()
editor.upload_to_device_trace("CpuCoreLoad")