[FEATURE-16831] OPC (PLC) browse


Currently working a tool to easily browse an AB plc from a perspective session and cannot help but wonder why this process is highly efficient in the designer environment but not on a running client (system.opc.browse is slow). Has anyone run into this issue? Is there a way to leverage the tools of the designer on a session?


Use system.opc.browseServer, not system.opc.browse. The former browses one level at a time like the OPC Browser does, the latter is a naive recursive browse that will quickly start taking too long and time out.

Thanks Kevin, took a while but was able to figure out a way to do this with the tree component. Now that getting the data is done, I was wondering what the best way is to determine the datatype of a tag is. I have attached a sample of the change script code. In summary there is a change script on the items property of the tree view. This change script is fired whenever an item is expanded, the code then goes through the items to see if it needs to load a new array of items. There is an updateData property that prevents the change script from constantly calling itself. Additionally I used a change script because adding an onitemClicked event disables the multiple selection capabilities and I needed to retain this feature

def valueChanged(self, previousValue, currentValue, origin):
	This function will be called when the value of the property changes.

		self: A reference to the component that is invoking this function.
		previousValue: The previous value, as a qualified value object.
		currentValue: The new value, as a qualified value object.
		origin: The origin of the property value. Possible origin values include
		        Browser, Binding, BindingWriteback, Script, Delegate, Session, Project
	logger = system.util.getLogger("My Logger")
	data = self.props.items
	if self.view.custom.updateData:
		def expand(items):
			for item in items:
				if item["expanded"] and item["items"][0]["label"] == "Loading...":
					server = "Ignition OPC UA Server"
					node = item["data"]["opcItem"].split("ns=1;s=")[1]
					result = system.opc.browseServer(server,node)
					newItems = []
					for child in result:	
						dict = {}
						name = child.getDisplayName()
						opcItem = child.getNodeId()
						elementType = str(child.getElementType())
#						if elementType not in ["OBJECT","FOLDER"]:
#							datatype = child.getType()
						if name not in ["[Diagnostics]"]:
							dict["label"] = name
							if elementType == "OBJECT":
								dict["items"] = [{"label":"Loading...","expanded":False,"data":{},"items":[]}]
								dict["items"] = []
#								dict["datatype"] = datatype
							dict["expanded"] = False
							dict["data"] = {"opcItem":opcItem,"type":elementType}
					item["items"] = newItems	
				elif item["expanded"]:
	self.view.custom.updateData = False

Unfortunately it doesn’t look like the datatype is included in the browse results. This would have to be something we added.

Looks like the browse()/browseSimple() functions can do this. I was attempting to browse at the specific tag but there appears to be something going on. How would you recommend getting a specific tag info?

Those functions browse Ignition tags, not OPC, which is different.

system.opc.browseServer is doing a live OPC browse directly against the OPC server. You are getting results that may not even be brought into Ignition as a tag.

Forgive me Kevin I meant the system.opc.browseSimple function. I was trying to pass the opcItemPath and folderPath to the function so I can apply the getDataType() function on the OPC item. But this was not working.

Well, this is what I meant originally, which is that this is functionality we’d have to add. This version of the function simply doesn’t do the same thing as browseSimple does. It returns a different result structure that doesn’t include the datatype.

Where can I go to track the progress of this feature request? It has come up a few times already.

Hey, where can I track the progress of this item, or how can we develop a work around with the tools already in existence. can I call on system.opc.browse and pass folder path if the item does not have children? maybe I need to make this a support ticket or something, we really need a way to browse PLC and bring in tags at real time so users can configure alarms and history.

This was implemented in Ignition 8.1.1.