Create Tag Change Event Scripts On the Fly / Adding Callbacks to Tags at Runtime

I have a PLC with a variable set of tags which start with a certain prefix and then an index indicating which of my stations the tags relate to.

I can dynamically search and access these tags already using a combination of the tag browser and a bit of logic. I can create a timer script to monitor all of these tags, but this will quickly become inefficient, as it is expected that a copy of this PLC with its tags will be placed at more stations in the future. I do not want to have to check if 100 different tags have changed in value in the last 10 seconds and then update my database based on only a few changes which occurred. The timer script would have to run on the server, because we cannot guarantee that the station computer will be on at all times.

Question:

I need to be able to dynamically create a tag change event for all of the tags I find in the PLC matching my search criteria. Is there any way to do this?

Attempts:

from com.inductiveautomation.ignition.gateway.sqltags.execution.tags import AbstractGatewayTag
AbstractGatewayTag.createTagChangeEvent()

Unfortunately, it says there is no gateway module.

I am sure this is a common problem, but I cannot find a solution.

1 Like

I’d like to know also.

I have not tried this, but how abaout system.tag.editTag?
This should allow you to add a tag event script to already existing tags in your system.

If you are trying to quickly customize in a designer context for specific installs, editTag() might be the best way.
If you need something truly dynamic, you might consider using something like this:

from com.inductiveautomation.ignition.gateway import SRContext
from com.inductiveautomation.ignition.common.sqltags.parser import TagPathParser
from com.inductiveautomation.ignition.common.sqltags.model.event import TagChangeListener

class MyListener(TagChangeListener):
    def tagChanged(self, event):
        # do something with event
        pass

listener = MyListener()
tp = TagPathParser.parse('[someProvider]some/Path/To/Tag')

SRContext.get().getTagManager().subscribe(tp, listener)

This is a super-simplified example – not for production use without close attention to object lifetimes (pair the above with .unsubscribe()). But it allows you to dynamically subscribe to tag events as you see fit.
Don’t expect any official support from IA if you go this route, of course.

Do you have an example?, I want to add a script to a bunch of tags, I was thinking about doing it via script, but I cannot find a way to write the events script ValueChanged.

If you want the same script on a bunch of tags, consider using a Tag Change Event Script instead of a Tag Event Value Change script. In the former, you write the script once, and list all the tags you wish it to monitor. It’s also in project scope, so you can use project scripts in addition to shared scripts.

In my not-so-humble opinion, this question highlights just how much of an unmaintainable mess tag events really are.

[quote="pturmel, post:6, topic:16042, full:true"]
If you want the same script on a bunch of tags, consider using a Tag Change Event Script instead of a Tag Event Value Change script. [/quote]
I am not familiar with Tag Change Event Script I will look it up

Could not agree more!! and more to be created!!
My concern is when someone fresh tries to understand the mess

Thank you Phil, this turned out great for what I am trying to achieve!

This is exactly when you start going nuts with documentation. It takes awhile at first to put it together and maintenance is fantastic, but it will pay for itself when you or someone else has to crack open some code no one has looked at in a year.

Was anyone able to get this working for Ignition 8? I have tried to get it working but so far no sucess.
This is what I have so far, the registring of the listener seems to be working but the tagChanged method is never run.:

from com.inductiveautomation.ignition.common.sqltags.parser import TagPathParser
	from com.inductiveautomation.ignition.common.tags.model.event import TagChangeListener
	
	from com.inductiveautomation.ignition.gateway import IgnitionGateway
	from com.inductiveautomation.ignition.gateway.tags.model import TagSubscriptionModel
	from com.inductiveautomation.ignition.common.tags.model import TagPath
	from com.inductiveautomation.ignition.common.tags.paths import BasicTagPath
	
	class MyListener(TagChangeListener):
	    def tagChanged(self, event):
	    	print 'test'
	        logger = system.util.getLogger('test')
	        logger.info('123')	        
	
	listener = MyListener()
#	tp = TagPathParser.parse('[default]AAATEST')
	tp = BasicTagPath('[default]AAATEST')
	
	context = IgnitionGateway.get()
#	tagSubscriptionModel = 	TagSubscriptionModel(context)
#	tagSubscriptionModel.subscribe(tp,listener)
	
	logger.info(str(context.getTagManager().subscribeAsync(tp, listener)))