"Debounce a Contact Sensor" in RM

Is this a Z-Wave contact sensor?

We've seen it a very few times. But, none were as short as 4 - 8 msecs. Conceptually our architecture has an (unstated) minimum event separation time spec that this device violates. That doesn't help you or us though. Were I in your shoes, I'd swap out the device with one that doesn't have this problem.

We could implement a fix at the platform level to prevent multi-threading of device messages for certain devices. This is doable, and we'll open an issue for it. It's not RM that needs the fix, it's down at the level that incoming device messages are processed. And, as you suggest, the fix would entail a semaphore to prevent simultaneous parallel message processing.

I'm seeing similar duplicate events with at least one of my motion sensors also:

dev:972019-09-19 12:17:17.922 infoDriveway - Motion is inactive
dev:972019-09-19 12:17:17.914 infoDriveway - Motion is inactive
dev:972019-09-19 12:01:13.466 infoDriveway - Motion is active
dev:972019-09-19 12:01:13.459 infoDriveway - Motion is active
dev:972019-09-19 11:33:36.593 infoDriveway - Motion is inactive
dev:972019-09-19 11:33:36.586 infoDriveway - Motion is inactive
dev:972019-09-19 11:30:10.915 infoDriveway - Motion is active
dev:972019-09-19 11:30:10.912 infoDriveway - Motion is active

so it isn't just that one door sensor.

I obviously don't know anything about how the system is written. But there is clearly support for timestamped logging. So yes, a "throw out duplicate messages within some time window" filter should be possible, hopefully with the time window user settable per device.

1 Like

Not when they happen faster than whatever records the first event! This has to be a change to our platform.

I think you just have the unlucky draw with these two devices. For all practical purposes they are unusable with Hubitat as triggering devices.

We have opened an issue for this to be addressed at the platform level.

Well yes, that is what I meant -- not at RM level.

Is this a Zwave multipath issue? I would think that this kind of thing would happen often if a device sends communication back via more than one neighbor. These door sensors are a bit on the old side, but the motion sensor is Zwave Plus (Ecolink) I bought just last year. And I just checked a brand new Zooz motion sensor event log, and see occasional duplicate events with as low as 11ms difference.

I think I have a way to get this to work:

First of all, at a conceptual level you need to separate the tasks that might be fired by the double-firing device into two parts. Part one are ones that it doesn't matter if they are done more than once. For instance, turning on a light. You can send a second On command to it and that doesn't matter. Part two are those tasks where it is important that they only run once. These are the ones that are problematic and need protection.

For technical reasons Rule Machine uses a form of scheduling that doesn't help in the resolution of this with respect to part two. For part one things, an ordinary rule can be used. We need a small custom app for part two to do the debounce. What the app does is subscribe to the double reporting device. It schedules a handler within the app to run some number of milliseconds later. The normal scheduling approach has each new schedule request overwrite any existing schedule request. So, assuming that part two can wait 200 to 500 msecs, this would guarantee that part two only runs once. It could be that the total delay in this app could be reduced to 100 msecs -- would just have to check out if that works.

Here is the debounce app.

Give that a try. It creates a virtual contact sensor that is debounced. Both open and close are debounced. Here is a sample of what happens:

While this case has the double event happening in about 150 msecs, as opposed to the very short times you showed, it should work for both cases. Notice that the debounced contact actually opens in this case a bit less than 200 msecs after the last open event on the double reporting device. There's slop in this logging timing.

This app could be used as a template to debounce a double reporting motion sensor.

1 Like

Thanks Bruce, this looks like a step forward. I've just installed and giving it a go.

Bruce,

Conceptually, which is faster and more efficient: a global variable or a virtual switch?

I donā€™t know.

Bruce -- I'll take a look at this, it looks interesting. Thanks for taking the time to work on this.

You say "it is OK to issue some commands twice, like turning on a light". You'd think so. I sure did. But really the only rules I have are for turning on lights, and they are the ones I'm having trouble with. I've seen three behaviors from my Zooz switches when they get multiple "turn on" commands (probably depending on how quickly they come in succession):

1 - the light comes on and everything is fine

2 - the light comes on and quickly goes back off again

3 - the light never comes on (possibly an extreme case of 2?)

