2016-04-20 14 views
1

Ich möchte eine Regel in Esper schreiben, die ausgelöst wird, wenn die Anzahl der Schritte in den letzten 15 Minuten 0 ist und die Herzfrequenz über 120 liegt. Ich habe folgende Regel aufgestellt:Esper Regelsprache: Timer für Regel verwenden

EPStatement cepStatementRule8 = cepRule.createEPL("context PartitionByMacSteps select * from " 
       + "Steps.win:time(15 min) S, HeartRate.win:time(1 min) H " 
       + "having (max(S.steps)-min(S.steps) = 0) and (H.heartrate > 120)"); 
     cepStatementRule8.addListener(new rule8Listener()); 

Meine Herzfrequenz-Klasse hat die folgenden Felder:

int heartrate; 
String heartratesTimestamp; 
String macAddress; 

Und meine Schritte Klasse hat diese Felder:

int steps; 
String stepsTimestamp; 
String macAddress; 

Das Problem, dem ich gegenüberstehe, ist, dass ich die Regel nur dann aktivieren möchte, wenn in den letzten 15 Minuten keine Schritte unternommen werden. Jetzt wird es ausgelöst, wenn zwei Schritt-Ereignisse die gleiche Anzahl von Schritten haben. Ich weiß, dass ich wahrscheinlich timer.interval verwenden muss, aber ich konnte nicht herausfinden, wie man diese Regel schreibt. Kann mir jemand helfen?

Antwort

0

Die Anforderungen sind schlecht definiert. Was bedeutet "Herzfrequenz über 120" bedeutet wirklich, ist es nur einmal oder für 15 Minuten oder 1 Minute und darüber hinaus wie sich "Herzfrequenz über 120" überschneidet oder mit der Schrittbedingung übereinstimmt.

Ich würde empfehlen, das Problem in zwei unabhängige Zustandserkennung zu zerlegen und dann einen Join, um festzustellen, dass beide Bedingungen zu einem Zeitpunkt aufgetreten sind. Dies macht es auch leicht zu testen, da Sie sehen können, dass jeder Zustand separat angezeigt wird. ungefähr so ​​zum Beispiel etwas:

// detect the steps condition 
insert into StepConditionDetected 
select *, current_timestamp as detectedTime select * from pattern[...]; 

// detect the heartrate condition 
insert into HeartrateConditionDetected 
select *, current_timestamp as detectedTime from pattern[...]; 

// join step and heartrate condition to see if they co-occur in some way 
select * from StepConditionDetected.std:unique(macAddress).win:time(15 min) as a, 
HeartrateConditionDetected.std:unique(macAddress).win:time(15 min) as b 
where a.macAddress = b.macAddress 

Sie in die where-Klausel hinzufügen könnten die beiden Bedingungen und mit „Überlappung“ implementieren einige Allen-Kalkül dh „und a.detecttime.overlaps (b.detectedTime Beitritt x, y) "

+0

Was ich will ist, wenn in den letzten 15 Minuten keine Schritte unternommen werden und nach diesen 15 Minuten die Herzfrequenz höher als 120 ist, wird die Regel ausgelöst. – Tim

+1

Also, wenn ich richtig verstanden habe, muss die Schrittbedingung zuerst kommen und nur einmal, die dann gefunden wird, fängt an, nach der Herzfrequenzbedingung zu suchen? I.e. Wenn es keine Schrittbedingung gibt, müssen wir nicht nach der Herzfrequenz suchen? Eine Lösung könnte immer nur nach beiden Bedingungen suchen und den Join wie zuvor verwenden, könnte beispielsweise mit "nach" in "wo" nachschauen. Wenn Sie der Engine anzeigen möchten, dass der Herzschritt erst beginnt, wenn die Schrittbedingung auftritt, verwenden Sie einen Kontext "initiiert von s = StepCondition terminate nach 15 Minuten" und lassen Sie den Kontext die Herzfrequenz-Statements steuern. – goodie

+0

Ja die Schrittbedingung muss zuerst kommen. Aber könntest du mir einfach ein Beispiel geben, wie man die StepCondition schreibt, weil ich jetzt nicht wie man Regeln mit einem Timer schreibt. – Tim