This page last changed on Feb 25, 2016 by pz1.

I do need some help to add a watchdog to my UDPListener rule.
Sometimes the data stream unexpectedly stops. Because it is a rare event, it often goes unnoticed for a day or so.

My idea is to have one Rule named "timer" that switches a status to "off" when the pre-set time expires.
Every time a UDP message has successfully arrived, the status is set to "on", and the timer is reset to its initial value.

I have searched extensively in the Drools manuals an on this forum and other places to find a simple timer.

// Code provided by Michal Rutka 
package org.openremote.controller.protocol.preserve;
import java.util.*;
import org.openremote.controller.protocol.Event;
global org.openremote.controller.statuscache.CommandFacade execute;
 
 
rule "UDPListener9192"
                                                                                      
when
  Event(source=="RaZ-UDP-Status", $v: value!="")
then
  java.util.regex.Pattern regexPattern = java.util.regex.Pattern.compile("\\(?(ZWay.*),([\\d\\.+|on|off]+)\\)?");
  java.util.regex.Matcher matcher = regexPattern.matcher($v.toString());
  if (matcher.find()) {
    execute.command(matcher.group(1), matcher.group(2));
  }
end

Thank you for your attention

UPDATE: got it working:

package org.openremote.controller.protocol.preserve;
import java.util.*;
import org.openremote.controller.protocol.Event;
global org.openremote.controller.statuscache.CommandFacade execute;

rule "UDPListener9192"
when
  Event(source=="RaZ-UDP-Status-9192", $v: value!="")
then
  java.util.regex.Pattern regexPattern = java.util.regex.Pattern.compile("\\(?(ZWay.*),([\\d\\.+|on|off]+)\\)?");
  java.util.regex.Matcher matcher = regexPattern.matcher($v.toString());
  if (matcher.find()) {
    execute.command(matcher.group(1), matcher.group(2));
    execute.command("UDP9192On");                  //Added this
    execute.command("UDP9192countdown",100);       //Added this
  }
end

//Added following two rules
rule "UDP9192SourceFailed"
    timer (int: 2s)
when
    Event( source == "UDP9192countdownStatus", value == "0")
then
    execute.command("UDP9192Off");
end

rule "UDP9192CountDown"
    timer (int: 10s)
when
    Event( source == "UDP9192countdownStatus", $TimeLeft : value > 0 )
then
    Integer iTl = Integer.parseInt($TimeLeft.toString()) ;
    iTl = iTl - 1 ;
    execute.command("UDP9192countdown",iTl);
end

Cannot resolve external resource into attachment.

Hi

I think this might work for you, if you invert the logic.

A set of rules were written for me to use as a holiday countdown.

Where a slider or preset buttons sets an amount of days into an in memory virtual command.

The countdown loop will remove a day (although on the test rig it counts down in a few minutes.)

When the countdown gets to Zero, an in memory switch is set to off. (And any reset commands sent to the Velbus networks to return the building to a live / occupied state)

I'm sure you could do something similar, where you heartbeat resets the countdown timer to a high value?

Good luck,

Stuart

// Block of Rules for Holiday away days

rule "Holiday_mode_Off"
    timer (int: 1s)
when
    Event( source == "Holiday_Days_Status", value == "0")
then
    execute.command("HolidayVR_OFF");
end



rule "Holiday_Mode_On"
    timer (int: 1s)
when
    Event( source == "Holiday_Days_Status", value > 0 )
then
    execute.command("HolidayVR_ON");
end



rule "Holiday_Mode_dec"
    timer (int: 10s)
when
    Event( source == "Holiday_Days_Status", $TimeLeft : value > 0 )
then
    Integer iTl = Integer.parseInt($TimeLeft.toString()) ;
    iTl = iTl - 1 ;
    execute.command("Holiday_Days_set", iTl );
end

Posted by mdar at Feb 24, 2016 21:24

Thanks Stuart, this helps. I had come to the conclusion I should do something with decrementing a variable. I'll give it a try and let you know the final solution.
Pieter

Posted by pz1 at Feb 25, 2016 10:21

Got it working. Updated first post

Posted by pz1 at Feb 25, 2016 11:46

You can also try to declare internal facts instead of using in-memory virtual commands. Something like this should work (not tested, so spelling errors are possible):

package org.openremote.controller.protocol.preserve;
import java.util.*;
import org.openremote.controller.protocol.Event;
global org.openremote.controller.statuscache.CommandFacade execute;
 
declare UDPevent // Copy when event arrives
  source: String
end

rule "UDPListener9192"
                                                                                      
when
  Event($s: source=="RaZ-UDP-Status", $v: value!="")
then
  insert(new UDPevent($s)); // mark the event
  java.util.regex.Pattern regexPattern = java.util.regex.Pattern.compile("\\(?(ZWay.*),([\\d\\.+|on|off]+)\\)?");
  java.util.regex.Matcher matcher = regexPattern.matcher($v.toString());
  if (matcher.find()) {
    execute.command(matcher.group(1), matcher.group(2));
  }
end

// Expire events after timeout
rule "Expire events"
timer(int: 1h) // at least 1 event per hour
when
  $u: UDPevent($s: source)
  ArrayList($size:size) from collect(UDPevent(source==$s))
then
  retract($u);
  if($size==1){ // Only one event in memory, so must be the last one
       execute.command("UDP9192Off");
  }
end

// Add also duumy when the controller starts, so the alarm will trigger if the sensor is dead all the time
rule "Init event"
then
  insert(new UDPevent("RaZ-UDP-Status")); // mark the initial event
end

Posted by aktur at Feb 25, 2016 14:03

Michal,
Thanks for this feedback. I have little knowledge about Java and Drools, so I can't follow all the more advanced things you do. I do think yours formally is a better solution than the one I ended up with.
For the time being I'll stick with mine because there are some more pressing priorities.
Pieter

Posted by pz1 at Feb 25, 2016 15:09
Document generated by Confluence on Jun 05, 2016 09:33