Weird Python error with dataset.getValueAt()

I have this little piece of code that ignition keeps throwing an error on. It doesn’t like line 3 for whatever reason but the code works so I am not sure what its issue is. Does someone see something that I don’t see?

Edit:
I should say that this code takes the first and last values of a chart (this code sits in the propertychange of a chart). Finds the difference and sends that value to a label.

Dataset = event.source.Data
row = Dataset.getRowCount()-1
end = Dataset.getValueAt(row,1)
start = Dataset.getValueAt(0,1)
change = end - start
event.source.parent.getComponent('Label and Label (1)').Value = change
com.inductiveautomation.ignition.common.script.JythonExecException: Traceback (most recent call last):
 File "<event:propertyChange>", line 3, in <module>
     at com.inductiveautomation.ignition.client.gateway_interface.OptimizedDataSet.getValueAt(OptimizedDataSet.java:122)

     at com.inductiveautomation.factorypmi.application.binding.util.NonSerializingDataset.getValueAt(NonSerializingDataset.java:66)

     at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)

     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

     at java.lang.reflect.Method.invoke(Unknown Source)

 
 java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 25920
 
     at org.python.core.Py.JavaError(Py.java:495)
     at org.python.core.Py.JavaError(Py.java:488)
     at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)
     at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:204)
     at org.python.core.PyObject.__call__(PyObject.java:422)
     at org.python.core.PyObject.__call__(PyObject.java:426)
     at org.python.core.PyMethod.__call__(PyMethod.java:139)
     at org.python.pycode._pyx40.f$0(<event:propertyChange>:6)
     at org.python.pycode._pyx40.call_function(<event:propertyChange>)
     at org.python.core.PyTableCode.call(PyTableCode.java:165)
     at org.python.core.PyCode.call(PyCode.java:18)
     at org.python.core.Py.runCode(Py.java:1275)
     at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:636)
     at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:180)
     at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.access$000(ActionAdapter.java:40)
     at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter$ActionRunner.run(ActionAdapter.java:286)
     at java.awt.event.InvocationEvent.dispatch(Unknown Source)
     at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
     at java.awt.EventQueue.access$500(Unknown Source)
     at java.awt.EventQueue$3.run(Unknown Source)
     at java.awt.EventQueue$3.run(Unknown Source)
     at java.security.AccessController.doPrivileged(Native Method)
     at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
     at java.awt.EventQueue.dispatchEvent(Unknown Source)
     at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
     at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
     at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
     at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
     at java.awt.EventDispatchThread.run(Unknown Source)
 Caused by: org.python.core.PyException: Traceback (most recent call last):
 File "<event:propertyChange>", line 3, in <module>
     at com.inductiveautomation.ignition.client.gateway_interface.OptimizedDataSet.getValueAt(OptimizedDataSet.java:122)

     at com.inductiveautomation.factorypmi.application.binding.util.NonSerializingDataset.getValueAt(NonSerializingDataset.java:66)

     at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)

     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

     at java.lang.reflect.Method.invoke(Unknown Source)

 
 java.lang.ArrayIndexOutOfBoundsException: java.lang.ArrayIndexOutOfBoundsException: 25920
 
     ... 30 common frames omitted
 Caused by: java.lang.ArrayIndexOutOfBoundsException: 25920
     at com.inductiveautomation.ignition.client.gateway_interface.OptimizedDataSet.getValueAt(OptimizedDataSet.java:122)
     at com.inductiveautomation.factorypmi.application.binding.util.NonSerializingDataset.getValueAt(NonSerializingDataset.java:66)
     at sun.reflect.GeneratedMethodAccessor44.invoke(Unknown Source)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
     at java.lang.reflect.Method.invoke(Unknown Source)
     at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:186)
     ... 27 common frames omitted
 

If your doing this as a property change script do you have anything above this? Normally with a property change script you would want to add filters.

When I copy and paste what you have other than the last line and do a “print change” it works as I’d expect it to. That’s what makes me wonder if its related to whatever filters you have set up in your property change script prior to this.

1 Like

What do you mean by filters?

Multiple properties change anytime you change something on an object. For example if I tie a chart to the history of a tag and use a date range picker to set the time range. Then inside of the propertyChange function of the chart I put

print event.propertyName

When I change the date range, I will get the following in printed to my console:

propertiesLoading
Data
propertiesLoading

When each of these where printed in my console the script ran once. So for that one date change my property change script ran 3 times. Each object is different about what properties it has available to it but each change it likely to make your script run more than once. If you don’t have it filtered using if statements you can get results you don’t want or cause an extra load on your system. Because of this I assumed you would have something prior to the script you had posted.

I get errors like this all the time, and what I do is just simplify the code and add print statements.This exception makes me think it's just a simple problem with the inputs that .getValueAt() is expecting.

I would just make a button on a main window, copy and paste the code into it's scripting window. Comment out the code below that line ("Ctrl + /"), and print the value of "row".

Dataset = event.source.Data
row = Dataset.getRowCount()-1
print "my row value: %s" % row

#end = Dataset.getValueAt(row,1)
#start = Dataset.getValueAt(0,1)
#change = end - start
#event.source.parent.getComponent('Label and Label (1)').Value = change
1 Like

Since you only want this to happen when Data changes, you can add a ‘filter’ to check what property changed:

if event.propertyName == 'Data':
	Dataset = event.source.Data
	row = Dataset.getRowCount()-1
	end = Dataset.getValueAt(row,1)
	start = Dataset.getValueAt(0,1)
	change = end - start
	event.source.parent.getComponent('Label and Label (1)').Value = change
1 Like

Oh I see what you guys mean by filters now. I was thinking about this the other day but didn’t really put too much thought into it. I will check this and see if it changes anything.

I would agree that a filter is absolutely needed in this case (actually in all cases). It appears that the script is running when the data property is still empty, which would cause getRowCount() to return 0 meaning that line 3 would be trying to access the value at [-1,1]. Resulting in the Index out of bounds exception.

3 Likes

Yes! The filter was what was needed. Thank you all so much! My property change scripts will always have filters from now on!

1 Like