Gateway Timer Event Scripts in 8.0.6

Ok, thanks.

Real quick though. I didn’t define anything in global (an inheritable project).

global (an inheritable project), was created for me upon upgrading from 7 to 8. It then arrogated to itself all previously shared resources, and started running them in ways that were not previously intended.

I want my gateway event scripts to run on one computer only, the gateway. I want them to run on the gateway because I want them to always run, independent of whether a particular program is on, and I want them to run only one time. The timer scripts I wrote are Gateway Event Scripts.

From the 8.0 manual, emphasis mine:

“Gateway Event Scripts Overview
Gateway Event Scripts are scripts that run directly on the Gateway. They are useful because they always run, regardless if any sessions or clients are open. They also provide a guaranteed way to make sure only a single execution of a particular script occurs at a time, as opposed to placing a script in a window, as there could be multiple instances of the window open at a given point of time.”

It sounds like what I need to do, as a user who had Gateway Event Scripts running on the gateway in 7.9, is to remove them from global. Then create a non-inheritable project, called, for instance, Gateway Events and create a Gateway Timer event and store my Gateway event scripts there.

Otherwise my Gateway event scripts won’t run directly on the Gateway, will regard whether sessions or clients are open, and will not guarantee only a single execution of a particular script occurs. Correct?

Gateway Event Scripts will run on the gateway regardless of what project they are defined in.

I’m pretty sure 7.9 didn’t allow you define Gateway Event Scripts on the global project. Shared script libraries, sure, which your Gateway Event Scripts from various projects could have all been calling.

So I’m not sure how you could have ended up with any Gateway Event Scripts (timer, startup, shutdown, etc…) defined on the “global” project that gets created on upgrade unless you added them.

2 Likes

Hi Kevin,

So, now that it seems like I have a handle on the original problem, I’d just like to bump the error I was getting on starting up a project in Designer flagging a ‘collision in system.util.initialize’ Seems like this is a separate, independent issue. Any idea what could be causing it?

Also, I tried creating a gateway event in a project with no inheritors, and do not see it run, even when the gateway timer event is enabled. What could be preventing execution?

As for gateway behavior on ‘global’, it’s entirely possible I misapprehended the workflow. From what I recall, every project had access to the gateway events and shared libraries in designer. Indeed, I’m not aware of a way to affect gateway events in designer other than opening a specific project. Though I could configure those events and libraries from any project in designer, the changes, since they were tied to the gateway, propagated across all projects. They ran once and only once, regardless of how many projects I had open.

It sounds like you’re telling me there was a global project in 7.9 that I was somehow unaware of? Is that the case? I don’t recall one.

If it’s marked as ‘Inheritable’ it will not execute gateway events, among other things. Even if there aren’t currently any projects inheriting it.

It was more of an implicit thing in 7.9. Anything that had a global scope (shared script libraries, for example), resided in an internal global project. This project became explicit in 8.0 with the new project system.

There’s a blurb in the upgrade guide about how 7.9 -> 8.0 upgrade affects the project system: https://docs.inductiveautomation.com/display/DOC80/Ignition+8+Upgrade+Guide#Ignition8UpgradeGuide-ProjectInheritance&“global”upgradelogic

Oh, and we’re tracking the “system.util.initialize” thing already. It’s low priority and shouldn’t really affect you. It’s not something you’ve caused.

It’s a (minor, inconsequential) programming error on our part - nothing you’ve done, and nothing that’ll affect you.

That’s really not how it worked in 7.9. Any ‘gateway event script’ that you made in 7.9 would run exactly once…per project. If you make two gateway startup scripts, in two separate projects…you’re going to end up with two scripts running on gateway startup. The same principle applies in 8.0, there’s just now an explicit global project.

The gateway event scripts are gateway scoped, in that they execute on the gateway, but the actual definition is still per-project, and there is no “singleton” nature to them.

Thanks for clearing up the system.util.initialize error.

