How to use 'previousRawValue' and 'previousBlockResults' in a Custom Tag History Aggregate function

blockContext.previousRawValue and blockContext.previousBlockResults as described in the Custom Tag History Aggregates documentation are actually bound functions and must be utilized with parentheses to get the expected return value/object. Perhaps that is obvious to others but it took quite a bit of tinkering to figure that out and thought I’d share as there is very little mention of those in the forums.

Example Usage:

	print "blockContext.previousRawValue: {}".format(blockContext.previousRawValue) #  - QualifiedValue, the previous non-interpolated value received before this window
	print "blockContext.previousBlockResults: {}".format(blockContext.previousBlockResults) #  - QualifiedValue[], the results of the previous window.
	print "blockContext.previousRawValue(): {}".format(blockContext.previousRawValue()) #  - QualifiedValue, the previous non-interpolated value received before this window
	print "blockContext.previousBlockResults(): {}".format(blockContext.previousBlockResults()) #  - QualifiedValue[], the results of the previous window.

Results:

INFO   | jvm 2    | 2022/09/07 18:14:09 | blockContext.previousRawValue: bound method com.inductiveautomation.ignition.gateway.sqltags.history.query.processing.BlockContext.previousRawValue of {u'count': 1}
INFO   | jvm 2    | 2022/09/07 18:14:09 | blockContext.previousBlockResults: bound method com.inductiveautomation.ignition.gateway.sqltags.history.query.processing.BlockContext.previousBlockResults of {u'count': 1}
INFO   | jvm 2    | 2022/09/07 18:14:09 | blockContext.previousRawValue(): {v=43.54100036621094, q=Good, ts=Wed Sep 07 18:14:01 CDT 2022, intrp=false}
INFO   | jvm 2    | 2022/09/07 18:14:09 | blockContext.previousBlockResults(): array(com.inductiveautomation.ignition.common.model.values.QualifiedValue, [[-88, Good, Wed Sep 07 18:04:08 CDT 2022 (1662591848114)]])

@Colby.Clegg This is/was not clear in the documentation (to me), I suggest updating the documentation text and examples. I directed that comment at you solely because you provided the earliest reference to the documentation that I could find in the forums. Thanks.

Ignition v8.1.19

Specifically, the objects in question are a BlockContext and a QueryContext. We can definitely get the manual updated with more information.

1 Like

A few other items that I discovered with testing and are covered in the documentation but are easy to miss…

  • You can write your own key/value pairs to the blockContext dictionary and these persist across evaluation of samples within a given time window (block), blockContext is reset for each time window (block).
  • You can write your own key/value pairs to the queryContext dictionary and these persist across evaluation of remaining samples for all blocks (does not reset).
    Example Usage:
def print2log(qval, interpolated, finished, blockContext, queryContext):
	blockContextCount = int(blockContext.getOrDefault('count',0)) + 1
	blockContext['count'] = blockContextCount
	
	queryContextCount = int(queryContext.getOrDefault('count',0)) + 1
	queryContext['count'] = queryContextCount

	print '--- Query Sample: {} | Block ID: {} | Block Sample: {} ---'.format(queryContextCount, blockContext.blockId, blockContextCount)

	if finished:
		print '----------'
		return "Output to wrapper.log"

Results:

INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 1 | Block ID: 0 | Block Sample: 1 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 2 | Block ID: 0 | Block Sample: 2 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | ----------
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 3 | Block ID: 0 | Block Sample: 1 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 4 | Block ID: 0 | Block Sample: 2 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 5 | Block ID: 0 | Block Sample: 3 ---
...
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 53 | Block ID: 0 | Block Sample: 51 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 54 | Block ID: 0 | Block Sample: 52 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | ----------
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 55 | Block ID: 1 | Block Sample: 1 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 56 | Block ID: 1 | Block Sample: 2 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 57 | Block ID: 1 | Block Sample: 3 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 58 | Block ID: 1 | Block Sample: 4 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | ----------
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 59 | Block ID: 2 | Block Sample: 1 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 60 | Block ID: 2 | Block Sample: 2 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 61 | Block ID: 2 | Block Sample: 3 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 62 | Block ID: 2 | Block Sample: 4 ---
INFO   | jvm 2    | 2022/09/07 19:02:05 | ----------
INFO   | jvm 2    | 2022/09/07 19:02:05 | --- Query Sample: 63 | Block ID: 3 | Block Sample: 1 ---

@PGriffith I noticed that the Block ID of 0 (zero) is used for two different blocks, not sure if that is a bug. I’ll investigate further.

It's entirely possible it's a bug. As you may have noticed, this feature hasn't gotten much attention since it was first implemented.