Now, the very strange thing about (3) is that the SWITCH thinks the light is on! I have the LED on the switch on when the light is on, and off when it is off. But when the light never comes on at all, the LED does come on and stay on. It is very strange, and perhaps an issue specific to the Zooz switches?

I'll try to get time this weekend to try your app for the contact sensors that are causing me problems.

And then maybe look at the motion sensors also. Two of my three problem rules are motion triggered, and misbehave when the motion sensor fires twice very quickly.

The fact that my motion sensors are sometimes registering multiple events in quick succession still has me leaning toward a Zwave network issue, but if so I have no idea what to do about it. Except hope things settle down and it all goes away? My last network modifications were 2-3 weeks ago with some new switches then the contact sensors. I'd think the network would have straightened itself out by now.

Or perhaps an issue with the driver -- don't know. If turning on the switch is problematic then it's part two. So just use the debounce app, and replace the contact sensor in the rule with the debounced one.

I've never heard of a Z-Wave issue where commands are doubled in the mesh. But, I don't know. I'll make the mods for debouncing a motion sensor, and post that to the same Hubitat public repo.

1 Like

Bruce -- thanks, this looks great. Why can't something like this be included at the driver level? Then there would be no need for duplicate devices.

Anyway, I just tested this in my "Arrive via Garage" rule. The actual door sensor fired twice (5ms apart), but you debounced it beautifully and the rule to turn on the light only fired once. I used a 100ms delay.

I'll definitely adopt your app for my 3 motion sensors as well. It will be nice to see things running reliably and solid.

Thanks a lot!

Maybe it could be. This is a new problem that we haven't really seen before. We'll keep an eye on it.

Bruce,

I modified a copy of your "debounce contact", replacing "contact" with "motion" everywhere, and "open/closed" with "active/inactive". I replaced the RM triggers with these "debounced" versions, and put the debounced motion sensors in my Zone Motion controllers, and everything seems to work. I'm only getting my rules firing once now, and the lights are behaving.

Thank you very much!

2 Likes

Bruce -- quick question: I'm looking at your "debounce contact" app. I have no real experience with groovy or app development (but lots of other programming). I'm impressed with how little code there is here, and see more or less what it does. But when my contact sensor fires twice, what prevents THIS from firing twice?

I would have thought the handler would get called 2x, start 2 delays, get two event results, and not help at all. But it consistently fires just once. Which is perfect, and does what I want. I just don't know why. RM rules fire multiple times -- why not this? Something about the runInMillis call? Guess I should start reading up on the developer pages, but I'm very curious about why this works.

It does run twice. Where the debounce is happening is in the scheduler. With the default call to runInMillis(), which you see in this code (or runIn(), its equivalent for seconds) each time it is called it overwrites any previous schedule for that method. This works because it isn't a read followed by a write, it's just a write to a fixed place in the database. So the second time this thing runs it overwrites the time put in by the first instance. That's why the ultimate delay is from the second event. The scheduler itself is multi-threaded, but it doesn't matter, because there is only a single location for the value to be written to, and the last one to write is the one that happens. So the handler only gets called a single time, and that's where we set the virtual contact sensor.

Rule Machine doesn't work quite the same way. It uses a second form of runIn() in which it does not overwrite any previous schedule (runIn(15, handler, [overwrite: false])). This is because RM can have multiple things scheduled at the same time that will all call the same method. Using overwrite would wipe out those other scheduled events. Of course, in the debounce app, wiping out those other schedules is exactly what we want to happen.

1 Like

Don't they let you have Saturday's off?

Anyway, thanks for the explanation!

May I ask why you did this and how this has improved your system.
Just wondering and if it is an improvement I may do this as well. :+1:
Thanks.

He was getting two open events in quick succession from a contact sensor. This caused a rule to trigger twice, causing problems. We now think this is possibly a problem with the driver.

Hi Bruce.
I probably wasn't very clear.
I get the contact sensor 'debounce' app. (I'm actually seeing this occasionally on a contact sensor on my curtain rail).
I was referring to the post from @BrianX where he modified your original app for motion sensors.
I wouldn't have thought motion sensors would report a 'bounce' (so to speak) so I was wondering what the issue he had was.
Thanks for the reply though. :smile: