v8.1.5
I’ve imported a whole bunch of tags from another gateway into a new gateway and having lots of issues…
Lots of UDT instances have imported and their tags are showing as Bad_Disabled when in fact they’re enabled… If I overwrite them to disabled and then remove the override they come good. In the past i’ve seen this before and I could just do a tag restart which would force them to read properly, but not this time I should have budgeted a lot more for this upgrade… I have similar issues with bindings becoming “stuck” with old values as well…
I tried deleting some of the tags and re-importing back in, but no change.
The only way I found to get this unstuck and enabled was to disable the root UDT instance and re-enable it (e.g. “Common”). Time to write a script…
In case it helps anyone else:
'''
This will collect all root (non-nested) UDT Instance tag paths and disable and re-enable those that aren't already disabled.
This will fix "stuck" tags part of UDT instances that won't come good.
'''
import time
import math
processNestedUDTInstances = False
processDisabledUDTInstances = False # DO NOT ENABLE UNLESS YOU KNOW THE RISKS
basePath = '[default]'
# found that writing all at once didn't fix some of the tags, so write them slowly in groups instead :/
tagWriteGroupSize = 10
tagWriteDelaySecs = 1
# get all UDT instance tags
UDTI = system.tag.browse(basePath, filter={'recursive': True, 'tagType': 'UDTInstance'}).results
# get a list of just the fullPaths
UDTI_TagPaths = [str(tag['fullPath']) for tag in UDTI]
# sort it alphabetically so we can remove nested UDT instances efficiently
UDTI_TagPaths = sorted(UDTI_TagPaths)
# loop through all UDT instance tag paths and add them into a new list if any item in the new list isn't in each of the tag paths.
# this effectively checks if the tag path is nested within any of the other tag paths already added to the new list.
### remove this for loop if you want to process ALL UDT instances, nested or not. ###
UDTI_Root_TagPaths = []
for tag in UDTI_TagPaths:
if processNestedUDTInstances or not any([tagpath in tag for tagpath in UDTI_Root_TagPaths]):
UDTI_Root_TagPaths.append(tag)
# read the current Enabled status of each UDT Instance so that we don't inadvertently affect UDT instances that *should* be disabled.
disabledStatuses = system.tag.readBlocking(['{}.Enabled'.format(tag) for tag in UDTI_Root_TagPaths])
# get just disabled status values.
disabledStatuses = [tag.value for tag in disabledStatuses]
# remove the already disabled UDT instance tag paths from the list
UDTI_Root_TagPaths_NotDisabled = [tag for tag, state in zip(UDTI_Root_TagPaths, disabledStatuses) if processDisabledUDTInstances or state == True]
print 'Not disabled tag count: ', len(UDTI_Root_TagPaths_NotDisabled)
print "Already disabled tag count (these won't be processed): ", len(UDTI_Root_TagPaths)-len(UDTI_Root_TagPaths_NotDisabled)
# create a list of the UDT instance enabled tag paths
UDTI_Root_EnableTagPaths = ['{}.Enabled'.format(tag) for tag in UDTI_Root_TagPaths_NotDisabled]
# finally, disable them and re-enable them
print 'Disabling all UDT instances...'
system.tag.writeBlocking(UDTI_Root_EnableTagPaths, [False]*len(UDTI_Root_EnableTagPaths))
time.sleep(5)
loopCount = int(math.ceil(1.0*len(UDTI_Root_EnableTagPaths)/tagWriteGroupSize))
totalSize = len(UDTI_Root_EnableTagPaths)
print 'Enabling UDT instances slowly in groups of ', tagWriteGroupSize
for index in range(loopCount):
firstIndex = tagWriteGroupSize*index
lastIndex = tagWriteGroupSize*(index+1)
if lastIndex > totalSize: lastIndex = totalSize
print 'Writing tag indexes: ',firstIndex, '->', lastIndex-1
system.tag.writeBlocking(UDTI_Root_EnableTagPaths[firstIndex:lastIndex], [True]*len(UDTI_Root_EnableTagPaths[firstIndex:lastIndex]))
time.sleep(tagWriteDelaySecs)
and this script to check if there are any remaining tags that are Bad_Disabled which are in fact Enabled:
'''
This will check to see if there are any tags that are "stuck" with a Bad_Disabled quality when the tag is enabled.
'''
import time
import math
basePath = '[pckg_barrelWashLine]Wolf Blass/Packaging/Barrel Washing/Stations'
# get all tags
tags = system.tag.browse(basePath, filter={'recursive': True, 'tagType': 'AtomicTag'}).results
# get a list of just the fullPaths
tagPaths = [str(tag['fullPath']) for tag in tags]
# sort it alphabetically
tagPaths = sorted(tagPaths)
# read the current quality status of each tag path.
tagPaths_qual = system.tag.readBlocking(['{}.Quality'.format(tag) for tag in tagPaths])
# get just disabled status values.
tagPaths_qual = [tag.value for tag in tagPaths_qual]
# read the current Enabled status of each tag path.
tagPaths_en = system.tag.readBlocking(['{}.Enabled'.format(tag) for tag in tagPaths])
# get just enabled status values.
tagPaths_en = [tag.value for tag in tagPaths_en]
badDisabledTagPaths = []
for t,e,q in zip(tagPaths, tagPaths_en, tagPaths_qual):
if e and str(q) == 'Bad_Disabled':
badDisabledTagPaths.append(t)
print t