Expression runscript() not working properly

I am trying to run a script in an expression tag. I tried using the runScript() expression function but it is giving me the following tag error:

Error_ExpressionEval("Error executing script for runScript() expression:Utils.getCardDataset")

Here is my following implementation:

I am referencing the function just as the documentation suggests that I should but still get the error regardless. I am pretty sure that the issue is not a runtime error in my script as I can run it successfully from the Script Console.

Am I doing something wrong with my function reference here? Or is this a bug?

This project must be configured as the Gateway Scripting Project in order for tag scripts to reference the script library.

This is not a good test for anything in gateway scope, as it is a derivative of Vision Client scope.

Am I missing something here? I do not have the config option for the gateway scripting project under Gateway Settings. Is this a licensing issue? I am running Ignition Edge 8.1.24

Edge doesn't have a 'Gateway Scripting Project' setting, because Edge only allows one project.

Do you have the compute plugin installed/are you in a valid trial? That could be why the script isn't allowed to run.

No, I do not have the compute plugin installed. I'm guessing that's a full stop on me trying to do this without it.

The actual functionality that I am trying to do is to have opc data populated in this dataset. My initial thought was to return a dataset from a script that populates a python dataset using system.opc.readValues(). From what I can tell, there isn't a great way to pull an array of data from a modbus device without having a separate tag for each register. Am I missing an obvious solution here or is my thinking correct? Trying to read 200 values at once.

Why can't you just have 200 tags?

I could, but I was interested in using a dataset as it would be a little more dynamic and less cluttered than having x number of tags. It would also allow me to work with my data a little more intuitively as I can have rows in the dataset representing specific data points. It is seeming like that is what I am going to have to do, but it is a little inconvenient. It would be nice for datasets to be useful for more than just queries or memory sources and actually be able to populate them with data from OPC devices.

Some of the newer drivers support arrays, but our Modbus driver is pretty old and doesn't.

Dataset isn't a natural mapping for anything that would come from OPC except perhaps a 2-dimensional array, and even then there's no obvious column name or type that can be applied. It only makes sense to build one from scripting, which you may not be able to do since it sounds like you're on an Edge edition that doesn't include scripting access.

Yeah, the script I have written is the perfect solution to the problem. Just not able to use it atm due to licensing.

Here is the code I used to do it for anyone trying to do something similar:

def getCardDataset(driveName):
	server = "Ignition OPC UA Server"
	opcPaths = []
	for x in range(200):
		opcPaths.append("[%s]1.HRI%d"%(driveName, 9001+(x * 2))) #the registers I am trying to poll start at 9001
	qualifiedValues = system.opc.readValues(server, opcPaths)
	headers = ['Position', 'Load']
	data = []
	for x in range(100):
		qualifiedValue1 = qualifiedValues[x] #This is the values for column 1 of my dataset
		qualifiedValue2 = qualifiedValues[x + 100] #This is column 2
	card = system.dataset.toDataSet(headers, data)
	return card
1 Like

Has scripting ever been considered as an official ValueSource for a tag, similar to how an expression is?

Now that I am thinking about it, I wonder if I can run this function in the runScript() expression function as a one-liner. Does the runScript() function work with lambdas?