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

Wolfgang Laun wolfgang.laun at gmail.com
Thu Dec 5 03:40:07 EST 2013


What about

rule cleanup
when
    $d: Device( $id: id )
    not Event( id == $id )
then
    retract( $d );
end

-WL

On 05/12/2013, IK81 <ml at kofler.me> wrote:
> 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
>
> _______________________________________________
> 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