From ecec3c8ab9d39d6b1b43f6c5c2aeaef355fab840 Mon Sep 17 00:00:00 2001 From: mburget <77898400+mburget@users.noreply.github.com> Date: Sun, 4 Apr 2021 12:22:43 +0200 Subject: [PATCH] Fix Raspi GPIO binary_sensor produces unreliable responses (#48170) * Fix for issue #10498 Raspi GPIO binary_sensor produces unreliable responses ("Doorbell Scenario") Changes overtaken from PR#31788 which was somehow never finished * Fix for issue #10498 Raspi GPIO binary_sensor produces unreliable response. Changes taken over from PR31788 which was somehow never finished * Remove unused code (pylint warning) --- .../components/rpi_gpio/binary_sensor.py | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/homeassistant/components/rpi_gpio/binary_sensor.py b/homeassistant/components/rpi_gpio/binary_sensor.py index 36d7ae50f32..318b29131b6 100644 --- a/homeassistant/components/rpi_gpio/binary_sensor.py +++ b/homeassistant/components/rpi_gpio/binary_sensor.py @@ -1,4 +1,7 @@ """Support for binary sensor using RPi GPIO.""" + +import asyncio + import voluptuous as vol from homeassistant.components import rpi_gpio @@ -52,6 +55,14 @@ def setup_platform(hass, config, add_entities, discovery_info=None): class RPiGPIOBinarySensor(BinarySensorEntity): """Represent a binary sensor that uses Raspberry Pi GPIO.""" + 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( + rpi_gpio.read_input, self._port + ) + self.async_write_ha_state() + def __init__(self, name, port, pull_mode, bouncetime, invert_logic): """Initialize the RPi binary sensor.""" self._name = name or DEVICE_DEFAULT_NAME @@ -63,12 +74,11 @@ class RPiGPIOBinarySensor(BinarySensorEntity): rpi_gpio.setup_input(self._port, self._pull_mode) - def read_gpio(port): - """Read state from GPIO.""" - self._state = rpi_gpio.read_input(self._port) - self.schedule_update_ha_state() + def edge_detected(port): + """Edge detection handler.""" + self.hass.add_job(self.async_read_gpio) - rpi_gpio.edge_detect(self._port, read_gpio, self._bouncetime) + rpi_gpio.edge_detect(self._port, edge_detected, self._bouncetime) @property def should_poll(self):