[IGN-16242]system.util.queryStatus doesn't return AlarmQueryResult

From the docs we're told that system.util.queryStatus() returns AlarmQueryResult see here

When I run it in the design console I get this:

#Pull all alarms
alarms = system.alarm.queryStatus(state=["ActiveUnacked", "ActiveAcked"], source=["*AJAX Alarm*"])
type(alarms)
alarms.getDataset()

# I get this
>>> 
<type 'java.util.Collections$UnmodifiableRandomAccessList'> # not AlarmQueryResult!!!
Traceback (most recent call last):
  File "<input>", line 4, in <module>
AttributeError: 'java.util.Collections$UnmodifiableRandomAccessList' object has no attribute 'getDataset'
>>>

Am I missing something? I need to turn the alarms into a dataset

I'm on 8.3.1

This is a bug caused by some "under the hood" changes from 8.3. We're tracking it internally at a fairly high priority - it'll likely be fixed in 8.3.4 or shortly therafter.

In the meantime, you could try this as a workaround:

from com.inductiveautomation.ignition.common.alarming.query import AlarmQueryResultImpl

def datasetFromAlarms(alarms, historical=False):
		inner = AlarmQueryResultImpl(historical) # pass True if using queryJournal
		inner.extend(alarms)
		return inner.dataset

alarms = system.alarm.queryStatus(state=["ActiveUnacked", "ActiveAcked"])
ds = datasetFromAlarms(alarms)

Great! thanks for the workaround

Running into this same issue on 8.3.2. When I run the workaround in the Script Console I’m getting a ClassCastException. Something obvious I’m doing wrong?

Java Traceback
Traceback (most recent call last):
  File "<input>", line 4, in <module>
	at com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResultImpl.buildFrom(AlarmQueryResultImpl.java:60)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.ClassCastException: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent cannot be cast to class com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult (com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent and com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult are in unnamed module of loader java.net.URLClassLoader @124d25a0)

	at org.python.core.Py.JavaError(Py.java:545)
	at org.python.core.Py.JavaError(Py.java:536)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:192)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:208)
	at org.python.core.PyObject.__call__(PyObject.java:461)
	at org.python.core.PyObject.__call__(PyObject.java:465)
	at org.python.pycode._pyx125.f$0(<input>:5)
	at org.python.pycode._pyx125.call_function(<input>)
	at org.python.core.PyTableCode.call(PyTableCode.java:173)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1703)
	at org.python.core.Py.exec(Py.java:1747)
	at org.python.util.PythonInterpreter.exec(PythonInterpreter.java:277)
	at org.python.util.InteractiveInterpreter.runcode(InteractiveInterpreter.java:130)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:628)
	at com.inductiveautomation.ignition.designer.gui.tools.jythonconsole.JythonConsole$ConsoleWorker.doInBackground(JythonConsole.java:616)
	at java.desktop/javax.swing.SwingWorker$1.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.desktop/javax.swing.SwingWorker.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent cannot be cast to class com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult (com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent and com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult are in unnamed module of loader java.net.URLClassLoader @124d25a0)
	at com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResultImpl.buildFrom(AlarmQueryResultImpl.java:60)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	... 19 more
Traceback (most recent call last):
  File "<input>", line 4, in <module>
	at com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResultImpl.buildFrom(AlarmQueryResultImpl.java:60)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.ClassCastException: java.lang.ClassCastException: class com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent cannot be cast to class com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult (com.inductiveautomation.ignition.common.alarming.BasicAlarmEvent and com.inductiveautomation.ignition.common.alarming.query.AlarmQueryResult are in unnamed module of loader java.net.URLClassLoader @124d25a0)

Test Code
from com.inductiveautomation.ignition.common.alarming.query import AlarmQueryResultImpl

alarms = system.alarm.queryStatus(state=["ActiveUnacked", "ActiveAcked"])
AlarmQueryResultImpl.buildFrom(alarms)
ds = alarms.getDataset()

You'll need to query your own journal in the source keyword argument

you haven't handed your query a source yet

My bad, my (untested) workaround was flawed because I misunderstood what the 'buildFrom' method was for.

Try this (original post updated as well):

from com.inductiveautomation.ignition.common.alarming.query import AlarmQueryResultImpl

def datasetFromAlarms(alarms, historical=False):
		inner = AlarmQueryResultImpl(historical) # pass True if using queryJournal
		inner.extend(alarms)
		return inner.dataset

alarms = system.alarm.queryStatus(state=["ActiveUnacked", "ActiveAcked"])
ds = datasetFromAlarms(alarms)

That did the trick - thanks for the fast fix!

Hey Paul, will this still work after this bug is fixed?

Good question - yes, it should continue to work, because public class AlarmQueryResultImpl extends ArrayList<AlarmEvent>, so even once the queryStatus function goes back to properly returning an AlarmQueryResultImpl directly the .extend call within will still work, since Jython is providing it for any List-like.

This bug (and the corresponding issue with Vision's alarm status and journal tables) are fixed in 8.3.4, projected release very soon. today :smiley:

Heads up, I am still seeing this issue on 8.3.5. I have a basic script similar to the original post where I am trying to use .getDataset() on the result of system.alarm.queryStatus and I am seeing the same issue with the type being "java.util.Collections$UnmodifiableRandomAccessList".

#get my alarm source value
path = "[default]DemoControlModules/Demo_P_AIn/Hi/Alm/Alarms/Alarm.Source"
source = system.tag.readBlocking([path])[0].value

#query the alarm status
alarmQueryResult = system.alarm.queryStatus(source = [source])
print alarmQueryResult

#attempt to use getDataset
if len(alarmQueryResult) > 0:
    eventIds = alarmQueryResult.getDataset()
    print eventIds

Gives me the following output:

image

I am running Ignition in the official Inductive Docker container (8.3.5 tag), if that makes any difference.

Thanks for the report. We fixed it in the Vision alarm status and journal tables, but missed the scripting functions due to an oversight. I've filed a new ticket that we'll get fixed soon.