Search code examples
javadroolsruledrools-fusion

Drools rules for different users


I recently started programming with Drools Fusion and I have a smart wearable that sends pedometer and heart rate data to my laptop. I then process this data with using the drools rule language. But suppose I have multiple smart wearables with each an unique MAC address. I use time windows and my question is how can I change my rule file so that the rules only fire for events with the same macaddress and take appropiate action based on this MAC address. My current rule file is the following:

import hellodrools.Steps
import hellodrools.HeartRate
import hellodrools.AppInfo

declare AppInfo
    @role(event)
end

declare Steps
    @role(event)
end

declare HeartRate
    @role(event)    
end


rule "ACC STEPS RULE"
when
    accumulate( Steps( $s : steps )
                over window:time( 1h ) from entry-point "entrySteps"; 
        $fst: min( $s ), $lst: max( $s );
        $lst - $fst < 50 )
then
    System.out.println("STEPS RULE: get moving!");
    System.out.println($lst + "   " + $fst);

end

rule "HEARTRATE RULE 1"
when
    $heartrate : HeartRate(heartRate >= 150) from entry-point "entryHeartRate"
then
    System.out.println("Heartrate is to high!");
end

rule "HEARTRATE RULE 2"
when
    $heartrate : HeartRate(heartRate <= 50 && heartRate >= 35) from entry-            point "entryHeartRate"
then
    System.out.println("Heartrate is to low!");
end

rule "HEARTRATE RULE 3"
when
    $heartrate : HeartRate(heartRate < 35 && heartRate >= 25) from entry-point "entryHeartRate"
then
    System.out.println("Heartrate is critical low!");
end

rule "HEARTRATE RULE 4"
when
    $max : Double() from accumulate(
        HeartRate( $heartrates : heartRate ) over window:time( 10s ) from entry-point "entryHeartRate",
        max( $heartrates ) )&&
    $min : Double() from accumulate(
        HeartRate( $heartrates : heartRate ) over window:time( 10s ) from entry-point "entryHeartRate",
        min( $heartrates ) )&&
    eval( ($max - $min) >= 50 )
then
    System.out.println("Heartrate to much difference in to little time!");
end

My HeartRate events have the following fields:

int heartRate;
Date timeStamp;
String macAddress;

My Steps events have the following fields:

double steps;
Date timeStamp;
String macAddress;

Solution

  • This is simple: you need to define a fact, call it Walker with String macAddress, create it with the MAC address the rules should handle, and then

    rule "ACC STEPS RULE"
    when
      Walker( $mac: macAddress )
      accumulate( Steps( $s : steps, macAddress == $mac )
                  over window:time( 1h ) from entry-point "entrySteps"; 
          $fst: min( $s ), $lst: max( $s );
          $lst - $fst < 50 )
      then ... end
    

    and similarly with the other rules. - You may simplify this (a little) by defining a basic rule

    rule "MAC"
    when
      Walker( $mac: macAddress )
    then end
    

    and write the other rules as extensions:

    rule "ACC STEPS RULE" extends "MAC" ...
    

    so you don't need to repeat the Walker pattern for each rule.