Search code examples
javarule-enginecomplex-event-processingesper

Esper rules for different users


I recently started programming with Esper and I have a smart wearable that sends pedometer data to my laptop. I then process this data using esper. 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 initialization and rule are:

    Configuration cepConfig = new Configuration();

    cepConfig.addEventType("Steps", Steps.class.getName());

    // We setup the engine
    EPServiceProvider cep = EPServiceProviderManager.getProvider("myCEPEngine", cepConfig);
    EPRuntime cepRT = cep.getEPRuntime();

    // We register an EPL statement
    EPAdministrator cepSteps1 = cep.getEPAdministrator();
    EPStatement cepStatementSteps1 = cepSteps1.createEPL("select * from "
            + "Steps().win:time(1 hour) "
            + "group by macAddress "
            + "having sum(max(steps)-min(steps)) < 100");
    cepStatementSteps1.addListener(new rule1Listener());

My Steps class has the following fields:

double steps;
String stepsTimestamp;
String macAddress;

And this is how I insert the events:

Steps steps0 = new Steps(0, new Date(timeStamp).toString(), "K5E45H778");
cepRT.sendEvent(steps0);
Steps steps00 = new Steps(0, new Date(timeStamp).toString(), "LD24ESF74");
cepRT.sendEvent(steps00);
Steps steps1 = new Steps(25, new Date(timeStamp).toString(), "K5E45H778");
cepRT.sendEvent(steps1);
Steps steps2 = new Steps(50, new Date(timeStamp).toString(), "LD24ESF74");
cepRT.sendEvent(steps2);
Steps steps3 = new Steps(55, new Date(timeStamp).toString(), "K5E45H778");
cepRT.sendEvent(steps3);
Steps steps4 = new Steps(105, new Date(timeStamp).toString(), "LD24ESF74");
cepRT.sendEvent(steps4);
Steps steps5 = new Steps(75, new Date(timeStamp).toString(), "K5E45H778");
cepRT.sendEvent(steps5);
Steps steps6 = new Steps(110, new Date(timeStamp).toString(), "K5E45H778");
cepRT.sendEvent(steps6);

This is my output:

Sending tick:    Steps: 0.0 Timestamp: Mon Mar 14 18:13:23 CET 2016 Mac Address: K5E45H778
->Rule 1 fired: K5E45H778
Sending tick:    Steps: 0.0 Timestamp: Mon Mar 14 18:18:23 CET 2016 Mac Address: LD24ESF7474
->Rule 1 fired: LD24ESF7474
Sending tick:    Steps: 25.0 Timestamp: Mon Mar 14 18:23:23 CET 2016 Mac Address: K5E45H778
->Rule 1 fired: K5E45H778
Sending tick:    Steps: 105.0 Timestamp: Mon Mar 14 18:28:23 CET 2016 Mac Address: LD24ESF7474
Sending tick:    Steps: 55.0 Timestamp: Mon Mar 14 18:33:23 CET 2016 Mac Address: K5E45H778
->Rule 1 fired: K5E45H778
Sending tick:    Steps: 75.0 Timestamp: Mon Mar 14 18:38:23 CET 2016 Mac Address: K5E45H778
Sending tick:    Steps: 110.0 Timestamp: Mon Mar 14 18:43:23 CET 2016 Mac Address: K5E45H778

Why doesn't the rule fire for the one but last event of 75 steps?


Solution

  • The SQL-standard "group by" clause is for aggregation per group. Thus just adding "group by macAddress" should get it done.