# Using system.tag.editTag to pass tag change event scripts

**URL:** <https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100>\
**Category:** Ignition\
**Tags:** ignition79, scripting\
**Created:** [June 26, 2020, 5:02pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100 "2020-06-26T17:02:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ross.moffett](https://avatars.discourse-cdn.com/v4/letter/r/6bbea6/32.png) [@ross.moffett](https://forum.inductiveautomation.com/u/ross.moffett)\
**Post date:** [June 26, 2020, 5:02pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100/1 "2020-06-26T17:02:31Z")

</div>

I’m running Ignition 7.9.14 and trying to write tag change event scripts to tags with script.

[https://docs.inductiveautomation.com/display/DOC79/system.tag.editTag](https://docs.inductiveautomation.com/display/DOC79/system.tag.editTag)

Documentation tells me that I can write attributes, great. It says these attributes are defined here:  
[https://docs.inductiveautomation.com/display/DOC79/Tag+Properties](https://docs.inductiveautomation.com/display/DOC79/Tag+Properties)

If I wanted to do literally any other attribute, there’s good documentation here for that, but there are three lines under Tag Events that let me know it’s possible without providing any information on how to format that when I pass through system.tag.editTag.

I used system.tag.browseConfiguration to parse out the script that I want to pass and try to get some idea of the formatting of the dictionary I need to pass into system.tag.editTag’s attributes… it also converts this java hash object to a list, and then the list object from a SQL type to a string, before printing the original text and parsed script so I don’t have to deal with escaping all the script characters myself.

```auto
sourceTag = " ***tag***"
tagConfig = system.tag.browseConfiguration(sourceTag,False)
propertyList = []

for tag in tagConfig:
	propList = tag.getProperties()
	print propList
	for prop in propList:
		#if prop == 'eventScripts':
		#print "Property '%s' has a value of '%s'" % (prop, tag.get(prop))
		#print propList[4]
		propertyList.append(tag.get(prop))
#for property in propertyList:
#	print property
#print propertyList.index("TagEventScripts[]")
#print propertyList[4]

tagChangeScript1 = str(propertyList[4])
print "------------------------------------------------"
print tagChangeScript1
print "------------------------------------------------"
tagChangeScript2 = tagChangeScript1.replace("TagEventScripts[scripts={valueChanged=(","")
#print type(tagChangeScript)
#print type(propertyList[4])
tagChangeScript = tagChangeScript2.replace(", enabled=true)}]","")
print "------------------------------------------------"
print tagChangeScript
print "------------------------------------------------"

```

That gives me some clues…

```auto
[HistoricalDeadband, HistoricalScanclass, InterpolationMode, tagType, eventScripts, path, HistoryTimestampSource, name, HistoryEnabled, PrimaryHistoryProvider, value, HistoryMaxAgeMode]
------------------------------------------------
TagEventScripts[scripts={valueChanged=(	***SCRIPT*** , enabled=true)}]

```

and this is where I’m stuck - I can’t seem to format the PyDictionary attributes correctly to feed in my script. Does anyone have a reference example using system.tag.editTag to pass eventScripts / TagEventScripts for valueChanged?

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [June 26, 2020, 8:24pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100/2 "2020-06-26T20:24:09Z")

</div>

I suspect that it is expecting an object, even though the native toString function prints this with the look and feel of a list and dictionary it is most likely an object of type BasicTagEventScripts, which inherits from the interface TagEventScripts.

Something like this should work (note this is not tested):

```auto
sourceTag = ' ***tagPath***'
tagConfig = system.tag.browseConfiguration(sourceTag,False)

for tag in tagConfig:
     propList = tag.getProperties()

     for prop in propList:
           if prop.toString() == 'eventScripts':
                editProp = tag.get(prop)
                editScript = editProp.get('valueChanged')
                #Do whatever editing to the script you need to here

                #set valueChanged eventScript value to new script
                editProp.set('valueChanged',editScript,True)
                #commit changes
                system.tag.editTag(tagPath = tag.getFullPath,attributes={'eventScripts':editProp})

```

---

<div class="post-metadata">

**Author:** ![ross.moffett](https://avatars.discourse-cdn.com/v4/letter/r/6bbea6/32.png) [@ross.moffett](https://forum.inductiveautomation.com/u/ross.moffett)\
**Post date:** [June 26, 2020, 8:55pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100/3 "2020-06-26T20:55:02Z")

</div>

I tried something like that before, but not quite in this way so I tried it and got the same error message.

The object type returned from system.tag.browseConfiguration is \<type ‘java.util.HashMap$KeySet’\>, the system.tag.editTag documentation says to pass a PyDictionary object. So what I’m having trouble with is not parsing out the data, but structuring the PyDictionary object in the way that system.tag.editTag expects for its eventScripts attribute.

Throws this error:

```auto
Java Traceback:

	at org.python.core.Py.JavaError(Py.java:495)

	at org.python.core.Py.JavaError(Py.java:488)

	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:188)

	at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction. __call__ (ScriptManager.java:431)

	at org.python.core.PyObject. __call__ (PyObject.java:320)

	at org.python.pycode._pyx104.f$0(<buffer>:9)

	at org.python.pycode._pyx104.call_function(<buffer>)

	at org.python.core.PyTableCode.call(PyTableCode.java:165)

	at org.python.core.PyCode.call(PyCode.java:18)

	at org.python.core.Py.runCode(Py.java:1275)

	at org.python.core.Py.exec(Py.java:1319)

	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:215)

	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:89)

	at org.python.util.InteractiveInterpreter.runsource(InteractiveInterpreter.java:70)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$InterpreterWorker.doInBackground(JythonConsole.java:476)

	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$InterpreterWorker.doInBackground(JythonConsole.java:464)

	at javax.swing.SwingWorker$1.call(Unknown Source)

	at java.util.concurrent.FutureTask.run(Unknown Source)

	at javax.swing.SwingWorker.run(Unknown Source)

	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

	at java.lang.Thread.run(Unknown Source)

Caused by: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Attribute 'eventScripts' is invalid or value is an incorrect data type

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:341)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:315)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:268)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.invoke(GatewayInterface.java:894)

	at com.inductiveautomation.factorypmi.application.script.builtin.ialabs.IALabsTagFunctions.editTagImpl(IALabsTagFunctions.java:59)

	at com.inductiveautomation.ignition.common.script.builtin.ialabs.AbstractIALabsTagFunctions.editTag(AbstractIALabsTagFunctions.java:58)

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.lang.reflect.Method.invoke(Unknown Source)

	at org.python.core.PyReflectedFunction. __call__ (PyReflectedFunction.java:186)

	... 19 more

Caused by: java.lang.Exception: Attribute 'eventScripts' is invalid or value is an incorrect data type

	at com.inductiveautomation.ignition.gateway.script.ialabs.IALabsTagFunctions.__editTags(IALabsTagFunctions.java:833)

	at com.inductiveautomation.ignition.gateway.script.ialabs.IALabsTagFunctions.editTagImpl(IALabsTagFunctions.java:729)

	at com.inductiveautomation.ignition.common.script.builtin.ialabs.AbstractIALabsTagFunctions.editTag(AbstractIALabsTagFunctions.java:58)

	at com.inductiveautomation.ignition.gateway.servlets.gateway.functions.IALabs.editTag(IALabs.java:189)

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at sun.reflect.NativeMethodAccessorImpl.invoke(null)

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(null)

	at java.lang.reflect.Method.invoke(null)

	at com.inductiveautomation.ignition.gateway.servlets.gateway.AbstractGatewayFunction.invoke(AbstractGatewayFunction.java:208)

	at com.inductiveautomation.ignition.gateway.servlets.Gateway.doPost(Gateway.java:405)

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)

	at com.inductiveautomation.ignition.gateway.bootstrap.MapServlet.service(MapServlet.java:85)

	at org.eclipse.jetty.servlet.ServletHolder$NotAsyncServlet.service(ServletHolder.java:1400)

	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:760)

	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1617)

	at org.eclipse.jetty.servlets.CrossOriginFilter.handle(CrossOriginFilter.java:310)

	at org.eclipse.jetty.servlets.CrossOriginFilter.doFilter(CrossOriginFilter.java:264)

	at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1596)

	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:545)

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)

	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:590)

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235)

	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1607)

	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)

	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1297)

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)

	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)

	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1577)

	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)

	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1212)

	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)

	at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:59)

	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)

	at org.eclipse.jetty.server.Server.handle(Server.java:500)

	at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)

	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)

	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)

	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:270)

	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)

	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)

	at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)

	at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)

	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:388)

	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)

	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)

	at java.lang.Thread.run(null)

Traceback (most recent call last):
  File "<buffer>", line 25, in <module>
	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.newGatewayException(GatewayInterface.java:341)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:315)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.sendMessage(GatewayInterface.java:268)

	at com.inductiveautomation.ignition.client.gateway_interface.GatewayInterface.invoke(GatewayInterface.java:894)

	at com.inductiveautomation.factorypmi.application.script.builtin.ialabs.IALabsTagFunctions.editTagImpl(IALabsTagFunctions.java:59)

	at com.inductiveautomation.ignition.common.script.builtin.ialabs.AbstractIALabsTagFunctions.editTag(AbstractIALabsTagFunctions.java:58)

	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

	at java.lang.reflect.Method.invoke(Unknown Source)

com.inductiveautomation.ignition.client.gateway_interface.GatewayException: com.inductiveautomation.ignition.client.gateway_interface.GatewayException: Attribute 'eventScripts' is invalid or value is an incorrect data type

```

---

<div class="post-metadata">

**Author:** ![ross.moffett](https://avatars.discourse-cdn.com/v4/letter/r/6bbea6/32.png) [@ross.moffett](https://forum.inductiveautomation.com/u/ross.moffett)\
**Post date:** [June 26, 2020, 9:09pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100/4 "2020-06-26T21:09:44Z")

</div>

Here is more what I’m trying to get correct, and the results.

Script:

```auto
sourceTag = " ***TagPath***"
destinationTag = " ***TagPath***"

tagConfig = system.tag.browseConfiguration(sourceTag,False)
propertyList = []

for tag in tagConfig:
	propList = tag.getProperties()
	print "-------------------------------------------"
	print "Property type and value"
	print type(propList)
	print propList
	print "-------------------------------------------"
	for prop in propList:
		#if prop == 'eventScripts':
		#print "Property '%s' has a value of '%s'" % (prop, tag.get(prop))
		#print propList[4]
		propertyList.append(tag.get(prop))
		if prop.toString() == 'eventScripts':
			editProp = tag.get(prop)
			editScript = editProp.get('valueChanged')
			print "editProp:"
			print editProp
			print "--------------------------------------"
			print "editScript:"
			print editScript
			print "--------------------------------------"
			editProp.set('valueChanged',editScript,True)
			dic = dict(editProp.toString())
			print "dictionary"
			print dic
			system.tag.editTag(tagPath=destinationTag,attributes={'eventScripts':dic})

```

Results:

```auto
Jython 2.5.3 (, Dec 6 2018, 12:34:00) 
[Java HotSpot(TM) 64-Bit Server VM (Oracle Corporation)] on java1.8.0_241

>>> 
-------------------------------------------
Property type and value
<type 'java.util.HashMap$KeySet'>
[HistoricalDeadband, HistoricalScanclass, InterpolationMode, tagType, eventScripts, path, HistoryTimestampSource, name, HistoryEnabled, PrimaryHistoryProvider, value, HistoryMaxAgeMode]
-------------------------------------------
editProp:
TagEventScripts[scripts={valueChanged=(	***SCRIPT*** , enabled=true)}]
--------------------------------------
editScript:
	***SCRIPT*** 
--------------------------------------
Traceback (most recent call last):
  File "<buffer>", line 31, in <module>
ValueError: dictionary update sequence element #0 has length 1; 2 is required

```

---

<div class="post-metadata">

**Author:** ![ross.moffett](https://avatars.discourse-cdn.com/v4/letter/r/6bbea6/32.png) [@ross.moffett](https://forum.inductiveautomation.com/u/ross.moffett)\
**Post date:** [June 26, 2020, 11:40pm UTC](https://forum.inductiveautomation.com/t/using-system-tag-edittag-to-pass-tag-change-event-scripts/36100/5 "2020-06-26T23:40:09Z")

</div>

From Ignition support, a working solution that uses the SDK.

This is important because it’s the only way to update event scripts on MQTT Engine tags when not inheriting those properties from Ignition Edge Nodes.

```auto
from com.inductiveautomation.ignition.common.sqltags.model import TagProp

sourceTag = " ***TAGPATH***"
destinationTag = " ***TAGPATH***"

tagConfig = system.tag.browseConfiguration(sourceTag,False)
propertyList = []

for tag in tagConfig:
	propList = tag.getProperties()
	print "-------------------------------------------"
	print "Property type and value"
	print type(propList)
	print propList
	print "-------------------------------------------"
	for prop in propList:
		#if prop == 'eventScripts':
		#print "Property '%s' has a value of '%s'" % (prop, tag.get(prop))
		#print propList[4]
		propertyList.append(tag.get(prop))
		if prop.toString() == 'eventScripts':
			editProp = tag.get(prop)
			editScript = editProp.get('valueChanged')
			print "editProp:"
			print editProp
			print "--------------------------------------"
			print "editScript:"
			print editScript
			print "--------------------------------------"
			editProp.set('valueChanged',editScript,True)
			type(editProp)
			system.tag.editTag(tagPath=destinationTag,attributes={TagProp.EventScripts:editProp})

```
