Read Tags, Check for Bad_NotFound vs Exists

I have a handful of client tags that must exist for scripts to work properly. If they don't exist I will throw an error box.

My question is, at what point is it more efficient/better to use system.tag.readblocking() and check for Bad_NotFound on all of the tags, instead of using system.tag.exists() for each tag?

i.e.

if not system.tag.exists('tag1') or not system.tag.exists('tag2') or not system.tag.exists('tag3') or not system.tag.exists('tag4') or not system.tag.exists('tag5'):
	print "return"
else:
	print "continue"

vs

tags = system.tag.readBlocking(['tag1','tag2','tag3','tag4','tag5'])

if True in [tag.quality >= 512 for tag in tags]:
	print "return"
else:
	print "continue"

assuming that the tags will need to be read to continue whatever code execution follows

I would say as soon as there are multiple tags readBlocking will be more performant.

Though, I would do it like this:

qvs = system.tag.readBlocking(['tag1','tag2','tag3','tag4','tag5'])
if any(qv.quality.isBadOrError() for qv in qvs):
    #return, possibly with error
#otherwise do stuff.
2 Likes

exists() internally is just a read call; it's got some special handling to prefer reading the .Name property, which is lighter than reading the value of all tag types, but it's literally just a read call that checks the returned quality code.

So, technically, to get the exact same logic but more performant, you unfortunately do need an import:

from com.inductiveautomation.ignition.common.model.values.QualityCode import Bad_NotFound

qvs = system.tag.readBlocking(['tag1','tag2','tag3','tag4','tag5'])
if any(qv.quality.is(Bad_NotFound) for qv in qvs):
    #return, possibly with error
#otherwise do stuff.
2 Likes

without the import would checking for code 519 work?

Or, is there any actual difference between your qv.quality.is(Bad_NotFound) and @lrose 's qv.quality.isBadOrError() ?

isBadOrError will return true for any bad or error quality code. So you wouldn't be able to distinguish between "the device is unavailable" and "the tag doesn't exist". That's the advantage of the more explicit check for the not found quality.

You can't directly pass 519, because that's not the actual underlying quality code value. The "actual value" of Bad_NotFound is -2147483129, because we pack semantic meaning into some of the 32 bits of a long int before we stuff the "user code" (519) at the end. I'd just do the import rather than peppering my code with a wacky number like that.

Definitely would prefer the import over a "magic number."

Since this is actually a client tag, I'll stick with the isBadOrError. I would assume isBad would work as well, but I'm guessing lrose went off the "> 512" that I originally used.

isBad() will return true for any “Bad” condition. So it’s less specific than the import, but more specific than isBadOrError()

2 Likes