I am having a hard time understanding how getConfiguration / configure are supposed to work together in Ignition 8. For example, why does the following code fail for the simple case where I want to disable the UDT instance tag ‘T1/T2/Finst’?
(Yes I understand that I could do this directly in this simple case with something like nodes[0][‘enabled’] = False but I’m trying to build more general tools and want to have Python lists/dictionaries for the more general case)
import pprint
nodes = system.tag.getConfiguration('T1/T2/Finst', False)
print 'before = %s' % pprint.pformat(nodes)
rawInfo = {}
for key, value in nodes[0].iteritems():
rawInfo[key] = value
rawInfo['enabled'] = False
nodes = [rawInfo]
print 'after = %s' % pprint.pformat(nodes)
system.tag.configure('T1/T2', nodes)
The result is:
before = [{u'enabled': True,
u'name': u'Finst',
u'parameters': {u'P1': {datatype=Integer, value=53},
u'P2': {datatype=Integer, value=null}},
u'path': [default]T1/T2/Finst,
u'tagType': UdtInstance,
u'typeId': u'YokagawaUDTsDMWebb/FFF'}]
after = [{u'enabled': False,
u'name': u'Finst',
u'parameters': {u'P1': {datatype=Integer, value=53},
u'P2': {datatype=Integer, value=null}},
u'path': [default]T1/T2/Finst,
u'tagType': UdtInstance,
u'typeId': u'YokagawaUDTsDMWebb/FFF'}]
18:18:31.717 [AWT-EventQueue-0] ERROR Scripting[util_tag] - Error converting PyTagDictionary to tag edit:
java.lang.ClassCastException: Cannot coerce value '{
"pathParts": [
"T1",
"T2",
"Finst"
],
"source": "default"
}' into type: interface com.inductiveautomation.ignition.common.tags.model.TagPath
at com.inductiveautomation.ignition.common.TypeUtilities.coerce(TypeUtilities.java:1493)
at com.inductiveautomation.ignition.common.TypeUtilities.coerceNullSafe(TypeUtilities.java:838)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializePropertySafe(TagGson.java:670)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeProperty(TagGson.java:684)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeJsonObject(TagGson.java:642)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:566)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:515)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:927)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:994)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:967)
at com.inductiveautomation.ignition.common.tags.TagUtilities.toTagConfiguration(TagUtilities.java:128)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.dictToTagEdits(AbstractTagUtilities.java:223)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.lambda$configure$0(AbstractTagUtilities.java:163)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(Unknown Source)
at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.configure(AbstractTagUtilities.java:170)
at jdk.internal.reflect.GeneratedMethodAccessor105.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:541)
at org.python.core.PyObject.__call__(PyObject.java:477)
at org.python.core.PyObject.__call__(PyObject.java:481)
at org.python.pycode._pyx175.f$0(<event:actionPerformed>:10)
at org.python.pycode._pyx175.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:788)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:297)
at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
at com.sun.proxy.$Proxy58.actionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Another case. It seems like when using system.tag.configure() to set UDT Instance data type parameters, only the Integer type is supported. The code below was run in a button, and the comments describe the result of print statements or system.tag.configure() calls.
nodes = system.tag.getConfiguration('T1/T2/Finst', False)
params = nodes[0]['parameters']
p1 = params['P1']
config = {}
config['name'] = 'Finst'
config['parameters'] = params
# Case 1: Change value of P1 to 12
p1.setValue(12)
print 'Config 1: %s' % config
# Config 1: {'name': 'Finst', 'parameters': {u'P1': {datatype=Integer, value=12}, u'P2': {datatype=Integer, value=null}}}
r = system.tag.configure('T1/T2', [config], 'm')
# Result: Works as expected, changes value of parameter P1 to 12
# Case 2: Change dataType of P1 to String
import com.inductiveautomation.ignition.common.sqltags.model.types.DataTypeClass as DataTypeClass
dataType = DataTypeClass.valueOf('String')
p1.setDatatype(dataType)
print 'Config 2: %s' % config
# Config 2: {'name': 'Finst', 'parameters': {u'P1': {datatype=String, value=12}, u'P2': {datatype=Integer, value=null}}}
r = system.tag.configure('T1/T2', [config], 'm')
# Result: Silently ignored, datatype for P1 is still Integer even though the value of r shows Good.
Finally, an attempt to set the datatype of P1 to String using the Tag Browser GUI, then use code to set the value to a string.
# Case 3: Change value of P1 to 'abc'
# [Change configuration of P1 to be String type using GUI before running this.]
p1.setValue('abc')
print 'Config 3: %s' % config
# Config 3: {'name': 'Finst', 'parameters': {u'P1': {datatype=String, value=abc}, u'P2': {datatype=Integer, value=null}}}
r = system.tag.configure('T1/T2', [config], 'm')
# Result: Exception:
16:16:57.475 [AWT-EventQueue-0] ERROR tags.json - Error parsing value. Data type: Integer, value: "abc"
java.lang.NumberFormatException: For input string: "abc"
at java.base/java.lang.NumberFormatException.forInputString(Unknown Source)
at java.base/java.lang.Long.parseLong(Unknown Source)
at java.base/java.lang.Long.parseLong(Unknown Source)
at com.inductiveautomation.ignition.common.gson.JsonPrimitive.getAsLong(JsonPrimitive.java:242)
at com.inductiveautomation.ignition.common.tags.config.TagGson.deserializeValue(TagGson.java:825)
at com.inductiveautomation.ignition.common.tags.config.TagGson$ParameterValueTypeAdapter.deserialize(TagGson.java:234)
at com.inductiveautomation.ignition.common.tags.config.TagGson$ParameterValueTypeAdapter.deserialize(TagGson.java:212)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:927)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:994)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter$GsonContextImpl.deserialize(TreeTypeAdapter.java:162)
at com.inductiveautomation.ignition.common.tags.config.TagGson$ParameterTypeAdapter.deserialize(TagGson.java:189)
at com.inductiveautomation.ignition.common.tags.config.TagGson$ParameterTypeAdapter.deserialize(TagGson.java:155)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:927)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:994)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter$GsonContextImpl.deserialize(TreeTypeAdapter.java:162)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeProperty(TagGson.java:682)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeJsonObject(TagGson.java:642)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:566)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:515)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:927)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:994)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:967)
at com.inductiveautomation.ignition.common.tags.TagUtilities.toTagConfiguration(TagUtilities.java:128)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.dictToTagEdits(AbstractTagUtilities.java:223)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.lambda$configure$0(AbstractTagUtilities.java:163)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(Unknown Source)
at java.base/java.util.Iterator.forEachRemaining(Unknown Source)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.base/java.util.stream.ReferencePipeline.collect(Unknown Source)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.configure(AbstractTagUtilities.java:170)
at jdk.internal.reflect.GeneratedMethodAccessor69.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:541)
at org.python.core.PyObject.__call__(PyObject.java:494)
at org.python.core.PyObject.__call__(PyObject.java:498)
at org.python.pycode._pyx295.f$0(<event:actionPerformed>:26)
at org.python.pycode._pyx295.call_function(<event:actionPerformed>)
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1687)
at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:788)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:206)
at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:297)
at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
at com.sun.proxy.$Proxy58.actionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.desktop/java.awt.Component.processEvent(Unknown Source)
at java.desktop/java.awt.Container.processEvent(Unknown Source)
at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
From what I've seen, you simply cannot include UDT parameter overrides directly in system.tag.configure if they aren't integers. But you can use system.tag.writeBlocking afterwards to set instance parameters without disturbing the defined datatype.
@pturmel , I was actually trying to overwrite a tag in the UDT with properties with that idea that we would store data like opcItemPath and SourceTagPath values in the JSON of the tag and then manipulate the ValueSource whether its OPC or reference and it should get appropriate property accordingly but when I try to overwrite the tag with properties through change script it gives me this error :`
when I do syste.tag.configure it gives me following error:
java.lang.ClassCastException: Cannot coerce value '[default]Instance/Tag2' into type: interface com.inductiveautomation.ignition.common.tags.model.TagPath
at com.inductiveautomation.ignition.common.TypeUtilities.coerce(TypeUtilities.java:1513)
at com.inductiveautomation.ignition.common.TypeUtilities.coerceNullSafe(TypeUtilities.java:853)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializePropertySafe(TagGson.java:673)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeProperty(TagGson.java:687)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserializeJsonObject(TagGson.java:645)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:569)
at com.inductiveautomation.ignition.common.tags.config.TagGson$PropertySetTypeAdapter.deserialize(TagGson.java:518)
at com.inductiveautomation.ignition.common.gson.internal.bind.TreeTypeAdapter.read(TreeTypeAdapter.java:69)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:927)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:994)
at com.inductiveautomation.ignition.common.gson.Gson.fromJson(Gson.java:967)
at com.inductiveautomation.ignition.common.tags.TagUtilities.toTagConfiguration(TagUtilities.java:128)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.dictToTagEdits(AbstractTagUtilities.java:227)
at com.inductiveautomation.ignition.common.script.builtin.AbstractTagUtilities.configure(AbstractTagUtilities.java:177)
at jdk.internal.reflect.GeneratedMethodAccessor124.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
at com.inductiveautomation.ignition.common.script.ScriptManager$ReflectedInstanceFunction.__call__(ScriptManager.java:552)
at org.python.core.PyObject.__call__(PyObject.java:477)
at org.python.core.PyObject.__call__(PyObject.java:481)
at org.python.pycode._pyx200.initializeTagProperties$5(:90)
at org.python.pycode._pyx200.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:134)
at org.python.core.PyFunction.__call__(PyFunction.java:416)
at org.python.pycode._pyx200.update$4(:101)
at org.python.pycode._pyx200.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:119)
at org.python.core.PyFunction.__call__(PyFunction.java:406)
at org.python.pycode._pyx199.valueChanged$1(:7)
at org.python.pycode._pyx199.call_function()
at org.python.core.PyTableCode.call(PyTableCode.java:173)
at org.python.core.PyBaseCode.call(PyBaseCode.java:306)
at org.python.core.PyFunction.function___call__(PyFunction.java:474)
at org.python.core.PyFunction.__call__(PyFunction.java:469)
at org.python.core.PyFunction.__call__(PyFunction.java:464)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:846)
at com.inductiveautomation.ignition.common.script.ScriptManager.runFunction(ScriptManager.java:828)
at com.inductiveautomation.ignition.gateway.project.ProjectScriptLifecycle$TrackingProjectScriptManager.runFunction(ProjectScriptLifecycle.java:828)
at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$FunctionInvokerImpl.run(TagScriptManagerImpl.java:533)
at com.inductiveautomation.ignition.gateway.tags.scripting.events.AbstractTagScript.invoke(AbstractTagScript.java:34)
at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$Task.invoke(TagScriptManagerImpl.java:482)
at com.inductiveautomation.ignition.gateway.tags.scripting.TagScriptManagerImpl$TagScriptDispatcher.run(TagScriptManagerImpl.java:445)
at com.inductiveautomation.ignition.common.execution.impl.BasicExecutionEngine$ThrowableCatchingRunnable.run(BasicExecutionEngine.java:544)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Hi, is this still valid? You can't use system.tag.configure UDT instances? I have created a UDT that is used all over the place so the comms with our PLC is really high, we were able to fix this changing to a leased tag groups but then the issue was that the alarms set up to some of the UDT tags would be at the slow rate and not the leased rate. I tried to do a script to change the taggroup of only the tags with alarms but keep getting this error
[Bad_Unsupported("The target path '[BP2_300]BP2_300/Section_030/StateMachine/pinInterlock/8' cannot accept children tags.")]
system.tag.configure "overthinks" how it is supposed to apply values to instance parameters. And screws it up. (Makes things strings that shouldn't be, mostly.)
So create the UDT instance with system.tag.configure(), but don't include the parameters. Let them inherit the defaults. Then set the parameters with system.tag.writeBlocking().
But this is something else. Your script is trying to create tags inside a UDT. That isn't permitted. When creating/merging into a UDT instance, any nested tags can be configured at that time, but not standalone. Anything stand-alone must be done with system.tag.writeBlocking().
I was able to make my script work with your inputs. Now I have another issue. I have a bunch of UDTs that have the tag set up as ReadOnly. I tried modifying the UDT definition itself but it still give me the [Bad_AccessDenied("Tag is Read-Only")] I also tried modifying the ReadOnly parameter but didn't work.
Is there a way for the script to work or I need to disable manually the parameter on the UDT and the enable it again?
Here is just the example I used to test.
tagGroupList = ['[BP2_300]_types_/Step/stsFaultCode.ReadOnly']
groupConfigList = [False]
result = system.tag.writeBlocking(tagGroupList, groupConfigList)
print result
I would expect you to have to create everything read-write (have the definition be read-write) and change that parameter to read-only as the very last thing.
There are a few issues with the above. Primarily, the 'getConfiguration' (edit) function returns ALL parameters, which means ALL parameters are written back to the instance UDT as overrides.
I recall there were too many 'what-ifs' to handle (alarm configs vs UDT instance parameters, etc.).
I've had the best luck by reading the 'correct config' from a reference tag (manually updated w/ tag editor), isolating the key/property of interest (by building a new dictionary that contains ONLY the config item(s) I want to change, as read from the reference tag) and then configure other tags with that dictionary config & collisionPolicy='m'.