openhab / openhab1-addons

Add-ons for openHAB 1.x
Eclipse Public License 2.0
3.43k stars 1.71k forks source link

[GPIO] Item state out of sync even with debounce set #5729

Closed oktett-8 closed 4 years ago

oktett-8 commented 5 years ago

Expected Behavior

openHAB Items bound to GPIO pins should always be in sync with the pin state reported by the OS after the debounce time. For Linux the value reading of the GPIO pin in the /sys filesystem (e.g. cat /sys/class/gpio/gpio123/value) should be in sync with the bound Item state.

Current Behavior

When connecting GPIO to a potential-free relay (e.g. for decoupling from a status signal of a different circuit) GPIO Binding shows an unreliable behavior. Item state sometimes does not change after the relay changes state and is then not in sync with the “value” reading of the GPIO pin in the Linux /sys filesystem. This is due to heavy bouncing of the relay contact and an implementation weakness in GPIO software debounce.

The current implementation places a blocking call on a GPIO pin that is unblocked as soon as the GPIO state changes. A few lines later it reads the actual state which might have bounced back to the original state again in the meantime (after the unblocking). With the read state it does the event handling that updates openHAB Items (which may not cause an Item Changed Event if the read state was a bounce back to the original state).

If the debounce parameter is set in the GPIO Binding it would now (after the first, potentially wrong read) cause the event handling to be skipped for the specified time. If the relay contact then is stable the blocking call on the GPIO pin will not receive an interrupt anymore and so the Item state will remain out of sync with the actual contact state and its value in /sys.

Possible Solution

GPIO software debounce can be made reliable by not reading the state just after being unblocked, but sleeping for the time specified in the debounce parameter and then reading the state and doing the event handling. I will provide a commit with the fix.

Steps to Reproduce (for bugs)

  1. Get a 230 V relay (they seem to bounce much heavier than a button switch) and connect the potential-free part to a GPIO pin.
  2. Bind GPIO pin to an Item.
  3. Switch the relay and monitor the state (e.g. in events.log).

Context

Binding a GPIO pin to an Item is unreliable in the current implementation.

Your Environment