cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X

What is the best way to achieve Complex Event Processing (CEP)?

mnoack-2
1-Newbie

What is the best way to achieve Complex Event Processing (CEP)?

Hello,

I'd like to ask how Complex Event Processing could be achieved in ThingWorx Composer for evaluating value streams. For example timescale based events:

When the lamp is switched to ON/OFF 3 times within 10 seconds - fire an special event / call a special service.

or:

When the motion sensor A was triggered 10 times within the last hour and motion sensor B was triggered 30 % less - call a specific service.

Is that possible out of the box? What would be a best practice to implement rules like this?

Thank you very much,

Markus

4 REPLIES 4
Aanjan
9-Granite
(To:mnoack-2)

Markus, you could look into adding Alerts to that property and/or subscriptions. To start off simply, do you have access to ThingWorx tutorials? I believe there were some exercises around adding alerts to specific properties so that once they reach that value, a subscription would be triggered based on that.

Hi Markus,

I implemented such scenarios with a combination of Alerts and Converge BusinessProcesses (BP) with evaluations in custom, javascript-based services.

The scenario that I implemented was the following:

  1. Exceeding a temperature threshold triggers an Alert
  2. The Alert triggers a BP
  3. In the BP an evaluation robot that used a Thing with a custom service that queried the Alert History and counted
    the number of Alerts of a type in a specified timeframe. The code used in the AlertRuleValidator is shown below.
  4. The result is a Boolean that is used to route the BP for the action that has to encapsulated in another custom service.
    In my case I used the ServiceMax ‘CreateCase’ service.

Here is how the BP looks like:

BPE2.png

BPE1.png

Here is the signature of the AlertRuleEvaluator.ValidateAlertCountInTimespan() service:

AlertRuleValidatorSignature0.png

and here is the code I used:

//if alert source is a thing, then do it once, otherwise for all by QueryImplThing/Shape
//for now I impl only per Thing
var result = "false";
logger.info("eventInfo: "+eventInfo.ToJSON());

if(eventInfo.eventData){
    var alertDetails=eventInfo.eventData.getRow(0);
    //specify query based on input param
    var startDate, endDate = eventInfo.eventTime;
    switch(TimeUnit){
        case 'MILLIS':  startDate = dateAddMilliseconds( endDate, -1*Timespan); break;
        case 'SECONDS': startDate = dateAddSeconds( endDate, -1*Timespan); break;
        case 'MINUTES': startDate = dateAddMinutes( endDate, -1*Timespan); break;
        case 'HOURS':  startDate = dateAddHours( endDate, -1*Timespan); break;
        case 'DAYS':  startDate = dateAddDays( endDate, -1*Timespan); break;
        case 'MONTHS':  startDate = dateAddMonths( endDate, -1*Timespan); break;
        case 'YEARS':  startDate = dateAddYears( endDate, -1*Timespan); break;
        default:  startDate = dateAddSeconds( endDate, -1*Timespan); break;
    }
    logger.info("timespan: from "+startDate+" to "+endDate);
    var query = {
      "filters": {
        "type": "AND",
        "filters": [
          {
            "fieldName": "name",
            "type": "EQ",
            "value": alertDetails.name
          },
          {
            "fieldName": "sourceProperty",
            "type": "EQ",
            "value": eventInfo.sourceProperty
          },
          {
            "fieldName": "eventName",
            "type": "EQ",
            "value": eventInfo.eventName
          }
        ]
      }
    };
    logger.info("query: "+JSON.stringify(query));
    var params = {
        startDate: startDate /* DATETIME */,
        endDate: endDate /* DATETIME */,
        query: query /* QUERY */,
        name: eventInfo.source
    };

    // result: INFOTABLE dataShape: AlertHistory
    var foundAlerts = Resources["AlertFunctions"].QueryAlertHistory(params);
    logger.info("foundAlerts: "+foundAlerts.ToJSON());
   
    result = ((foundAlerts.rows.length > AlertCountThreshold)).toString();
}

I hope this gives you an impression how CEP can be implemented with ThingWorx.
Best regards, moritz

Hey Moritz, this seems to be very promising - thank you for this!

However,  I think unfortunately I do not have access to the Converge Business Process Editor because I am in the academic program.

Hey Aanjan, I am familiar with subscriptions - what I want to achieve is that the alert only triggers if a number of events occur in a defined time window. Normal alerts simply trigger when a threshold is reached, but I only want to fire an event when this threshold triggered i.e. 3 times within 10 seconds.

Maybe someone has any other ideas how to do this ?

My current solution would be to send relevant values out to a CEP-Engine like Esper or WSO2 an then trigger a service via REST API if a match is found, but it would be nicer to have all the logic in ThingWorx.

qngo
5-Regular Member
(To:mnoack-2)

Hi, I think about a work-around. I'd create a new Thing which contains a property "counter" and a property "startingTime", or keep the same thing with these two new properties.

The first time the threshold is reached, a first alert increases this "counter" and set the date for "startingTime". The next time the threshold is reached, the alert checks firstly if "startingTime" + 10 seconds < now, then the counter will be incremented by 1 or set "counter" back to 1.

A second alert of "counter" will be triggered if it reach 3 in order to do the "real" action.

Top Tags