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:

  1. 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.

  2. Id selection - targets one or a number of devices selected via their concrete IDs.

  3. 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