akenza.io
Search…
Stateful Operations
Sharing data between rule runs
Alongside user-defined inputs and parameters for Custom Logic Blocks, the implicit event property called state is provided. Using the state allows users to persist and share data between different rule runs ("memory"). This can be achieved by the emitting state which will be accessible in the next rule run. The state property is shared only between runs of the same rule, regardless of the source that triggered a rule execution.
Accessing the rule state property from a Custom Logic Block script:
1
function consume(event) {
2
var ruleState = event.state || {};
3
//your implementation goes here...
4
}
Copied!
Initially event.state property is an empty object!
An example of updating a rule state property from Custom Logic Block script:
1
function consume(event) {
2
var ruleState = event.state || {};
3
//your implementation goes here...
4
ruleState["numOfSamples"] = numOfSamples;
5
emit('state', ruleState);
6
}
Copied!
or
1
function consume(event) {
2
//your implementation goes here...
3
emit('state', { "numOfSamples": numOfSamples });
4
}
Copied!
An example of a Custom Logic Block script that makes use of the state property:
1
function consume(event) {
2
var temperature = event.inputs["temp1"];
3
var threshold = event.properties["tempT"];
4
var ruleState = event.state;
5
if (temperature > threshold) {
6
var numOfSamples = ruleState.numOfSamples;
7
if (typeof numOfSamples !== "undefined") {
8
numOfSamples = numOfSamples + 1;
9
} else {
10
numOfSamples = 1;
11
}
12
emit('state', { "numOfSamples": numOfSamples });
13
//Emitting action when numOfSamples is an even number
14
if (numOfSamples % 2 === 0) {
15
emit('action', { "message": "Rule has triggered the action!", "addedTemp": threshold + temperature });
16
}
17
}
18
}
Copied!
The rule state will be reset on rule deactivation or deletion. Once a rule is activated again, the rule state property will be set to a default value.
A more advanced example of using rule state:
1
// rule that adaptively changes the threshold based on the average temperature
2
3
function consume(event) {
4
const alpha = 0.2;
5
const initialThreshold = event.properties.initialThreshold;
6
const currentTemperature = event.inputs.temperature;
7
8
let state = event.state || {};
9
let movingAverage = state.movingAverage || 0;
10
let threshold = state.threshold || initialThreshold;
11
12
let numberOfSamples = state.numberOfSamples || 0;
13
14
//compute a moving average
15
movingAverage =
16
(currentTemperature + numberOfSamples * movingAverage) /
17
(numberOfSamples + 1);
18
19
// let's define the threshold by 20% above the average
20
const currentThreshold = movingAverage * 1.2;
21
22
// exponentially smooth the threshold in order to account
23
// for the phase where not much data is present
24
threshold = alpha * currentThreshold + (1 - alpha) * threshold;
25
if (currentTemperature > threshold) {
26
emit("action", {
27
message: `temperature (${currentTemperature}°C) is above threshold (${threshold})`,
28
});
29
}
30
31
numberOfSamples += 1;
32
state = { threshold, numberOfSamples, movingAverage };
33
emit("state", state);
34
}
35
Copied!
Last modified 4mo ago
Copy link