Behavior
The behavior object represents a black box that will include some logic, in form of a python script, that can be used to model the component behavior. The behavior logic will be interfaced using variables that can be connected to other elements.
Variables will be defined inside the 'variable' element by their name, data type (smtk_...), type (input, output, constant or parameter) and optionally public or not.
Attributes
- Name: The name used when referring to this element from other places.
Mandatory children
- step_time: Step time to force the execution of the behavior logic periodically in seconds. If step_time is 0, behavior is executed when any input changes.
- Var: smtk_float
- Type: input
- Default value:
0.0
Optional children
- variable: Behavior variable linked to the python script in order to exchange information.
Selectable child
- script: Python script asset GUID.
- Var: smtk_guid
- Type: constant
- Default value:
<empty>
- File extension: .py
Available Python functionality
Python Libraries
- NumPy
- JSON
Python Classes
- tuple - Sequence type -
(value1, value2)
- dict - Dictionary Mapping type -
{key : value, key2 : value2}
- list - Sequence type -
[value1, value2]
- int - Integer number -
1
- float - Floating point number -
0.0
- bool - Boolean -
True/False
- str - Text -
"Value"
- range - Sequence type -
range(5)
Basic Python functions
- len() - Returns the length of an object.
- iter() - Returns an iterator object.
- print() - Prints to the standard output device.
- abs() - Returns the absolute value of a number.
- max() - Returns the largest item in an iterable.
- min() - Returns the smallest item in an iterable.
- round() - Rounds a number.
- chr() - Returns a character.
- ord() - Returns an integer number from a character.
- hex() - Converts a number to hexadecimal.
Specific methods
- Transform2Euler() - Converts transform in quaternion to transform in RPY angles in radians.
- Transform2Quat() - Converts RPY angles in degrees to quaternion.
- on_{ParamterName}() - Method that is called when a variable of the type parameter is changed.
Reserved variable names
- initialize - smtk_bool - Returns true when workspace loads or reloads a component.
- clock - smtk_float - Time since emulation started in seconds.
- step_time - smtk_float - Used to force the execution of the behavior logic periodically in seconds. If step_time is 0, behavior is executed when any input changes.
Tip
If you are new to Python programming or want to know more, please check out our Academy course on Python.
Behavior structure
When a behavior is added to a component it contains the following code.
if initialize:
# Enter your initialization code here
# It will be executed after resetting the emulation
pass
else:
# Enter your behavior code here
# It will be executed depending on the step_time and input variable changes
pass
Initialize
When the component is loaded to or reloaded in a workspace the reserved boolean variable initialize is True. This can be used to control how the components shall behave when resetting the emulation or to declare and define outputs. For example, to reset an output variable named origin with data type smtk_transform the initialize part could look like this:
if initialize:
# Enter your initialization code here
# It will be executed after resetting the emulation
origin = [0, 0, 0, 0, 0, 0, 1]
else:
# Enter your behavior code here
# It will be executed depending on the step_time and input variable changes
pass
Regular execution
The regular behavior execution can be placed indented after the else:. For example, by using the reserved variables step_time to force execution and clock to change the origin during execution could look like this:
if initialize:
# Enter your initialization code here
# It will be executed after resetting the emulation
origin = [0, 0, 0, 0, 0, 0, 1]
else:
# Enter your behavior code here
# It will be executed depending on the step_time and input variable changes
step_time = 0.1 # Execute the behavior every 100 ms
origin[0] = clock # The X-position of the transform will move along the x-axis with 1 m/s.
Parameter change
For a variable of the type parameter a method can be added that is called when the parameter is changed, this method is declared as def on_{parameter name}(). In the example below two parameters are defined, driver_type and setup_params, when the user changes the driver_type in the workspace the setup_data variable is changed accordingly. This variable can be used in the regular parts of the behavior, as for the example below be used to set up a dictionary, setup_dict, for a communication driver. See the initialization part in the code snippet below.
Note that the variables that need to be accessed in the method need to be defined as globals to be able to use them outside of the local scope.
if initialize:
# Prepare setup telegram
setup_dict = {
'parameters': json.loads(setup_params),
'variables': {
input_variable : {'datatype': 'word', 'size': 1, 'operation': 'write'},
output_variable : {'datatype': 'word', 'size': 1, 'operation': 'read'}
}
}
# The code below is executed when the driver type is selected
def on_driver_type():
global driver_type, setup_params
if driver_type == "opcua_client":
setup_params = '{"url": "opc.tcp://localhost:4840"}'
elif driver_type == 's7protocol' or driver_type == 'allenbradley_logix':
setup_params = '{"ip": "192.168.0.1"}'
else:
setup_params = '{}'
Print to log
To print to the workspace log use the method print()
. By using a argument of type string this will show up in the workspace log. By also using a second parameter dest and set it to LOG_ERROR
it will display it as an error.
if initialize:
# Prints text to the workspace log
print("Initializing component.")
else:
if some_error_occured:
# Prints text in red to the workspace log and indicates error.
print("Error in component", dest="LOG_ERROR")


Tip
There is an Academy course that will guide you through the steps required to edit the behavior of a component.