Gateway Project Script Library Scope

I'm cleaning up some ad-hoc scripting and moving them to Project Library functions. As an example, on every instance of a trend I have buttons that do functions such as change chart between real time/hist, toggle pens on and off, and change the mode between zoom and x-trace. I successfully wrote these as project library functions in one project, simply passing the chart object to the function.

I probably should have originally used this as an inheritable function, but somewhat past that point I imagine.

My question, if I want this project library to be useable in other projects on the gateway, is it plausible to move the library to a gateway script project? The functions don't really need gateway scope as they aren't interacting with tags or other gateway objects. Is that a misuse of the gateway scripting project or is that an intended use as well? The docs mostly reference gateway scoped functions, so I don't want to do something inefficient. Am I better served to just copy the function to each project as needed. I dont anticipate the functions needing to change at this point.

Less a misuse, and really just not a use. The gateway scripting project is for scripts where there is no project context available (such as tag value change events).

For scripts that are calling from Vision Client Scope, the scripts must be available in the project that the component is running in.

Another, potential, working solutions where you don't want to add an inheritable project to the chain, would be to use system.util.sendRequest() where you can call to a specific project.

1 Like

This sentence suggests you might be misunderstanding the way the project library works.

You can mentally imagine referencing a script from the project library as Ignition automatically copying and pasting whatever code you have there into wherever you're calling the script.
Putting something into the project library doesn't do anything about your execution scope - the only thing that matters is where you call the script from.

If you have some shared utility scripts you want to use in multiple projects, that's a great candidate for project inheritance - make an inheritable 'parent' project, put your common library code there, and make it the parent of your 'downstream' projects. Then they will automatically get an implicit copy of the library code, and you don't need to redefine it in each project.

3 Likes

Yes, I understand that distinction. What I wasn’t sure of, is that possible after the fact? I have about a dozen projects in this gateway. Many were provided by another integrator. What I'm trying to do is minimize the ad hoc scripting that exists directly on a button (for example) for common functions into the project library. But since these projects were not set up initially as inherited from a master project template, is it feasible to now define a master with a common project library, and then change the existing projects to inherit the project library from the master?

I knew that a gateway script project was accessible to all projects. Just do not know if after the fact I can transform the existing projects into inhertiable from a new master templated project.

Yes. Just make sure you've "sent" all necessary resources into the right place in your inheritance tree before you change any current project inheritance settings.

After you change inheritance, you can then remove the overrides in leaf projects for resources that should be retrieved via inheritance.

Possible inspiration:

Note the comments on ensuring only well-tested resources are placed in universe or any of the *_common projects.

3 Likes

Tip: you can right click a library script module, select export and then “send to project” to send it to another project. I use this a lot to code a new function, then when it’s ready, send it to a lib project that contains my reusable functions

4 Likes

If you're talking about the project selected as the gateway scripting project, then this makes the libraries defined in this project (and its inherited projects) available to use in the gateway scope, like in tag change scripts. However it does not mean that projects that don't inherit this project will be able to access those libraries; they won't. Projects that need access to these script libraries will still need to inherit from it

4 Likes

Thanks to everyone’s insight, I have successfully moved most of the scripting to appropriate Inherited Project Library and Gateway Scripts (where applicable).

I have one left, and I’m torn how to segregate it. Every project interrogates a client tag for Alarm Filter/Route when a general fault acknowledge event is executed, and then uses this filter to acknowledge the appropriate alarms through a system query as well as set a tag to the appropriate PLC.

I’m thinking that I should keep the client Read in the event script on the client, and call an external script passing the acknowledge tag path and ack filter, but where should I construct that script for optimal performance? Or do I just leave it where it is in the client? I’m unsure of the performance hit ,if any, of the system acknowledge, which I presume is handled on the gateway.

hasPermissive = event.source.Permissive
dispFilter = system.tag.readBlocking(['[client]Alarm_Display_Filter'])[0].value
displist=list(dispFilter.split(","))
if hasPermissive and "xxxxx" in displist:
	stringlist = [str(alarm.getId()) for alarm in system.alarm.queryStatus(state=["ActiveUnacked"],displaypath=displist)]
	system.tag.writeBlocking(['[xxxxx]Fault_Ack'], [1])
	system.alarm.acknowledge(stringlist,'')

Also, currently, this is on a Operator Button, and as operators do, they tend to repeatedly press it, not realizing that it does no better to repeatedly press, but that it does fire that query multiple times, and that’s not only inefficient for repeated queries, but also generates a nuisance system log that the tag is no longer available to acknowledge. Is there a clean way to disable multiple firings of this script? I know I could launch a timer, but prefer not to do so. I could set an additional tag in the PLC that resets on time, and use that tag to inhibit this script, but wanted to see if there’s a better way within Ignition.