I am having trouble with system.tag.addTag(). Context is adding instances of a UDT. Execution of the system.tag.addTag() results in a java exception:
system.tag.addTag([Default]site/area1/lineX): Exception type: , value: java.lang.IllegalArgumentException: UDT [Default]types/myUDTs/line does not exist. Can not create instance.
No combination of tinkering with tag provider specifications seems to work.
Back story: We have two UDT's defined:
myUDTs/index
myUDTs/line
The first is supposed to serve as an index of "lines" that constitute an "area". For sake of illustration I have distilled the index UDT down to a single memory tag: (of type String instead of say a dataset).
When the value of the string is changed, the valueChanged event script should create an instance of the line UDT in the same folder where the index is located, eg. area1 in the example shown above.
The line UDT here is also distilled down for illustrative purposes:
I have tried packaging the system.tag.addTag() call up inside both project and shared python libraries. As this simplified toy example serves to demonstrate, none of that complexity is causing the Java exception.
I wonder if anyone can enlighten me on this issue. I found a few related posts in the forum but no answers. As I mentioned above, I have experimented with all possible ways of specifying the tag provider. It seems system.tag.addTag() cannot find the UDT definitions when the program code is bundled up inside a UDT definition.
I see that you’ve included the tag provider (I’m assuming [Default] is the tag provider) as part of the UDTParentType key on line 14 of lineSpec’s script. Have you tried removing that?
It’s assumed that UDT instances are always in the same tag provider as their definition: otherwise the instance wouldn’t be able to reference the configuration on the definition. I’m thinking the error you’re seeing is accurate: the script can’t locate the definition due to the provider messing/confusing the reference to the definition.
re: included [Default] as part of the UDTParentType key - Have you tried removing that?
I've tried it both ways. The behavior is the same. What prompted me to try this was the system.tag.* documentation. Several places therein it stipulates the need to specify tag provider for scripts running in the gateway scope.
Here is XML for the UDT's with two lineSpec tags - one with [Default] and one without - in the UDTParentType value:
In an instance of the revised index UDT definition, changing the value of either lineSpec or lineSpec1 tags yields the same exception:
UDT [Default]_types_/myUDTs/line does not exist. Can not create instance.,
re: It's assumed that UDT instances are always in the same tag provider as their definition
Both UDT's are defined in the [Default] tag provider. Likewise the intention is for all instances (of both tags) to be in the default tag provider.
re: Try just myUDTs/line for the parent type.
If I understand what you mean, I think this is demonstrated above in the revised MyUDTs/index definition.
I expect the exception is thrown by the Java object constructor for the new line UDT instance. The fact that this constructor is executed/triggered from within the context (scope) of the index UDT instance is the problem.
This leads me to suspect that datatype definitions are not included in a UDT instance's "view" of its tag provider (i.e. the tag provider it hosted within).
Is there any way we could test this?
Can anyone point me to some example SDK code that might enable me to build a work-around?
BTW: One might contemplate building a work around using a gateway event script. Problem with this is these scripts are still scoped to the project. The tags have global scope of the gateway. One could further envision an SFC to monitor these global tag events. Rube Goldberg would be impressed...
@jsorlie What version of Ignition are you using? I took the tag export in your last post and was able to create an instance of your line UDT without modifying your script. For the record, the gateway I tested this on is 7.9.4 beta 2.
Note that both of your lineSpec tags work: looks like the tag provider in the UDTParentPath doesn't matter in this case.
Unfortunately I can't help you here, but I don't see why this shouldn't work out of the box. Perhaps someone else can chime in on this.
Thanks for bearing with me and for testing the line UDT works. Of course manual creation of line instances is not the objective. The goal is to do this in the tag-change event script in the index UDT instance.
Such a mechanism would allow each index instance to locally maintain the tag folder it is created within. By maintain I mean creating instances of other UDT definitions. Here I created the "toy" line UDT definition purely to prototype the mechanism.
re: Note that both of your lineSpec tags work: looks like the tag provider in the UDTParentPath doesn't matter in this case.
Yes you can change the value in either of these tags (lineSpec or lineSpec1) in an instance of the index UDT. If you do so and then check the gateway log (eg. http://localhost/main/web/status/diag.logviewer ) you will see the exception thrown in the tag valueChange event scripts.
The desired behavior would be to create a line UDT instance named per the lineSpec or lineSpec1 value (of course depending on which one you change..) if it does not already exist. Again the difference between the two lineSpec tags is that one explicitly includes [Default] in the UDTParentType specification in the system.tag.addTag() invocation.
The second tag.XML upload in my original post contains instances of both UDTs inside a folder named site (eg. []site/area1/index).