Check if an item has a state longer than x seconds

Hi,

I have a number-item (see below), which can have the values 0,1,2,10,11 or 12.

Number Tex_Window_W10_GV_Bureau_Zijkant						"Raam Bureau zijkant [MAP(windows.map):%s]"

If this item attains value 10, this means there is an error. Values are populated via incoming UDP packets.

Due to the nature of the incoming UDP packets, it is possible that my item is getting status 10 for less than a second. In that case, we can ignore it. If this item is having this 10-status for long than 1 second, something needs to happen.

My initial approach was the following:

    if (Tex_Window_W10_GV_Bureau_Zijkant.state == 10) {
		Thread::sleep(1000)
		if (Tex_Window_W10_GV_Bureau_Zijkant.state == 10) {
                // Do some stuff here
                }
    }

This works in most cases, but today I had the following scenario:

  • Item got state 10;
  • 400 milliseconds later the item got state 1;
  • 500 milliseconds later the item got state 10 again;
    => My rule assumed that the item had the “10” for longer than a second, but what actually happened is that within that second, it changed status twice.

So how can I take this scenario into account?

Thanks,

Don’t use sleep, use a Timer based in a global variable. When item changes, if > threshold start the Timer if not already running. If item < threshold, cancel Timer if running. If Timer expires, ring the bell or whatever.

Or use a proxy Item with Expire binding. Update the proxy everytime a ‘good’ update takes place, allow proxy to eventually go to expired state if none received.

2 Likes

Thanks!

I wasn’t aware of the timer concept, but it serves that purpose perfectly!

when   
    Item  Tex_Window_W10_GV_Bureau_Zijkant changed
then
    var Timer timer
    if (Tex_Window_W10_GV_Bureau_Zijkant.state == 10) {
	    	timer = createTimer(now.plusSeconds(1)) [|
				// Doing stuff here
    		]
    	} else {
    		if(timer!=null) {
    			timer.cancel
    			timer = null
    		}
    	}	
end

That won’t quite work as wanted, because the var creating the variable to hold the Timer is local to the rule. Every time the rule is triggered, a new Timer will be created and spun off to do its thing later.

The fix is to create the var outside of the rule, near the beginning of the rules file. That way only one Timer will be created in it, which will be shared by repeated triggers of the rule.

1 Like

True, I noticed that later. I’ve now put it on top of my rules file. Thanks!