[rules-users] Group-by rule without using a fact for grouping purposes

IK81 ml at kofler.me
Thu Dec 5 02:57:35 EST 2013


The devices may come and go and there may be several hundreds of them. 
They are stored in a database.

Currently, I feed the events into the knowledge session and trigger an 
EJB call (instead of the simple System.out.println I used in the example 
below) and pass the device id. The EJB does the rest and looks up the 
device and related information from the database. If the id is unknown, 
this call is just a NOOP.

Currently the knowledge session and the database need no 
synchronization. I just wanted to avoid this in my design, but now it 
seems to be necessary just for this group-by issue. I can imagine that I 
can also insert the fact using a rule that matches if I get an event for 
a currently unknown device (i.e., having no fact for it in the session), 
but how to clean up the facts if a device disappears. This @expires 
annotation is only valid for events afaik.

Are there really no alternatives for this group-by instead of having 
the fact?

Ingo


On 2013-12-05 06:52, Wolfgang Laun wrote:
> Why is it "not practical" to add a fact for a device? You don't have
> to do this up front; they may come and go, dynamically.
>
> -W
>
>
> On 05/12/2013, IK81 <ml at kofler.me> wrote:
>> Hi,
>>
>> I am trying to figure out a rule for matching an incoming sequence 
>> of
>> events, but so far I was not really successful. Basically, I want to
>> process events from devices. Every event has a timestamp (long), an 
>> id
>> (a UUID string), a deviceId and an error code (both are strings).
>>
>> What I want to have is a simple rule that fires, if a single device
>> reports a certain error code (e.g. ABCD) 3 times within 5 minutes 
>> (i.e.,
>> getting 3 such events within 5 minutes). So far, I suceeded in 
>> counting
>> the ABCD error codes in the time window as follows:
>>
>>
>> rule "Detect 3 occurrences of code ABCD for a certain device"
>> when
>>      Number( intValue == 3 ) from accumulate(
>>          Event( $i : id, code == "ABCD") over window:time( 5m ),
>>          count( $i ) )
>> then
>> 	System.out.println("Raise alarm");
>> end
>>
>> This first attempt does not distinguish which device sent the error
>> code. But how can I express to fire only if the events share the 
>> same
>> deviceId? I found many solutions that use a fact (e.g., a device 
>> fact)
>> to group by the device and do the accumulation. I successfully
>> implemented the group-by using the following when-part of the rule.
>>
>> when
>>      Device($deviceId : id)
>>      Number( intValue == 2 ) from accumulate(
>>          Event( $i : id, deviceId == $deviceId, code == "ABCD") over
>> window:time( 5m ),
>>          count( $i ) )
>> then
>>
>> Adding a device fact is however not practical in my case. Are there 
>> any
>> alternatives for expressing this group-by?
>>
>> Thanks,
>> Ingo
>> _______________________________________________
>> rules-users mailing list
>> rules-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users



More information about the rules-users mailing list