Gateway Tag Change Script not finishing

I have a Gateway Tag Change script that seems not to finish. I know it starts, but it seems to fail when calling a project script in a the Script Library that does some recursive browseTags. My intent is have this script called on gateway startup, and I know it works because I’ve run the code in the Script Console and it works.

I’m really stumped … here’s some cut-n-paste:

–Tag Change–

def AddTags(path, udttype, data):
	#get all the tags that have the given UDT type under the given path
	tagList = project.alarmlist.manualSearch(path, udttype)

	# strip of the last part of the tag path and make that the alarm name
	# the first part then becomes the path
	for tag in tagList:
		lastDel = tag.path.rfind("/")
		strLen = len(tag.path)
		alarmName = tag.path[lastDel+1:strLen]
		path = tag.path[0:lastDel]
		row = [path,alarmName,'default','color(255,255,255,255)','color(0,0,0,255)','','','','default','color(250,214,138,255)','color(0,0,0,255)','','',udttype]
		
		data.append(row)

logger = system.util.getLogger("alarmlist")

if newValue.value:
	data = [] # create an empty list to fill with tag paths
	
	logger.info("Start Alarm Tag Refresh")
	system.tag.writeSynchronous('GUI/Test','Starting')
	
	AddTags("[default]/.","DigitalAlarm",data)
	logger.info("DigitalAlarm Tag Refresh Complete")

	AddTags("[default]/.","AnalogAlarm",data)
	logger.info("AnalogAlarm Tag Refresh Complete")

	AddTags("[default]/.","AnalogLockoutAlarm",data)
	logger.info("AnalogLockoutAlarm Tag Refresh Complete")
	
	almDataSet = system.tag.read('GUI/Alarm Tags')
	headers = system.dataset.getColumnHeaders(almDataSet.value)
	dataset = system.dataset.toDataSet(headers, data)	
	system.tag.writeSynchronous('GUI/Alarm Tags',dataset)
	logger.info("Tag Refresh Complete")

	system.tag.writeSynchronous('GUI/Alarm Tag Refresh',0)
	system.tag.writeSynchronous('GUI/Test','Complete')
else:
	system.tag.writeSynchronous('GUI/Test','Nothing Done')

– Script Library –

# Define the search as a function. This makes recursion easier.
def manualSearch(initPath, alarmType):
    # Create a result set of just tags.
    tagSet = system.tag.browseTags(parentPath = initPath, tagPath = '*', udtParentType=alarmType, recursive=False)
     
    # Create a result set of UDT instances.
    udtSet = system.tag.browseTags(parentPath = initPath, tagPath = '*', tagType='UDT_INST', recursive=False)
	 
    # Create a result set of just folders. We'll iterate over this set and call browseTags() again for the results.                                             
    folderSet = system.tag.browseTags(parentPath = initPath, tagPath = '*', tagType = 'Folder', recursive=False)

    # Iterate through folders...                                  
    for folder in folderSet:    
        # Recursively start the process over again until we run out of folders.
        tagSet+=manualSearch(folder.fullPath,alarmType)
    
    # Iterate through UDT's ...                                  
    for udt in udtSet: 
		# Recursively start the process over again until we run out of folders.
		tagSet+=manualSearch(udt.fullPath,alarmType)
    
    # Return the list of tags.
    return tagSet

Does initPath contain the tag provider as well?

Because this project script is being called from a gateway scope event the system.tag.browseTags() needs a tag provider. To me this explains why it was working from the script console but not at the gateway level.

Yes, as you can see in the calls to AddTags, they all include a tag path that includes the provider ([default]/.):

If I remember correctly, you cannot use “default” for the tag provider in any Gateway scripting. “default” is defined for each project, not for the gateway. You need to replace this with the name of the tag provider you want this script to check.

I don’t know … the Tag Browser under All Providers doesn’t have a provider for the my gateway other than default.

Any errors in the gateway logs when you run the scripts? Another thing to consider is the number of tags you have in your tag provider. Could it be the scripts hasn’t finished?

I missed this before …

com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last): File “”, line 24, in File “”, line 3, in AddTags NameError: global name ‘project’ is not defined

Do I need an import project statement I wonder?

Yes, when calling project scripts from gateway scope events I always import project to avoid these types of errors.

Whoops, sorry about that. It looks like I didn’t remember correctly! I was mixing up “[~]” (which means the default provider for the project) with “[default]”…

And more specifically, the import only works if placed inside my AddTags function.

That is a normal side-effect of the legacy python scoping rules that apply to gateway event scripts. Consider putting all of your gateway event code in functions in project script modules and have all of the events be just a one-line call to the corresponding function. You’ll have modern scope rules in the script module.

Useful.

Now I can’t seem to make the Gateway Startup script system.tag.write the tag to trigger the Gateway Tag Change script.

It’s just one thing after another.

okay, so like you said @pturmel … bury everything in the project script and then just call it with a one-liner.

That’s gives me what I want both on setting the refresh tag and on gw startup.

Thanks!