Tag Value Changed script not triggering in UDT

Hi all, wondering if you could provide some help with the issue I’m facing.

Implementation: I’ve created a Reference Tag to the System→Gateway→CurrentDateTime in a UDT definition. I’ve then created a Script under Value Events → Value Changed.

Behavior: When I do this with a generic Ref Tag in my Tag Provider, it works as expected. However, when I update my UDT to have an identical Ref Tag, the Value Change script doesn’t fire. I’ve verified that both Ref Tag values are reading the time second by second as the System’s clock increments.

[TagProvider]TestTags/GlobalTimerReferenceTag → works

[TagProvider]TestTags/TestUDTInstance/GlobalTimerReferenceTag → doesn’t work

Other Notable Behavior: I’ve noticed that if I have multiple Ref Tags defined identically in the same provider, they’ll all work (i.e. [TagProvider]TestTags/GlobalTimerReferenceTag, [TagProvider]TestTags/GlobalTimerReferenceTag2, and [TagProvider]TestTags/DummyDir/GlobalTimerReferenceTag3 will all trigger as expected).

Script:

I’ve dumbed the script down to just writing a Gateway error message to isolate the problem:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
	#log stuff
	logger=system.util.getLogger("logger")
	logger.error("TESTING ONLY: value change event script fired for: {0}".format(tagPath))

Context: I am trying to create an equipment uptime counter for maintenance purposes in Perspective (so it’s operator driven, not device driven). I would like to stick with this implementation if I can, but I understand there may be different ways to implement this, so I’m open to suggestions if this is a limitation in Ignition.

This is silly, but can you modify your logging statement so it doesn't use the format function - in particular, so that string doesn't have curly brackets in it?

Not silly, at this point I’ll try anything :slight_smile:

Modified the UDT definition and verified script propagated to my instance. Not showing in Gateway logs still (other tags still do).

Hmm, not sure then. I would have expected that to work.

There's an open ticket (IGN-8411) about the curly brackets in UDT scripts breaking things.

You might have to call support and let them take a look.

I do something similar, instead of referencing a tag outside of the UDT you can just create a trigger tag inside of the UDT and update the tag at a set rate.

Ok - do you have any other recommended approaches to work around this in the meantime? I’m new to Ignition development, so while I can probably figure out something, I’d like to get something working for now and move on.

Using a tag valueChange event for this is a terrible approach, fwiw. Consider storing a start timestamp and a boolean run flag in a pair of memory tags. Then the UI can use an expression based on secondsBetween({path/to/tag}, now()) to supply the live uptime to an operator.

Nice, I’ll try this out right now. Thanks.

(post deleted by author)

This doesn’t account for other downtime windows. In other words, equipment runtime isn’t necessarily time since last reset…it may have other factors where we need to stop the counter. Thanks for your input though!

Ok. Consider this topic's solution:

Note that using timestamps like this has a number of advantages over a counter tied to a timer:

  • Only consumes Gateway CPU when a Perspective UI is actively watching, or the run/stop boolean changes. (A Vision UI can watch without any gateway load.)
  • Preserves precision down to the update pace of the run/stop tag.
  • Scales without risking tag event bottlenecks.

Edit: I knew I'd made a better example somewhere--took a moment to find it:

In that example, the RTO_Accum expression tag is not required to be a tag. It can be moved to a UI expression (with suitable indirect tag bindings to retrieve the parts it needs).

Great and with some additional work on my end (a bit of a state machine that I’ll need to use to create a simple boolean running), this will work. Thanks for adding the bullet list, that’s extremely helpful.