Fill drop-down list issue

#1

I’m trying to generate a 1-column list and populate a drop-down list when a numeric label changes value.
The data is read using OPC and any duplicate values are not added to the list.
When it attempts to convert the List into a dataset I get the error below at the line

dataset = system.dataset.toDataSet(header,oList)

ERROR MESSAGE:
java.lang.ClassCastException: java.lang.ClassCastException: org.python.core.PyInteger cannot be cast to org.python.core.PySequence

PRINT of the List (oList):
[0, 13, 14, 8, 122]

CODE:
if event.propertyName == “value”:

	oTags = []
	for i in range(60):
		oTags.append("Tagname_" + str(i) +"_")
	oValues = system.tag.readAll(oTags)

	oList = []

	for x in range(len(oTags)):
		nValue = oValues[x].value
		
		#add new number to droplist 
		if not (nValue in oList):
			oList.append(nValue)


	header = ["Value"]
	dataset = system.dataset.toDataSet(header,oList) 
	sortDataSet = system.dataset.sort(dataset,"Value")
	event.source.parent.getComponent('droplist_1').data = sortDataSet
0 Likes

#2

The oList needs to be a List of rows, not just a list of values.
Should look more like
Print of oList = [[0], [13], [14], [8], [122]]

I think the easiest way is to change the line

oList.append(nValue)

to

oList.append([nValue])
1 Like

#3

That worked!
Now how do you check the List for an existing number? Basically it’s a list of lists now.
Using

If not (nValue in oList):

doesn’t filter out duplicate values

0 Likes

#4

You could keep it a flat list (so you can easily check membership) and only convert it to a nested list at the last moment before creating the dataset:
system.dataset.toDataSet(header, [[i] for i in oList])

1 Like

#5

BINGO! That worked like a charm :smiley:

I didn’t know you can convert a list inline…where is that documented?

0 Likes

#6

That’s a generic Python concept known as a “comprehension” - specifically, a list comprehension.

1 Like

#7

Thanks! I’m a newbie to Python (I know VB, VBA and VBScript very well though).

0 Likes

#8

How would you do the reverse, take a List of Rows and return only a flat List?

I have a returned List from an OPC writeValues call and would like to parse through the list and
generate a flat list. If a returned value is [GOOD], insert a “1” otherwise a “0” into the flat list.

Here’s the returned List:

[[GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD], [GOOD]]

flat list would be [1,1,1,1,1,1,1,1,1,1,1]

Or is there a better way just to return a value of “1” if all of the List rows = “GOOD” otherwise a “0”?
Looking for a elegant solution to determine if there was any error during the OPC writeValues call.

0 Likes

#9

You can use the all builtin to check all members of an iterable for a condition. Paired with a comprehension, something like this works:

l = system.opc.writeValues("Ignition OPC UA Server", ['abc'], [123])

print all(qc.isGood() for qc in l)
>>> False

In this case, the QualityCode object returned by writeValues has an isGood method that conveniently returns a boolean.

0 Likes

#10

Perfect! :clap::clap:

0 Likes