Working with rules
Rules are administrative statements of what the system should do in specific situations. They define automated executions of action scripts that are triggered when arbitrary functional states or events occur. Each triggering of a rule launches tasks, corresponding to the number of involved devices, or in other words, rules automate the execution of tasks.
You are already familiar with how to manage rules through Bosch IoT Manager's Console. In this page we will go through a typical rule-based scenario, programmatically, via Bosch IoT Manager's Java API.
The following examples show you how to create, enable, fire and delete a rule, as well as how to subscribe for events:
Access the service
Initially, you need to establish a connection to the Mass Management remote service. To do so, refer to the Mass Management Engine-related steps described in Remote access to Bosch IoT Manager.
Once the connection is successfully established, you may continue with concrete interactions with the Mass Management remote service, such as:
Create a rule
Creating a rule involves the same mechanism as when using the Bosch IoT Manager UI:
-
Specify the rule script action
JsonObjectBuilder builder = JsonObject.newBuilder();
builder.set(JsonField.newInstance(
"groovyScript"
, JsonValue.of(
"println(target.deviceId())"
)));
Action action = Action.create(
"groovyScript"
, builder.build());
-
Specify the rule scope
When using device scope, you can choose between three scope selection modes to specify the devices of interest:
Group selection - targets a group of devices via their directory You can refine them through a Groovy script, RQL filter or through tags associated to them.
Id selection - targets one or a number of devices selected via their concrete IDs.
Groovy selection - targets devices via a list script that can be optionally filtered through a filter script.
See how to create each of them in the code snippet below:
GroupSelection.Builder groupSelectionBuilder = GroupSelection.newBuilder();
groupSelectionBuilder.directoryPath(
"/"
);
groupSelectionBuilder.recursive(
true
);
groupSelectionBuilder.gatewaysOnly(
true
);
groupSelectionBuilder.filteringScript(
""
);
groupSelectionBuilder.rqlQuery(
""
);
groupSelectionBuilder.tags(Collections.emptyList());
Selection groupSelection = groupSelectionBuilder.build();
Selection idsSelection = IdSelection.newBuilder()
.deviceIds(Collections.singletonList(
"deviceId"
))
.build();
Selection groovySelection = GroovySelection.newBuilder()
.listingScript(
"target.deviceId().contains(\"someString\")"
)
.build();
DeviceScope<Selection> deviceScope = DeviceScope.create(groupSelection);
-
Specify the rule triggers
The following code snippet demonstrates how to create a Cron, device event or manual trigger, and how to add them to the list of triggers:
String cronExpresion =
"cron expresion"
;
TriggerFireDef cronFireDef = TriggerFireDef.create(
"cron.trigger"
, JsonObject.newBuilder().set(
"expression"
, cronExpresion).build());
String dittoConnectionStatusAddedEvent =
"FeaturesEvents/org.eclipse.ditto:ConnectionStatus:1.0.0/ConnectionStatusAdded"
;
String deviceOnlineEvent =
"DeviceOnlineEvent"
;
TriggerFireDef eventFireDef = TriggerFireDef.create(
"device.events.trigger"
, JsonObject.newBuilder().set(
"eventType"
, deviceOnlineEvent).build());
TriggerFireDef manualFireDef = TriggerFireDef.create(
"mme.manual.trigger"
,
null
);
Trigger trigger = Trigger.create(cronFireDef);
TriggerList triggerList = TriggerList.create(trigger);
triggerList.addTriggerelement(Trigger.create(eventFireDef));
-
Add rule execution options if needed
You can, optionally, add rule execution options:
RuleParameters ruleParameters = RuleParameters.newBuilder()
.name(
"RuleName"
)
.action(action)
.scope(deviceScope)
.trigger(triggerList)
// A rule may have one or more triggers
.execOptions(ExecOptions.create())
//Execution options have sensible defaults otherwise can be configured trough dedicated methods
.build();
CompletionStage<Rule>rule = mme.createRule(ruleParameters);
Subscribe for rule events
In order to subscribe for rule events follow the pattern:
AtomicReference<StreamHandler> streamHandler =
new
AtomicReference<>();
rule.subscribeForRuleEvents(Arrays.asList(RuleEvent.Type.values()),
new
StreamConsumer<RuleEvent>() {
@Override
public
void
opened(StreamHandler handler) {
streamHandler.set(handler);
/**
* Request count events from the stream/channel. This allows back-pressure for the stream/channel.
* If the consumer of the events doesn't want to use back-pressure it may call this method with count -1.
* Note that before this method has been called no events will be sent to the consumer.
*/
handler.request(-
1
);
}
@Override
public
void
accept(RuleEvent next) {
// do something
}
@Override
public
void
close(Throwable error) {
// close the error handler
}
});
Subscribe for task events
In order to listen for task events coming from tasks, created by a rule:
rule.subscribeForTaskEvents(Arrays.asList(TaskEvent.Type.values()),
new
StreamConsumer<TaskEvent>() {
@Override
public
void
opened(StreamHandler handler) {
handler.request(-
1
);
}
@Override
public
void
accept(TaskEvent next) {
// do something
}
@Override
public
void
close(Throwable error) {
// close the error handler
}
});
Enable a rule
All rules must be enabled in order to be triggered/fired:
rule.enable();
Оnce enabled, the rule turns into state Rule.State.ENABLED and may be triggered either manually or automatically according to its defined triggers.
Fire a rule
To fire a rule manually execute:
rule.fire();
View device state
Once the rule has been fired, execute the following code to view the state of all involved devices:
CompletionStage<List<DeviceRuleStatus>> deviceRuleStatuses = rule.listInvolvedDevices(DeviceExecStatus.State.ANY);
Modify a rule
Modifying the rule properties is possible in the following manner:
rule.modify(rule.getDisplayName() +
"edited"
, rule.getScope(), rule.getTrigger(), rule.getExecOptions(), rule.getAction());
Note that modifying a rule will reset all statistics for it. So in order to edit a rule, it must not be in Rule.State.ENABLED state.
Delete a rule
To delete a rule use:
rule.delete();
Deleting a rule also deletes all tasks created by it