UDT tag Scripting

Good day all!

I am needing some help in scripting with UDTs. As you can see below, I have a script on the UDT Breakout Count. For testing I have a bool that I turn on to move the currentValue of the tag into the Prev Breakout Count.

	if "[~]zzzTimezzz/Time Test - Manual Turn On" == True:
		system.tag.writeBlocking("[.]TESTPrevShift/Prev Breakout Count", currentValue)

You can see from the pic that the Prev still has null in its value, but I need it to be the 21 value.

I did this outside of the UDT with memory tags and it worked fine. I must be missing something, because I havent read where you cannot do this in a UDT.

Any ideas for me?

You need to use system.tag.readBlocking to read the value of [~]zzzTimezzz/..... You are testing the string against a boolean, always yielding false. Jython doesn't know that a string containing a tagpath has any meaning other than being just a string.

I think firstly you must read Value of your tag path that you are testing using readBlocking after to use writeBlocking

OK, I have added the readBlocking

	if system.tag.readBlocking("[~]zzzTimezzz/Time Test - Manual Turn On")[0].value == True:
		x = system.tag.readBlocking("[.]Breakout Count")[0].value
		system.tag.writeBlocking("[.]TESTPrevShift/Prev Breakout Count", x)

I am still not getting the value into the Prev Breakout mem tag

in the script console I do the same thing, except not in the UDT

if system.tag.readBlocking("[default]zzzTimezzz/Time Test - Manual Turn On")[0].value == True:
	x = system.tag.readBlocking("[default]Twisters/TW2/Left/Quad_A/Breakout Count")[0].value
	system.tag.writeBlocking("[default]Twisters/TW2/Left/Quad_A/TESTPrevShift/Prev Breakout Count", x)

And it works:

Im kinda confused.

What do you get in your gateway logs?

Consider retrieving your boolean tag's Qualified value instead of directly checking .value. So you can see bad quality (which typically causes .value to be None, which will never be true).

Ill have to add some logger stuff to my code. Ill let you know.

Main difference I see (that I'd have to test) is that you're using relative references for tags in read and write blocking. Since your script is on the Breakout Count already, I'm assuming it's on a value changed script, so can use the currentValue parameter provided to get the current value without doing a readBlocking call, but then the writeBlocking may have to use the full tag path (again, I'm not certain of this, but that could be an issue). If it's relative to the current tag, you'll have to build it into your script.

1 Like

I do believe you are correct about the relative paths, just because the script is on the udt tag in the setup of the udt. So, would it be better to set the script up on the tag in the browser? I would love to do it in the udt since it would multiply across the udt instances.

You can do it in the UDT, but you'll have to dynamically build the tag path to be an absolute path instead of a relative path.

1 Like

Why not have the previous count be part of the UDT? Then use an on change script in the UDT definition to copy the previous value.

It is. I'm just having trouble getting the script to execute using relative tag paths.

You won't be able to use relative tag paths directly because your call to system.tag.readBlocking() or system.tag.writeBlocking() requires the full path to the tag. You'll have to build the path to the appropriate tag using string manipulation in python. To the python script "[~]" and "[.]" are plain old strings, just like any other and have no meaning in the context of a path. So, you'll have to manipulate the path manually using the path string parameter in the change script.

image

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
	
	#check that value changed - not quality
	if (previousValue <> currentValue):
	
		#build the path to PrevValue from path to Value (i.e. substitute "PrevValue" for "Value")
		#<string>[0:-x] gets the entire string, minus the last x characters
		prevTagPath = tagPath[0:-5] + "PrevValue"
	
		#write the previous value to the tag
		system.tag.writeAsync([prevTagPath], [previousValue])

From your screenshots, it looks like your previous value tag is outside of the UDT. Just add it to the UDT like I have above. Makes things much easier. Adding a tag to the UDT should to affect any of the existing elements.

system.tag.readBlocking/writeBlocking can accept relative paths. See
Reading and Writing to Tags - Ignition User Manual 8.1 - Ignition Documentation, "Relative Tag Paths".

I'm not noticing any issues with the script. Could you provide some more details on how it's set up? It might help to find a way to prove that it's triggering if you haven't already. Create a test tag somewhere and write to it directly with no if statements.

I think the original issue is that the previous tag value that he was trying to write to was not a part of the UDT.

Looking at his screenshots, it's been part of the UDT all along, just in a subfolder in the UDT relative to the tag with the script on it. The instance of the UDT is called TW2. If he would post his full script it may help out as I don't know why he's not just using the currentValue to do a write to the relative tag. Would be much simpler.

This what Im doing currently with no success:

A-ha. The screenshot actually tells you what's wrong (though it may not be obvious). currentValue is a "Qualified Value" with a timestamp and quality, but writeBlocking wants a numerical value. I think currentValue.value is the syntax, try that and see if it works.
Edit: I was corrected below, writeBlocking can accept qualified values.

If I'm having an issue with a script I usually try to find a way to prove that it's executing. If currentValue.value isn't working, you could create a "Test" tag somewhere and try to write a value to it before and after (outside) the if statement. I suspect that the line before would execute and the line after wouldn't, because line 3 will crash the script.

I will try that. I didn't realize currentValue was a qualified value. I will let you know how it goes.

I have tried a couple different time with this:

At this point im not sure its evaluating the "if" part. Isnt there some kinda logger script that I can see if it is in the logs?

I’m pretty sure writeBlocking can take qualified values. I used this before to force specific qualities on tags.

Test your line 2: you’re passing a simple path instead of an array of paths, which should work, but you’re extracting the first value returned.
Now, i never passed a simple path to readBlocking, so I don’t know what it returns, but if it’s returning a single qualified value instead of an array (to match the input), this will raise an error.
Check the logs on the gateway. Always check the logs.

Edit: and batch your writes.

2 Likes