Gateway Script global name not defined

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:

def generateReport():
	return generateReportPart()
	
def generateReportPart():
	return ''

report = generateReport()

and the error:

line 2, in generateReport NameError: global name 'generateReportPart' is not defined

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.

I wrote about the scope change in Ignition here: http://www.perfectabstractions.com/blog/new-scripting-features-in-ignition-77-part-1#standard-scoping

The best thing to do is write all your code in a project library function and then simply execute that function in your Gateway script.

2 Likes

Dead Thread I know, but I am having the exact same issue. What do you mean by a project library function?

Define functions in a project script module. Call those functions as project.someName.functionName(). In the designer, navigate to Project => Scripts => Script Library.

Perfect!! Thank you.

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”.

Any ideas?

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.