import pprint from com.inductiveautomation.ignition.common.tags.config.types import TagObjectType defaultProvider= utils.admin.tags.helper.defaultProvider defaultSrcProv = utils.admin.tags.helper.defaultSourceProvider def getUDTBaseParameters(): return {'srcPath': {"dataType":"String", "value":None}, 'tagGroup': {"dataType":"String", "value":"Default"}} def transformBase(): """ Read the [default]Base UDT and convert it into the Reference Tag equivalent New logic to create an additional expression tag bound to the srcPath parameter Returns: Nothing, will create the UDT in the global defaultProvider """ newTagConfig= (transformSingleObject("%s_types_/Base"%(defaultSrcProv))) devPathTag={'dataType': "String", 'expression':'{srcPath}', 'name': 'DeviceTagPath', 'tagType': "AtomicTag", 'valueSource': 'expr'} newTagConfig["parameters"] = getUDTBaseParameters() newTagConfig["tags"][0]["tags"].append(devPathTag) pprint.pprint(newTagConfig) system.tag.configure("%s/_types_"%(defaultProvider), [newTagConfig], "o") def transformObjects(udtFolder= "Objects"): """ Scan for all of the Object UDTs in [default] and create the Reference tag version Returns: Nothing """ metaTagNames = [t["name"] for t in system.tag.browse("[MQTT]_types_/Base/Meta")] def normalizeTagConfig(tagConfig): # tagConfig.pop("path") tagConfig.pop("parameters") # Clean up the meta tags inherited from base for t in tagConfig["tags"]: if t["name"] == "Meta": t["tags"] = [item for item in t["tags"] if item['name'] not in metaTagNames] return tagConfig allTagConfig = {} for udtPath in recBrowse("%s_types_/%s"%(defaultSrcProv, udtFolder)): newTagConfig = normalizeTagConfig(transformSingleObject(udtPath)) if "parameters" not in newTagConfig.keys(): newTagConfig["parameters"] = getUDTBaseParameters() rootFolder = "/".join(udtPath.split("/")[:-1]).replace(defaultSrcProv,defaultProvider) allTagConfig.setdefault(rootFolder, []) allTagConfig[rootFolder].append(newTagConfig) for k,v in allTagConfig.iteritems(): system.tag.configure(k, v, "o") def recBrowse(path): """ Recursively process the folder """ listOfPaths = [] for tag in system.tag.browse(path): if tag["tagType"] == TagObjectType.Folder: if tag["name"] != "Parent": # don't browse the parent folder when we're doing the root Objects folder listOfPaths.extend(recBrowse(str(tag["fullPath"]))) elif tag["tagType"] == TagObjectType.UdtType: listOfPaths.append(str(tag["fullPath"])) return listOfPaths def transformSingleObject(udtPath): """ Convert a single UDT Object to a reference tag equivalent. Reusable in individual scenarios Returns: JSON configuration for the new tag object """ curTagConfig = system.tag.getConfiguration(udtPath, True)[0] # curTagConfig.pop("path") # don't need this since we're creating new curTagConfig["tags"] = recFolderTransform(curTagConfig["tags"], curTagConfig["name"]) return curTagConfig def recFolderTransform(tagObj, rootObjName= "", folderPath=""): """ Recursively process the folder's contents to convert the existing tags to Reference Tags Returns: Newly constructed JSON """ alarmSummIdx = -1 for idx, obj in enumerate(tagObj): # print obj["name"], obj["tagType"] if obj["tagType"]== TagObjectType.Folder: # print " %s -- folder found"%(obj["name"]) if "tags" in obj.keys(): recFolderTransform(obj["tags"], folderPath="/".join([folderPath, obj["name"]])) elif str(obj["tagType"]) not in ["UdtInstance"] and obj["name"] != "AlarmSummary": obj["valueSource"] = "reference" # obj["sourceTagPath"] = {"bindType":"parameter", "binding":"{srcPath}/%s{TagName}"%(folderPath[:]+"/" if folderPath != "" else "")} obj["sourceTagPath"] = {"bindType":"parameter", "binding":"{srcPath}/%s%s"%(folderPath[1:]+"/" if folderPath != "" else "", obj["name"])} # hardcode tagpath, but change name to underscore obj["tagGroup"] = {"bindType":"parameter", "binding":"{tagGroup}"} obj["name"] = obj["name"].replace(" ", "_") # remove keys that are no longer relative to the MQTT transmission for k in ["value", "opcServer", "opcItemPath", "sampleMode", "alarms", "sampleMode", "scaleMode", "scaledHigh"]: obj.pop(k, None) # Remove historian settings since we don't need to log this obj["historyEnabled"]= False for setting in ["historyMaxAge", "historyProvider", "historyTagGroup"]: obj.pop(setting, None) elif obj["tagType"] == TagObjectType.UdtInstance: print "1" # Special handler for the Base Object if str(obj["name"]) == "AlarmSummary" and rootObjName=="Base" : replacementTag = obj["tags"][0] replacementTag["valueSource"] = "reference" replacementTag["sourceTagPath"] = {"bindType":"parameter", "binding":"{srcPath}/{TagName}/ActiveAlarms"} replacementTag["tagGroup"] = {"bindType":"parameter", "binding":"{tagGroup}"} replacementTag.pop("name") replacementTag.pop("path") replacementTag.pop("value") obj.pop("tags") obj.pop("typeId") obj.update(replacementTag) return tagObj