That’s surprising to me, because that’s not the behavior I got out of our gateway timer. It worked according to my (mistaken) understanding during 7.9, and after the upgrade, it’s behavior changed dramatically. We run several projects on several different terminals, but only one alarming terminal. The alarming project looked at a tag to time its klaxon, the tag was set by a Gateway timer event. Every other project could see the (implicit) global project storing the gateway timer, but our timekeeping was correct. That is, only one computer/project (I’d assumed it was the gateway program on the gateway server) was running the event script and setting/resetting the ‘metronome’ tag.

Can you explain how I lucked into getting that behavior in 7.9 vs 8.0?

Also, how, specifically, do I get back to a situation wherein when I define a gateway event, that event triggers once independent of any projects running or not. Is that possible? I much preferred maintaining our code in one shared codebase, and having a super-project capable of executing events without regard for the current status of clients. It allowed me to centralize non-standard behaviors for components and prevented needless duplication of effort in writing and maintaining code across multiple projects. It also helped other users understand what was going on in a project.

I really don’t like that I now have several dozen lines of identical code in two identical components in two windows in the same project, to get behavior that USED to be ‘standard trigger property bound to metronome tag’, with the metronome tag named in such a way as to point the user to the shared library and global events.

It really sounds like you’re conflating the idea of a project running with a client being open. They are totally independent. Non-inheritable projects are always running their gateway scoped things. This was true of projects in 7.9 as well.

Define common script library code in ‘global’. Make a non-inheritable child project to define your gateway event scripts in. You can reference the script library from ‘global’ all you want. This project will be running and executing its gateway-scoped event scripts regardless of whether any clients are open or not.

I was indeed my understanding that nothing a project was set up to do (in the local scope) would happen unless a client had the project open or a designer had it in play mode, and that the project had no effect outwards on the global scope, without an explicit call to do so. A call which would not have executed if the project were not active in a client or designer.

All projects I have are currently child projects that inherit ‘global’.

It sounds like I want an inheritable project in which I define a timer event. And a project to inherit that other project, that does nothing, no windows, not client accessible, but as an inheritor will automatically call the timed event. Correct?

I’m going to steer clear of doing anything with ‘global’, as it is currently set to be inherited by all projects. I’d prefer to offload functionality from ‘global’ into other inheritable function(s), until I’m left with a stable system. And then work on understanding how to utilize 'global’s inheritance by my client-facing projects.

Nope.
Gateway scoped things (tags, SFCs, alarm pipelines, transaction groups, gateway event scripts, scheduled reports, webdev resources, etc) are always executing[1]. Only resources specifically highlighted as belonging to the “client” (ie, client event scripts, or naturally any Vision windows or templates) are running on that local client.

[1] when applicable - this is where things get a bit more complicated with the inheritance model in 8.0, but basically the only complication is that “runnable” resources (transaction groups, scheduled reports, gateway event scripts) will not execute if their defining project is marked as ‘inheritable’ - but, any non-inheritable child project will run (a copy of) those resources.

Another very important distinction, or thing to be aware of: in 7.9, there is an actual, unique, special, “global” project. When you upgrade to 8.0, we make a new project and call it “global” and set up the inheritance tree for you - but there’s nothing “special” about that project, anymore (other than it being marked inheritable automatically). You can make your own inheritable “parent” or “whatever” or “mycorp” project and have it act the same way, unlike 7.9, where you were stuck to the somewhat arbitrary set of resources we called “global” or allowed you to put into the ‘shared’ section.

I think the underlying problem is that it makes no sense to have events defined in an inheritable project. They won’t run in that project. If multiple projects inherit from it, they’ll each run those events.

v7.9 didn’t run any events in an inheritable project because the only “implied” inheritable project was the gateway global scope, and events simply didn’t exist for it. Similarly, v7.9 couldn’t double up the execution of a script because projects couldn’t inherit them from other projects.

Inheritance shouldn’t exist for events. Inheritable projects should not even show the event editors in the navigation tree.

Set the separate parent/child pair and it works.

