Transaction Group -> Write wandshake on success does not update if sequential successes happen

I want to trigger an event script off of the writing of a new row into a database table that is running through the tag historian. I have this set up to only evaluate when values have changed, and I found the "Write handshake on success" section at the bottom of Trigger and implemented it. It works for everything except for sequential success writes; I expected the Timestamp on the tag to refresh even if the value remains the same, but as far as I can tell it will not update at all unless I change the value to something else (which ironically forces it right back to the "To value:" value because the tag has to be a member of this group.

Is there a way to fix this / a standard alternative way to trigger an event script on a database row insert?

The expectation is that whatever is triggering the transaction group writes a 0 to the handshake tag after receiving the handshake, normally after a cool down period(3x poll rate) to prevent race condition issues with Ignition.

What is your tag script doing that requires you tie it to an insert into the DB?

You may need to manually script your transaction to perform the script action you originally wanted AND insert into the db, using a Gateway Tag Change Event.

This was a demo script just printing a log, but the goal was to run a script to evaluate some conditions based on the most recent entries.

You may need to manually script your transaction to perform the script action you originally wanted AND insert into the db, using a Gateway Tag Change Event.

I don't really understand this -- the tag historian transaction group is just watching some externally controlled tags, and my entire goal is to get a Gateway Tag Change Event script to function, but I don't want to manually watch every single tag in the group, so I figured I'd watch the write success handshake tag.

Also, if I write that tag back down to 0 won't it trigger the Tag Change Event handler? That seems like a recipe for an infinite loop.

What is really causing my problem is that the timestamp on the tag that is being written as "Write handshake on success" apparently does not update its timestamp when it recieves the same value that it already has. I can trigger the Gateway Event Tag Change script against the timestamp, but it isn't budging. And since the tag for "Write handshake on success" apparently has to be part of the transaction group, if I pull that back down I end up with an infinite loop.

I'm suspicious that the better approach would be to have whatever is remotely controlling the tags control the transaction with a dedicated trigger tag.

If you check for the previous value to be null or 0 and the current value to be 1, then no, no loop will happen when you set it back to zero.

if not event.previousValue.value and currentValue.value:
    # Do your stuff here

Pretty commonly used on tag changes to catch the transition from low to high. You can also make use of the initialChange value as well.
Also, use a Gateway Tag Change Event, not a tag Value Changed event. The first can spawn a dedicated thread, the second runs on a limited thread pool, and you risk locking the tag system as a whole.

" Tags to watch for change - Select either All tags, or Custom to select one or more tags from the dropdown, to monitor for value changes." - From the documentation. You should be able to omit the handshake tag from the monitored tags list so it doesn't re-trigger your transaction.

You already are, in a transaction group. No difference between specifying them there or in a Gateway Tag Change Event. You can specify a list of tags or even a list of folders to monitor, and it will trigger off of any of them.

I could put an event handler on upwards of a hundred tags, or I could catch it in one place -- I'm aiming for the one catch.

" Tags to watch for change - Select either All tags, or Custom to select one or more tags from the dropdown, to monitor for value changes." - From the documentation. You should be able to omit the handshake tag from the monitored tags list so it doesn't re-trigger your transaction.

This is good, thank you. I can exclude the one success tag so that it doesn't cause the infinite loop, although tbh it is baffling to me that it is not held out by default. That said, the interface is problematic -- if I add new tags to the group I will have to make sure to add them to the watchlist. I'd rather use a blacklist than a whitelist here, since the default is "yes please trigger off my tags in this group".

I think you are going to be disappointed. To get a reliable handshake, you need signals to only go one way, and you need all source values to hold still while the transaction is in progress.

Ryan suggests having the PLC reset the success boolean, but that means that boolean is written from two direction. You can't fix the resulting races just by waiting a little longer, as comms problems don't have a definitive time limit. (3x the poll rate just makes it appear to be reliable, until it isn't.)

If you want something reliable, you will:

  • Monitor for significant changes in the PLC, not in Ignition, but only while trigger and ack are false,
  • Copy all values to a holding buffer when that occurs,
  • Then set the trigger,
  • Ignition monitors just that trigger, captures all the values with OPC Read, then sets the acknowledgement,
  • PLC turns off the trigger when it sees the acknowledgement, and finally
  • Ignition turns off the ack when the trigger goes away.
3 Likes

So I suppose I should elaborate on my use case a little:

I have a Tag Historian that I use to track a significant (and changeable) number of setpoints and switches and relays and things of that ilk. I also have an externally managed "tool state" system that has enumerated state tuples that represent legal and known configurations for our system. Should an operator manually deviate from one of the legal states (which is something that happens intentionally from time to time), we want them and the rest of the system to be aware. So I have a routine that determines a priori if the system is in any legal states regardless of how it got there.

Now, instead of running my system state checker on a timer, I wanted an intelligent hook where it would run when needed, and "whenever the Tag Historian writes a new row" was a great spot to hook it in, hence my attempt to hook a Tag Change Event script into the handshake that occurs when a row is written successfully.

I wanted this because it was a single point hook that didn't require fundamentally changing anything else about our control scheme. Handshaking of those individual controls is handled elsewhere, and I am actually completely uninterested in "handshakes" for everything I have spoken about here other than because I needed a spot to hook in to trigger an event script at the time I thought was most appropriate. Unfortunately because of where I was trying to hook, and the strange behavior I found there, we had to talk about handshakes a lot.

In the end, my current (functional) solution is to remove the write handshake tag from being a trigger tag for the transaction group (this really should default to not be included, and/or that should be a blacklist not a whitelist) in combination with not allowing it to trigger too quickly.

Sounds like you need a gateway tag change event with a list of trigger tags.

If you need something more declarative, consider my Integration Toolkit's BulkScript Tag Action.

That would be one way to do it, except for the fact that the tags keep changing and I want 1 hook not N hooks.

This makes no sense. A gateway tag change event is one "hook".

I suppose then that what I want is one hook with a single barb, one that is not subject to change.

I don't understand. Everything in your transaction-group is subject to change in a designer. What sort of solution do really want?

(Perhaps you need to use the SDK to make a module with your desired functionality.)

I have the transaction groups updated dynamically by script whenever my external configurations are recompiled. Annoying that I had to reverse engineer the XML and use the legacy interface, but I made it work.

What I wanted for this particular system was just "an event trigger that fires whenever my Trigger driven Transaction Group writes a new row".

Perhaps you need an insert trigger procedure in your database.

Anyways, I'm not a fan of Rube Goldberg code contraptions.

How might the database notify Ignition if we went that route? That would be the traditional way to do it, but this is entirely for the operators to be aware of what they are doing and so it needs to be accessible to the HMI codebase.

Is Ignition not already one of Rube's greatest proteges?

Ignition would have to poll for it.

No, I don't think so. The defining characteristic of a Rube Goldberg machine is unnecessary complexity. Ignition itself is a remarkably streamlined collection of data flows and visualizations thereof, with an architecture that leads designers to generally efficient applications.

That you've built exotic infrastructure to programmatically build transaction groups so you can leverage the trigger capabilities of those transaction groups to initiate a series of analyses boggles my mind. Especially since the trigger capabilities of transaction groups are a subset of the trigger capabilities of gateway events, which can run your analysis code directly.

Mind-Boggling

3 Likes

That you've built exotic infrastructure to programmatically build transaction groups so you can leverage the trigger capabilities of those transaction groups to initiate a series of analyses boggles my mind. Especially since the trigger capabilities of transaction groups are a subset of the trigger capabilities of gateway events, which can run your analysis code directly.

Ah, see, I have already built the infrastructure and one of the things I want to do is hook on transaction group writes, because I already have what I need otherwise. I did not do all of that for this purpose, that would indeed be mind boggling, considering how much Ignition resists my will. Programmatically defining members of Gateway Tag Change Event scripts would have been fine too, but as far as I know this is not an option.

In fact I built the entire external configuration management system so that I could keep our PLCs' controls and associated metadata fresh and available in Ignition. Believe it or not, Ignition is only a fraction of our control system. Currently the most central component, but less so every day as our capabilties around it grow.

Maybe a Rube Sherman ecospace then?

2 Likes

I'll put that on my short list for possible names for the whole system

1 Like