Frequently Asked Question
Unlike in Python Idle where global and local namespaces are the same thing, in HIL SCADA Macro scripts global and local namespace are divided. This means that when you define variable or function it won't put them in global namespace (and accidentally overwrite something inside global namespace with the same name) instead they are in widget local namespace.
Problem description
Let's see how it works in practical example. If you define some function a() in local namespace, and want to use it in another function b():
You will get the error similar to this one:
[MACRO EXECUTOR] Error occurred! Widget 'Button' macro error: Traceback (most recent call last): NameError: name 'a' is not defined
This is one of restrictions of HIL SCADA. Functions can't be called by other functions defined in the same macro script, as they are not aware of each other.
Workarounds
1. Using Panel initialization
The best option to overcome this is to define all functions inside panel initialization script. All function and variables defined in init script are placed inside the global namespace.
This way it will successfully call the function b(), and print "a" in the Message Log.
2. Defining functions as global inside the widget
The second option is somehow simpler, but is not according to best Typhoon practices. Here is how will it look like:
If you decide to use this option, be careful not to override already existing function definitions.
3. Nesting the whole macro code inside the function
The last option is a bit more complex, but is allowing you to avoid need to use global function. Here is how it look:
In this approach we are defining new helper function button(), so we can use its local namespace. As function button() has well defined local namespace, it is possible for functions inside it to call each other. This means that function b() will be able to see function a() inside outer function.
To find more about global variables, please check this FAQ.