This sounds a lot like what I’ve been trying to say. I’ve now got two programs to run one gateway script. One of which is inheritable and does nothing but define the event, and one that inherits and does nothing but runs the event in the background. It seems like a needless division of labor.

And while I appreciate the added flexibility having the option to create many inheritable projects, PGriffith, the restricted nature of what I could do with the global project in 7.9 helped keep me from getting in trouble, even if (especially because?) I wasn’t 100% on what I was actually doing behind the scenes. Rails are limiting, but ‘going off the rails’ is a good thing in very few circumstances. Maybe it was my fault for not fully understanding what I was not allowed to do and what was changing in the upgrade. As it is, I think I’m sorted, on this issue at least.

Sorry, final question.

What is the difference between a gateway event that is defined in an inheritable project but can only be run by inheritor projects, and just having those inheritors run client scoped events? Client scoped events don’t run unless a client has the project open?

Client scoped events run per client, on the client - so if you have a client startup script, it will run every time a client starts that’s running project ‘x’. If you have a client timer script, it will be running at ‘y’ rate for every client running project ‘x’.

Gateway scoped events are “triggered by”, and run on, the gateway - so no matter how many clients you launch, you will generally only expect to see one such event. (I believe we manually kick off ‘gateway startup scripts’ if you make a change that would impact your startup script, for ease of testing).

Ok, so, I’m back to square one, since this entire thread - unless I grossly misunderstood the advice I was given and the behavior I witnessed and eventually controlled - has been telling me that a Gateway scoped event in 8.0 will not run unless a project inherits it, and it will be run as many times as there are inheritor projects.

The behavior you’re describing is my naive understanding of gateway scoped events prior to the upgrade.

Yes, that’s correct. My statement above:

was specifically about the difference between gateway and client events, since you asked about the difference between gateway events and client events.

Putting it another way:
A “Gateway Startup Script” will run once, when the project starts up, during gateway startup.
If you have an inheritable project, and it has a gateway startup script defined, every inheriting project will then have that gateway startup script - which will run once, when the project starts up, during gateway startup. Per each project.

A “Client Startup Script” will run each time any Vision client (running the right project) starts up. You can ‘inherit’ client startup scripts, too - they’re still a project level resource.

What you’re asking for, indirectly, just doesn’t exist - there is no way to configure a “global”, singleton resource that will only ever be defined and run once per gateway lifecycle and cannot be duplicated via project manipulation. Nothing changed in that regard from 7.9 to 8.0; you couldn’t do it in 7.9, and you can’t do it in 8.0.

That’s only true if the Gateway Event Script lives in an inheritable project.

Gateway Event Scripts defined in any standalone or leaf project will also run.

So the ‘correct’ way to get a gateway project to run (that is, dependent only on the on and running status of the gateway, in the minimal necessary package) is create a project with no inheritors and define the event.

A project with inheritors will not run the event, but only its inheritors will, however many they happen to be. A project without will run the event, and only one time.

The default upgrade process linked literally every project through inheritance to a newly created global project, ensuring that every gateway event would be run by every currently existing project, simultaneously. We only had one timer to that point, but if we’d defined several this would have been a nightmare.

Perhaps modify your installer/upgrader for future versions to package Gateway Events into a newly created uninherited project, and leave it to the user how many projects he or she would like to link, and thereby how many simultaneous instances of the same code they’d like to execute.

This is where things get confusing. AFAIK 7.9 didn’t allow you to define a timer event script in the special global project, so there’s no way the upgrade process would result in the post-upgrade “global” project in 8.0 having a timer event script defined.

Yes, this is what would be necessary if 7.9 allowed gateway event scripts to be defined on the special global project. This is what we did with run-always SFCs and alarm pipelines.

Precisely. v7.9 doesn’t have any event script resources that could possibly end up in the conversion-generated global project.

@byrnep: somewhere along the way, after you imported your v7.9 gateway backup, you added event scripts to the global project (or other inheritable project), or you changed a project with event scripts to be inheritable. Upgrade from v7.9 wouldn’t get you into the mess you’re in.

1 Like