Gateway Timer Event Scripts in 8.0.6

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

To make this bullet-proof, I would add: Changing a project to "inheritable" should be denied if there are any event script resources defined.

1 Like

I’m mostly out of the mess at this point, but I certainly didn’t muck around with ‘global’. Without knowing precisely what it did, it was immediately obvious as something with a lot of importance. Other than pulling my gateway events and moving them off into another project, I’ve left global exactly as I found it, since honestly, other than this one facet of it, I’m still not sure what it is or how to interact with it in a way that makes it an asset and not a liability.

It’s been over two weeks now, memory doesn’t extend back that far in sufficient detail, but I’d be very surprised if I imported my gateway event scripts (from where if not global?) into global and just fired it up. At the very least, it would have been immediately clear to me what to un-do to try fixing the multiple simultaneous execution issue. I’m not the smartest guy but I think I can at least pattern match at that level.

Global was where I found them, and so Global was where I tried executing them.

Perhaps I defined them in such a way in 7.9 that they ended up in global. Some way that is nonstandard, and thus finding my gateway events in global is nonstandard behavior?

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.

Right, but as we've established there was no 'global' project in 7.9. At least as far as anyone without access to the backend of Ignition would have been aware. I had a Gateway Timer event defined. I defined it in 7.9. It ran once, at the rate specified, without reference to client status. This is real and it happened, as defined, for months. However that was done in 7.9, that's what I did. However that changes in 7.9 to 8.0 upgrades, that's what happened. And that was real, and it happened, and behavior changed in ways that were unwanted, and unflagged.

Guys, I don't code this up. I'm telling you the behavior I saw, as completely as I can. It was really really unwelcome. Perhaps I did something 'wrong' but my understanding of the job of commercial software providers is to prevent the possibility of software allowing the user to do anything 'wrong'. The thing to take from this is that there are nonstandard (it took a while for you all to understand and suggest changes so I'm guessing this hasn't come up much) use-cases that can screw up customers. You guys should be figuring out how this happened and preventing it in the future rather than telling me how what I literally saw happen either didn't happen, or couldn't happen, or I should have known to do something different. The issue is fixed, but that it even was an issue is a larger, UX issue.

Do you still have that v7.9 backup? It would be interesting to look at to see what might have happened. For your gateway event to have been running happily in v7.9, it must have been defined in a project.

I do. If it is something that anyone is interested in, I can share that, but frankly, as I told Kevin, there doesn’t seem to be any interest in Inductive’s part about figuring out how a user managed to do something with their software they think should not be possible.

My interest is a program that does what I want, and I’m back to that state, so I’m staying there. I’m not super interested in rolling our software back and forth.

We’re definitely interested in running your backup through the upgrader and seeing if it comes out with gateway script events in the global project somehow. I’ll PM you a dropbox upload link.

1 Like

Awesome, thanks!

Edit: something to look out for, I’ve looked a little closer at our Alarm Page. It also had a message handler, in order to track the user who acknowledged an alarm.

Based on the comments I wrote at the time, I had issues getting a client level handler to attribute the acknowledgement to any user other than the default low level user that runs that client. The alarm terminal is always open under a low-level, no permissions credential, because we want anyone in the facility to be able to read an alarm state, but we don’t want just anyone to acknowledge shelf or silence alarms.

This is all by way of saying the eventhandler was scoped in the project as gateway. However that gateway level event handler did not get promoted to global. Global does not have it, while the alarm page still has the handler available in its own, editable gateway events tab. As far as I know, all other projects that inherit from global have their gateway events tab greyed, and can’t be edited except through the global project.

To summarize, the alarming page, that has been giving these issues, had 2 gateway level events defined, a timer and a message handler. The timer went to global post upgrade while the handler didn’t. The timer then became accessible to every client that inherited global while to the best of my knowledge the handler has not. The global events icon in the alarming page in designer is different than in other inheritors of global, as I can open, create, edit and delete gateway alarms, which I can do in no other global inheriting project I’ve seen so far.

Ok. So.

I disabled the ‘gateway scoped’ message handler in the Alarming page. I changed the Alarming page’s inheritance from ‘global’ to my new ‘Global Event Scripts’ page. I disabled the ‘Global Event Scripts Caller’ page (so that my timer would not run at double time).

I then created a message handler in Global Event Scripts with the same name and code.

When I went to acknowledge an alarm in my page I got the following error:

Gateway script MessageHandlerException, project ‘D3Alarm’, message handler ‘publicAcknowledge’: com.inductiveautomation.ignition.common.script.message.MessageHandlerException: The message handler “publicAcknowledge” could not be found! Check your event script message handlers.

It was set to inherit from a project that had such a handler defined. The relevant code calling the message handler is:

system.util.sendMessage(project = 'D3Alarm',messageHandler = 'publicAcknowledge',payload = {'uuid':uuid,'ackMsg':ackMsg,'user':info[0]}, scope = 'G')

And it was not able to find a 'G’ateway scoped message handler, because the one defined in the project itself was disabled and the one in the inheriting project was somehow not accessible.

As I said, I noticed that in almost all other projects, ‘gateway events’ are greyed and inaccesible by default. Right clicking on Gateway events in such a project gave an option to ‘Override Resource’ which seemingly makes gateway events defineable at the client level, and also seems to supersede any events defined at the gateway (or parent) level!

I also don’t see a way to remove the override. Do these facts imply anything? As it is, I think the safest thing, for this project is:

  1. It’s gateway events are overriden. It is apparently a gateway/parent unto itself
  2. End all inheritances
  3. Move all gateway scoped events that had been defined in parent projects to the alarm page itself

I think the useage most in line with how Inductive wants us to work is to define all gateway events in a parent project, but that seems impossible unless I can remove the override.

We are currently fighting this same issue using Gateway events in an “Inheritable” project in 8.0.15. Is the final solution to create a non inheritable project to move gateway events to?

Thanks,

Frank

I have also noticed that the Gateway Timer event setup as FIXED DELAY does not behave like it did in Ignition 7.9 anymore. From the documentation the FIXED DELAY will make it so that when the timer fires, your script within it will execute for however long it takes. THEN the fixed delay time will start again.

In 8.0.13 I have not been seeing that. If I define a Gateway timer event and set it for 30 seconds and FIXED DELAY on DEDICATED THREAD. Then the script in the timer executes anywhere from 10 to 15 seconds. The event then fires 20-15ish seconds later! What happend to the FIXED DELAY of 30 seconds?