This page last changed on Oct 22, 2013 by delvedi.

Hi,

When an event is triggered(door sensor) I would like to start a countdown timer and at the end check the status of the sensor again. Only when the status hasn't changed in between a command should be executed. How can I integrate a countdown timer in the rules engine?

Thanks for your help

This can be done by the timer command:

rule "door countdown 30s"
  timer(int: 30s)
when
  Event(source=="door sensor",value=="on")
then
  // door sensor was triggered 30s ago and is still "on"
end
Posted by aktur at Oct 22, 2013 12:27

Thanks Michal,

Didn't know the interval could be used for this. The drools documentation talks about an "initial delay" so I'am a bit confused. What happens if the status of the sensor changes within the interval period(eg:on off on) Will it reset the timer with the last status change?

I appreciate your help,

Dirk

Posted by delvedi at Oct 22, 2013 13:28

I think that on-off-on would fire after the last on. At least this is what is happening when I use @expires() metadata tag and trigger a rule on the fact expiration (this is what I use but I have a custom drools binary, in standard distribution @expires() does not work). So maybe you can test if the timer() has the same effect?

Posted by aktur at Oct 22, 2013 14:22

IIRC, the condition is evaluated again when the initial delay completes – so the initial delay begins when the condition is true and the consequence is executed after the initial delay is complete if the condition is still true.

Posted by juha at Oct 22, 2013 20:03

The problem with drools is that the docs are not the best. According to it it is true what you write, but it does not make much sense. Therefore, I've modified slightly the hello world example and run the test:

package com.sample
 
import com.sample.DroolsTest.Message;
import java.util.Date
import java.text.SimpleDateFormat;
 
function String _TimeStamp(){
  Date now;
  now = new Date();
  SimpleDateFormat dateFormatter = new SimpleDateFormat("H:mm:ss");
  return(dateFormatter.format(now));
}
 
rule "Hello World"
dialect "mvel" 
    when
        m : Message( status == Message.HELLO, myMessage : message )
    then
        System.out.println(_TimeStamp()+ ": "+myMessage );
        m.setMessage( "Goodbye cruel world" );
        m.setStatus( Message.GOODBYE );
        update( m );
end

declare Delay
  on: boolean
end

rule "delay1"
timer(int: 3s)
when
  m: Message(status==Message.GOODBYE)
  not Delay()
then
  m.setStatus(Message.HELLO);
  m.setMessage("delay1");
  update(m);
  System.out.println(_TimeStamp()+": in delay1");
  insert(new Delay());
end
  

rule "GoodBye"
timer(int: 5s)
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println(_TimeStamp()+": "+myMessage);
end

The results are:

14:24:19: Hello World
14:24:22: in delay1
14:24:22: delay1
14:24:27: Goodbye cruel world

You can see that the GoodBye rule was delayed 8 seconds instead of 5.

Posted by aktur at Oct 23, 2013 13:29

Thank you for your help Michal, I'll give it a try during the weekend

Posted by delvedi at Oct 23, 2013 15:40

It would make sense if you recall that update is equivalent to retract + insert. This would then lead your goodbye cruel world to execute 5 seconds after the update. Which it does at 3+5 seconds.

3.3.3.1.3. Update

The Rule Engine must be notified of modified facts, so that they can be reprocessed. Internally, modification is actually a retract followed by an insert; the Rule Engine removes the fact from the WorkingMemory and inserts it again.

So from that point of view, you could assume that the initial delay and timer are re-scheduled and re-started due to your modify of the message in rule 'delay1'.

Posted by juha at Oct 23, 2013 15:55

And the same happens in RuleEngine.push() so it will work for the original request (door sensor update) too.

Posted by aktur at Oct 23, 2013 16:08

Your first example rule would get executed in 30s if the door sensor is in on status irrespective of which sensor updated it's state - if there are multiple sensors in the system.

The concept of using a status monitor (like the Delay in your second example) should work well though.

Posted by atamariya at Oct 23, 2013 16:26

Have you tested your first statement? Because I think that it is not true.

I don't use a status monitor in my second example. The delay1 rule is just a proxy of changing the sensor value, and Delay is to do it only once, otherwise I would have an infinitive loop.

Posted by aktur at Oct 23, 2013 16:51

Juha,

when I'm thinking about my test bench and recall other info you've told me I'm freaking out a bit . In the Hello World example there is only one call to ks.fireAllRules() and the program is stopped for 8s! This means that if timer() is used in the controller it would stop the execution of the event processing thread for a time that all timers are done. This can be quite dangerous, or am I wrong? Do you know what it would happen if one sets timer to few hours or days?

Posted by aktur at Oct 23, 2013 17:32

You're asking if an initial delay is handled synchronously by rules timer. I'd be surprised if that's the case. I've never tested it.

Posted by juha at Oct 23, 2013 18:07

I've tested it, program does not stop, it exits fireAllRules and handles facts timing internally by the rule engine.

Posted by aktur at Oct 26, 2013 11:18

Thanks for doing the test.

Posted by juha at Oct 29, 2013 00:29

I apologise but I don't succeed to make a decent test. The problem is a lack on documentation on the rules. I'm still waiting someone would point me to some documentation on the possibilities in the when and then clause.
I cannot find any information on commands like "customstate" for example. To me it seems drools and openremote rules engine are 2 different things with their own commands. Will any tutorial become avaialble in future?

Thx

Posted by delvedi at Nov 13, 2013 21:02
Document generated by Confluence on Jun 05, 2016 09:40