I have recently moved a project script to a Tag Change Gateway Script so I could have it run without any clients open. But I’ve run into an issue that makes absolutely no sense “global name … not defined” and this was with globally declared functions I’ve tested the exact code within the script console and there were no issues. what do I make of this?
This is the simplified code with the error with proprietary code stripped out:
Yes. This is happening because there is a bug in Ignition with Gateway scripts. Gateways scripts still have the old legacy scoping enabled by default.
The bug is this: variables defined in the outermost scope can not be see by functions. In this case you have the generateReportPart variable that holds a function and you try to execute it in the generateReport function. This is perfect legal Python – but as I said the error occurs because of the scoping bug in Gateway scripts.
Define functions in a project script module. Call those functions as project.someName.functionName(). In the designer, navigate to Project => Scripts => Script Library.
I’ve got the same issue happening. I have a script in my project script library called Test:
def testScript()
print "script executed"
If I assign the following script to a button click, the script executes:
project.Test.testScript()
Now, I create a tag UDT, and on one member of that UDT, put the same code in a tag change event script:
project.Test.testScript().
I create an instance of that UDT, and change the value of the tag with the tag change event script associated with it. The script does not execute, and the diagnostic log tells me “global name ‘project’ is not defined”.
Tag Change Event Scripts are not the same thing as a Tag Event Value Change Script. That’s the point. Things attached to the tag definition or a UDT definition are outside the project system and therefore have no access to any project.* scripts.
Look at the gateway event scripts under the project’s “Scripting” section of the designer nav tree. Scripts defined there are part of the project, not the tag, and therefore have access to project script modules.
That makes sense, thanks for the explanation. My application really needs the script attached to the UDT definition, so perhaps I need to think about it differently. To avoid derailing this thread, I’ll start a new one and describe what I’m trying to achieve more fully.
site_path = "foobar" # redacted
logger.info(site_path)
switched_off |= set(al.replace("Site", site_path) for al in switched_off)
switched_on |= set(al.replace("Site", site_path) for al in switched_on)
I get this error: com.inductiveautomation.ignition.common.script.JythonExecException: NameError: global name 'site_path' is not defined
But I also get the log entry with site_name’s value…
Is it something with the generator expression ?
What am I missing ?
I removed things before that snippet, that compute switched_on and switched_off, and a tag write after it, but nothing in that block has been modified/removed expect for the value of site_path, which was a literal too.
I’ll try moving things in the project library, but… still… wth ?
the log line works properly, and the very next doesn’t !
Putting it in a project library seems to fix the issue, but, really…
Why is the variable just fine on one line, then undefined on the next ?
That’s not just weird. Weird was fine, but we left weird a few thousand miles back.
I've just had this same issue on a scheduled gateway script that was just calling a project script (v8.1.22). It only errored once and has been fine every other time.
Is there anything I can do to make this more robust? Or maybe a way to re-run a scheduled script if it fails?
I'm so glad I've stumbled onto this thread, as I was about to lose my mind.
I guess the same applies to python iterators running native in gateway event scripts?
result = system.db.runNamedQuery('Recipe/Select_UnknownMaterials', parameters)
unknownMaterials = list(result.getValueAt(i, y) for i in range(result.getRowCount()) for y in range(result.getColumnCount()))
Would end up with 'NameError: global name 'result' is not defined'.
What I don't understand however is why when moving the script into the project library it magically works?
But thats most likely just me failing to understand the full extend of legacy scope vs standard scope.