[SOLVED] Best approach delay a flickering contact, proxy and/or timer or?

I´m using a coupple of Xiaomi door/window sensors to indicate my garagedoor beeing open or closed (top and bottom sensor).
Unfortunaly these Xiamoi sensors are not so stable. They tend to “flicker” when they change state, which is confusing my rule for monitoring the garagedoor.

What is the best approach to get around this problem? I was thinking about using a proxy item and a timer, like this: (simple logic example, I have yet to find the right actions to use).

when sensor_x update
 then
createTimer(now.plusSeconds(1)) [ | proxy_sensor_x.sendUpdate ]

But is there another/better way to deal with this?

1 Like

Another way is to use the Expire binding, this will eliminate the need to use a timer and lambda in your rule. What you have above will work fine but be aware if you have several rules that use lambda’s there’s a chance it may have problems when two or more try to run at the same time.

Also see this example for anti flapping in a rule https://community.openhab.org/t/rule-optimization-window-open-reminder/39451/12?u=h102

If your asking how to use this logic in your rule.

when sensor_x update
 then
createTimer(now.plusSeconds(1)) [ | proxy_sensor_x.sendUpdate ]

You need to define the variable Timer, the rule will look similar to this:

var Timer sensorTimer
rule "your_rule"
when 
Item sensor_x changed
then
if(senosr_x == ON){
sensorTimer = createTimer(now.plusSeconds(1), [ |
proxy_sensor_x.postUpdate(ON) 
])
}
end

Just for more idea’s here’s an example for a motion detector.
If your sensor triggers ON/OFF (0 and 1 in the example) several times you can use a counter in the rule similar to this:

var timerCount = 0
rule "timer"
when 
	Item Esp_Easy_Motion changed from 0 to 1
then
	if(Esp_Easy_Motion.state != NULL) {
		timerCount +=1
		timer.postUpdate(timerCount)
	}
end

rule "timer count"
when
	Item timer changed 
then
	if(timerCount >= 3 && Couch_Light.state != ON){
		Couch_Light.sendCommand(ON)
		timerCount =0
		timer.postUpdate(timerCount)
	}	
	else if(timerCount >= 3 && Couch_Light.state != OFF){
		Couch_Light.sendCommand(OFF)
		timerCount =0
		timer.postUpdate(timerCount)
	}
end

Just adjust the counter number to suit your needs.

You could also persistence and take the item.averageSince(x minutes).

If you really have a couple of sensors on one (physical) item, you should program a quorum function
(that would eval to true if out of say 5 sensors 3 or more are true).

Not sure what flickering means here.

My instalaltion has the same problem with garage door.

If it opens or closes the sensor give me this:

OPEN
CLOSE
OPEN
CLOSE
OPEN

Which means the sensor gets triggered more times for the same event. If you use a timer then you do not know, which was the last status. You must catch all of them and just look for the last one within a time period of 2 sec. for example.

I have fixed it in a different way. I relocated the magnetic part of the sensor that I get only one event. My sensor has more the one magnetic contact parts inside. This was the root cause.

The magnet tiggers the first one, untrigger it and triggers the next one.

1 Like

See Generic Presence Detection and Design Pattern: Motion Sensor Timer for further examples.

Thats what I mean by “flickering”. I can see others use the word “flapping”. Guess it´s two words given the same meaning, ie the contact returns with open/close several times in one action.

I believe, using a counter, you wil have to know for sure, how many times to count, or??

Is the variable really required??

I like your idea of using the expire binding, as its plain an simple, which I always prefere. But I fail to see how to, in this particular manner?

It´s a bit more complicated. It´s one sensor changing state “uncontroled” like flapping (or flickering) wihtin a very short time (ms).
Like this:

2018-11-18 14:37:09.494 [vent.ItemStateChangedEvent] - GaragePortBottomSensor changed from CLOSED to OPEN
2018-11-18 14:37:09.559 [vent.ItemStateChangedEvent] - GaragePortBottomSensor changed from OPEN to CLOSED
2018-11-18 14:37:09.779 [vent.ItemStateChangedEvent] - GaragePortBottomSensor changed from CLOSED to OPEN

This was suppose to go from CLOSED to OPEN only… Because of the “extra” CLOSED/OPEN in between, my monitor rule is sending messages two and even three time in a row. Its not a problem with the monitor rule, it´s a problem with the door/window sensor flapping/flickering.

I know what the last event state is suppose to be. Its a door/window sensor. Either it´s OPEN or CLOSED. If it start with CLOSED and the garagedoor move, then the last event state will have to be OPEN, no matter how many times the sensor is flapping/flickering.
Thats why my idea was, use a proxy item, wait for 1 sec and then set the state to the proxy item.
And then use the proxy item in my monitoring rule.

I have read both several times. I really fail to see how to, probably due to lack of knowledge.

Rich explains this here. I know you have read it several times so maybe try using the example with your items. Just replace the items in the example with your items and create the proxy item.

After setting it up if your having errors post what you have and someone can help. Getting your hand dirty is a good way to learn and understand how the rules work. The rules posted above are for example and meant to help with ideas. If you need more examples use search and the words anti flapping.

And that would be the best way. There is no point trying a software fix when the problem is the hardware. Of course it can be done but it’s a bad solution.
Always go to the source of the problem. In your case, the sensor. You did the right thing.

I´m not quite sure this will work with the small Xiaomi sensors. Otherweise this is what I would prefere.

I dont mind getting my hands dirty.

What you want to do is wait a certain amount of time after the last event before you take any action. So cat a timer on the first even for say 500 msec into the future. Where the action takes place (alert or what ever). On subsequent events reschedule the timer 500 msec into the future from then. The action will only occur once the events from the sensor stop flapping back and forth for 500 msec.

Both of the links I provide do exactly this.

They probably do. I´m working hard to understand it. But I´m getting there, I hope.

If you have specific questions or need elaboration I would be happy to answer. I only ask that you ask on the example posts instead of hear so that the answers can benefit other users who come to those threads.

@Kim_Andersen Please try using this rule and items for your specific setup.

Items

Switch Sensor_x "Door Contact" <door>   // This is the physical contact on door, can't prevent the flapping so an additional proxy item will be used to represent the state.
Switch Sensor_Item  // Use this proxy item in other rules, as its state will be updated after the anti flapping time has expired.
Switch Sensor_Proxy { expire="5s, command=OFF" } // 5s, may need to adjust the time to fit your setup.

Rule

rule "DoorMovement"
when 
Item TestSensor changed  // One of my physical sensors
then
Sensor_Proxy.sendCommand(ON) // Contact has changed states and the proxy timer, 5 seconds, has started
end

rule "DoorState"
when
Item Sensor_Proxy changed from ON to OFF  // the 5sec have passed
then
if(TestSensor.state == OPEN){  // The 5 seconds have passed, rule checks the item state
    Sensor_Item.sendCommand(OPEN) // if the state is ON the item sends an ON command
}
    else {
        Sensor_Item.sendCommand(CLOSED) // if state is not ON then item sends an OFF command
    }
end
2 Likes

It sure works great @H102 Thanks alot for your help and explaning :+1: