Something changed between Ignition 8.3.0 and 8.3.4 such that the AggregationModes passed by TagHistoryQueryParams to TagHistoryManager.queryHistory() can no longer be null (an exception is thrown now).
I don’t want any aggregation, I just want raw data, so I tried passing in an empty list. An exception is no longer thrown, but now a weird data point is returned that is in the future. It seems like maybe it’s the last value? But it has a future timestamp, roughly eight hours into the future. Maybe a timezone weirdness?
Anyone have any idea what this is? Is there a proper way to specify that you do not want any aggregation to be done?
The history provider in this case is Core Historian.
Forgot to say:
I verified that the same code (i.e., an empty AggregationModes list) running under 8.3.0 does not produce the anomalous value at the end.
What issue are you getting when you pass null?
Javadocs on TagHistoryQueryParams suggest it should be allowed:
/**
* If not null, must be 1-to-1 list corresponding to tag paths, specifying the aggregation mode
* for the column. If the list is null, or a particular entry is null, the general aggregation
* mode will be used instead.
*/
List<Aggregate> getColumnAggregationModes();
Here are my query params (without specifying AggregationModes)
BasicTagHistoryQueryParams queryParams = BasicTagHistoryQueryParams.newBuilder()
.paths(tagPathList)
.startDate(startDate)
.endDate(endDate)
.queryFlags(Flags.of(
TagHistoryQueryFlags.BOUNDING_VALUES_YES,
TagHistoryQueryFlags.NO_INTERPOLATION,
TagHistoryQueryFlags.NO_PREPROCESSED_DATA
))
.returnSize(0)
.returnFormat(ReturnFormat.Tall)
.build();
and here’s the exception:
jvm 1 | java.lang.NullPointerException: Cannot invoke "java.util.List.isEmpty()" because the return value of "com.inductiveautomation.ignition.common.sqltags.history.TagHistoryQueryParams.getColumnAggregationModes()" is null
jvm 1 | at com.inductiveautomation.historian.gateway.query.writing.HistoryWriter.hasNoAggregation(HistoryWriter.java:183)
jvm 1 | at com.inductiveautomation.historian.gateway.query.writing.HistoryWriter.calculateBlockSize(HistoryWriter.java:194)
jvm 1 | at com.inductiveautomation.historian.gateway.query.writing.HistoryWriter.<init>(HistoryWriter.java:82)
jvm 1 | at com.inductiveautomation.historian.gateway.query.writing.TallHistoryWriter.<init>(TallHistoryWriter.java:16)
jvm 1 | at com.inductiveautomation.historian.gateway.HistorianManagerImpl.createHistoryWriter(HistorianManagerImpl.java:1776)
jvm 1 | at com.inductiveautomation.historian.gateway.HistorianManagerImpl.queryHistory(HistorianManagerImpl.java:1083)
jvm 1 | at com.inductiveautomation.ignition.gateway.sqltags.history.TagHistoryManagerBridge.queryHistory(TagHistoryManagerBridge.java:99)
jvm 1 | at com.seeq.ignition.v83.gateway.link.IgnitionGatewayConnection.getSamplesViaTagHistoryManager(IgnitionGatewayConnection.java:1539)
jvm 1 | at com.seeq.ignition.v83.gateway.link.IgnitionGatewayConnection.getSamples(IgnitionGatewayConnection.java:1604)
jvm 1 | at com.seeq.link.sdk.DatasourceConnectionV2Host.signalRequest(DatasourceConnectionV2Host.java:1790)
jvm 1 | at com.seeq.link.sdk.BaseDatasourceConnection.processMessage(BaseDatasourceConnection.java:492)
jvm 1 | at com.seeq.link.sdk.BaseDatasourceConnection.lambda$processMessage$2(BaseDatasourceConnection.java:425)
jvm 1 | at com.seeq.link.sdk.BaseDatasourceConnection.lambda$processMessage$0(BaseDatasourceConnection.java:417)
jvm 1 | at com.seeq.link.sdk.utilities.DefaultConcurrentRequestsHandler.lambda$runWhenPermitted$0(DefaultConcurrentRequestsHandler.java:71)
jvm 1 | at com.seeq.link.sdk.utilities.ThreadCollection$Worker.run(ThreadCollection.java:313)
jvm 1 | at com.seeq.link.sdk.utilities.ThreadCollection.lambda$spawn$2(ThreadCollection.java:170)
jvm 1 | at java.base/java.lang.Thread.run(Unknown Source)
Explicitly specifying null has the same effect.
E.g.
BasicTagHistoryQueryParams queryParams = BasicTagHistoryQueryParams.newBuilder()
.paths(tagPathList)
.startDate(startDate)
.endDate(endDate)
.queryFlags(Flags.of(
TagHistoryQueryFlags.BOUNDING_VALUES_YES,
TagHistoryQueryFlags.NO_INTERPOLATION,
TagHistoryQueryFlags.NO_PREPROCESSED_DATA
))
.aggregationModes(null)
.returnSize(0)
.returnFormat(ReturnFormat.Tall)
.build();
I’ll mention that the stack trace shows Ignition calling a hasNoAggregation() function, which tries to look if the list is empty. That’s why I tried handing in an empty list, which seems to be what it wants.
The problem now is that there is an anomalous value returned as the final sample, as described in the original post.
Yeah, the NPE is just a bug where we're not being sufficiently defensive. I'm not sure what's going on with the anomalous result but I'll point the history team at this thread and see if they can explain what's going on.
Following up, that added post value should be removed as of the 8.3.5 nightlies.
2 Likes
@Kurt.Larson – I confirmed that the current 8.3.5 nightly no longer has the anomalous value. Thank you!
1 Like