UDT Tag Value Change Event Script not executing

I have tag change scripts set up on some UDT members that are supposed to write to a specified tag outside of the UDT. However, they don't appear to be executing at all. I've set up a try/except clause that should write to a logger if the primary code block fails to execute, but even that isn't working. Here is the value change script:

def valueChanged(tag, tagPath, previousValue, currentValue, initialChange, missedEvents):
		if currentValue.quality == "Good" and currentValue.value == True:
			#	Writes the tag path of this tag to Last Alarm tag to help with troubleshooting
			message2 = tagPath.split("/")[2]+"."+tagPath.split("/")[5]+"."+tagPath.split("/")[7]
			system.tag.writeBlocking("[~]Derived Tags/Last Alarm", message2)
			alarm_num = tagPath.split("/")[-1]
			tagPath = "[.]../Strings/"+str(alarm_num)
			message = system.tag.readBlocking(tagPath)
			system.tag.writeBlocking("[~]Derived Tags/Last Alarm Cause", message)
		#Log tag change to info logger
		logger = system.util.getLogger("myLogger")
		logger.info("Alarm Bit Tag Change failed to write")

Any suggestions on what's failing here? I have 15 instances of this UDT and none of them are writing to either the tag or logger.

This will never work - quality is a rich QualityCode object, and you're comparing it for equality against a string.

Try if currentValue.quality.isGood().

First, a couple of recommendations:

  1. Create your logger outside of the try/except so you can use it throughout the script for various trace/debug purposes
  2. give your logger a dynamic name so that you can pinpoint the logger to a specific instance e.g. logger = system.util.getLogger(%s_logger % tagPath). This should make it a bit easier to troubleshoot specific instances
  3. if possible, you should except specific errors (just as a general rule-of-thumb/good practice.
  4. if your tag is a boolean, you can trim your if statement to
if currentValue.quality.isGood() and currentValue.value:

Second, my guess is that your script is working, but a qualified value's (what currentValue is) "quality" property is not a string. What you should use to detect whether the quality is good is currentValue.quality.isGood().

also, note that system.tag.writeBlocking takes lists as its arguments, so you need to enclose your path and your value to write in square brackets [].

Finally, I don't know that system.tag.writeBlocking throws any errors, so a try/except clause may not even be applicable here. It returns an error code, so you could do some debugging using that.

`if currentValue.quality.isGood() and currentValue.value:
message2 = tagPath.split("/")[2] + tagPath.split("/"[5] + "."+tagPath.split("/")[7]
system.tag.writeBlocking(["[~]Derived Tags/Last Alarm"], [message2])

alarm_num tagPath.split("/")[-1]
tagPath = "[.]../Strings/"+str(alarm_num)
message = system.tag.readBlocking([tagPath])[0]
system.tag.writeBlocking(["[~]Derived Tags/Last Alarm Cause"], [message.value])`

from there, you can sprinkle in logger messages if needed.

Please let me know if you need any more guidance :slight_smile:

system.tag.writeBlocking Doc

1 Like

Eww! Not that dynamic. Loggers are system resources that never go away once created. Including a project name and/or a script name is as far as I'd go with the dynamic logger name. Definitely not one per tag. If you really need more, consider using the SDK's MDC class to temporarily add runtime attributes to specific log entries.

1 Like