-
-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Raspi GPIO binary_sensor produces unreliable responses #31788
Conversation
…unreliable responses ("Doorbell Scenario") Home Assistant's rpi_gpio binary sensor captures the pin state directly in the first egde interrupt. At first glance, it looks logical and, on a real-time platform like Arduino, it would work properly. On RPi/Linux, however, the timing is unpredictable, so that it might (actually, it often does) happen that the signal bounces back before the edge handler has been called, and the handler captures a wrong pin state. To fix it, we just wait until the signal stabilizes itself ("bouncetime" parameter) and capture the pin state after that. NOTE: PRi.GPIO's "bouncetime" parameter doesn't debounce input but simply disables additional egde interrupts for the specified period of time.
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
Thanks, stalebot, but this PR awaits an initial review from us. |
Meanwhile, @greg2001, the builds fail, which need to be addressed in order for this PR to be reviewed/merged. Could you take a look? |
The logs have been removed since it was quite a while back. I'll retrigger them. |
/AzurePipelines run |
Azure Pipelines successfully started running 1 pipeline(s). |
…unreliable responses ("Doorbell Scenario") Home Assistant's rpi_gpio binary sensor captures the pin state directly in the first egde interrupt. At first glance, it looks logical and, on a real-time platform like Arduino, it would work properly. On RPi/Linux, however, the timing is unpredictable, so that it might (actually, it often does) happen that the signal bounces back before the edge handler has been called, and the handler captures a wrong pin state. To fix it, we just wait until the signal stabilizes itself ("bouncetime" parameter) and capture the pin state after that. NOTE: PRi.GPIO's "bouncetime" parameter doesn't debounce input but simply disables additional egde interrupts for the specified period of time.
@frenck Thanks, got it! Should be OK now. |
"""Edge detection handler.""" | ||
threading.Timer(float(self._bouncetime) / 1000, read_gpio).start() | ||
|
||
rpi_gpio.edge_detect(self._port, edge_detected, self._bouncetime) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How often is an edge detected ?
def edge_detected(port): | ||
"""Edge detection handler.""" | ||
threading.Timer(float(self._bouncetime) / 1000, read_gpio).start() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not use a thread but instead schedule it on the event loop.
def edge_detected(port): | |
"""Edge detection handler.""" | |
threading.Timer(float(self._bouncetime) / 1000, read_gpio).start() | |
async def async_read_gpio(self): | |
"""Read state from GPIO.""" | |
await asyncio.sleep(float(self._bouncetime) / 1000) | |
self._state = await self.hass.async_add_executor_job(rpio_gpio.read_input, self._port) | |
self.async_write_ha_state() | |
def edge_detected(port): | |
"""Edge detection handler.""" | |
self.hass.add_job(self.async_read_gpio) |
There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. |
Not stale |
@Misiu I'm sorry, can I ask why you wrote not stale? |
@Misiu The author did not respond in a month. That is why it is marked stale. You've just messed with that process, which isn't appreciated. Please don't do that again. I'm sorry to hear you have problems, but the stale bot is here for a reason. |
@greg2001 Sure we are! However, this PR has been stale for over a month, without response. Hence it was closed. Feel free to re-open a PR when ready to work on it again and address the comments raised! 👍 |
@frenck Would you kindly re-open this PR or shall I create a new one? |
I would like to remember that issue #10498 concerns the same problem and is still open. |
Home Assistant's rpi_gpio binary sensor captures the pin state directly in the first egde interrupt.
At first glance, it looks logical and, on a real-time platform like Arduino, it would work properly.
On RPi/Linux, however, the timing is unpredictable, so that it might (actually, it often does) happen
that the signal bounces back before the edge handler has been called, and the handler captures a wrong pin
state. To fix it, we just wait until the signal stabilizes itself ("bouncetime" parameter) and capture
the pin state after that.
NOTE: PRi.GPIO's "bouncetime" parameter doesn't debounce input but simply disables additional egde interrupts
for the specified period of time.
Breaking change
Proposed change
Type of change
Example entry for
configuration.yaml
:# Example configuration.yaml
Additional information
Checklist
black --fast homeassistant tests
)If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
Updated and included derived files by running:
python3 -m script.hassfest
.requirements_all.txt
.Updated by running
python3 -m script.gen_requirements_all
..coveragerc
.The integration reached or maintains the following Integration Quality Scale: