Converting table headers to PyDataSet

Hello,

I have a simple task of writing table column names to PLC tags but it doesn’t want to convert the list to PyDataSet.

Here is the code:
headerVals = event.source.parent.getComponent(‘Power Table’).data.getColumnNames()
headersToPLC = system.dataset.toPyDataSet(headerVals)

Here is the error message:
TypeError: toPyDataSet(): 1st arg can’t be coerced to com.inductiveautomation.ignition.common.Dataset

It seems like I need to convert java.util.Collections$UnmodifiableRandomAccessList (that’s what print type(headerVals) gives me) to Ignition dataset but I couldn’t figure out how to do it.

Any suggestions?

Thanks,
Peter.

PyDatasets are (basically) 2D arrays, AKA lists of lists; the datastructure in pure Python would be something like:

pds = [
    [col1, col2, col3], # row1
    [col1, col2, col3], # row2
    [col1, col2, col3], # row3
]

getColumnNames() returns a flat list:
[columnName1, columnName2, columnName2]

Why are you trying to cast it into a pydataset? What’s the desired operation? You may just need to put it inside of another list, but that’s skipping the actual question:

headerVals = event.source.parent.getComponent(‘Power Table’).data.getColumnNames()
headersToPLC = system.dataset.toPyDataSet([headerVals])

@PGriffith,

All I need is to write this data to PLC tags. I want to use system.opc.writeValues().

I’ve tried putting header list inside of another list with no luck - gives me the same error. Does it work for you? I’m running 7.9.10.

system.opc.writeValues expects a flat list of paths and values - something like:

paths = ["path1", "path2", "path3"]
values = event.source.parent.getComponent(‘Power Table’).data.getColumnNames()
system.opc.writeValues("Ignition OPC UA Server", paths, values)

No PyDatasets required - I’m not sure why you started down that path. Are you able to share a bit more of your script so I can see more of what you’re trying to do?

Or (pure speculation) are you trying to use the table headers to determine which OPC tags to write to? And then extract values from somewhere else (the table data?) If so, this gets a bit more complicated, but still shouldn’t necessarily require PyDatasets.

Yes, that’s exactly where I started but it didn’t work for me:

basePath = 'ns=1;s=[' + event.source.parent.getComponent('PAC').text + ']' + event.source.parent.getComponent('TagName').text

opcuaServer = event.source.parent.getComponent('OPCUA').text

headerPaths = []
headerPaths.append(basePath + '.Headers[0]')
headerPaths.append(basePath + '.Headers[1]')
headerPaths.append(basePath + '.Headers[2]')
headerPaths.append(basePath + '.Headers[3]')
headerPaths.append(basePath + '.Headers[4]')
headerVals = event.source.parent.getComponent('Power Table').data.getColumnNames()
system.opc.writeValues(opcuaServer,headerPaths,headerVals)

Error:
java.lang.ClassCastException: java.lang.ClassCastException: Cannot coerce value ‘[Meter Pressure, Meter K-factor, Meter F/V, Meter Frequency, Meter Density]’ into type: class [Ljava.lang.Object;

Now, here is part of the code that writes the actual table data to PLC tags. I could only make it work with Py datasets. System.opc.writeValues operates only on single row PyDataSets from what i can see:

intData = system.dataset.toPyDataSet(event.source.parent.getComponent('Power Table').data)

intPath = basePath + '.INT'
i=0
for i in range(0,20):
	intRowPaths = []
	intRowVals = []
	for k in range(0,5):
		intRowPaths.append(intPath + str(k+1) + '[' + str(i)+ ']')
		intRowVals.append(intData[i][k])
	
	system.opc.writeValues(opcuaServer,intRowPaths,intRowVals)

What am I missing something here?

Thanks for the help @PGriffith

Try updating the first example to this:

basePath = 'ns=1;s=[' + event.source.parent.getComponent('PAC').text + ']' + event.source.parent.getComponent('TagName').text

opcuaServer = event.source.parent.getComponent('OPCUA').text

headerPaths = []
headerPaths.append(basePath + '.Headers[0]')
headerPaths.append(basePath + '.Headers[1]')
headerPaths.append(basePath + '.Headers[2]')
headerPaths.append(basePath + '.Headers[3]')
headerPaths.append(basePath + '.Headers[4]')
headerVals = list(event.source.parent.getComponent('Power Table').data.getColumnNames())
system.opc.writeValues(opcuaServer,headerPaths,headerVals)
1 Like

That did the trick, Paul @PGriffith

Thanks for your help!

For a little background - it looks like the java.util.Collections$UnmodifiableRandomAccessList that is returned from getColumnNames isn’t a close enough type to a regular Python list to be coerced by system.opc.writeValues - so, calling the list() function automatically creates a new, true list class instance based on the sequence of values provided - the UnmodifiableRandomAccessList.

2 Likes