GPIO pins work as output only, not input

I’m using a Rapsberry Pi 3b+ with a 32-bit kernel, and trying to use GPIO pins as input. Unfortunately, it isn’t working. I’ve seen several threads on here but they were old, unresolved, and/or weren’t caused by the same thing as my problem. Here’s what my configuration looks like (or at least one version, I’ve tried a lot of things to make this work, since some people reported switching pins fixed the problem):

switch:
  - platform: rpi_gpio
    ports:
      5:  Relay1
      6:  Relay2
      13:  Relay3
      16:  Relay4
      19:  Relay5
      20:  Relay6
      21:  Relay7
      26:  Relay8
    invert_logic: true

binary_sensor:
  - platform: rpi_gpio
    ports:
      11: Input1
      12: Input2

Note that the outputs work fine. Moreover, I’ve tried a bunch of different GPIO numbers, and none of them work for inputs, while all of the ones I’ve tried work as outputs.

What also works is the command gpio readall from the wiringpi package, run as the same user as hass. This strongly suggests it is not a permission issue. I can also see that the pins I’m trying are configured for input.

Here’s where things seem to go wrong in the log:

2019-08-25 17:14:20 ERROR (MainThread) [homeassistant.components.binary_sensor] Error while setting up platform rpi_gpio
Traceback (most recent call last):
  File "/home/hass/local/lib/python3.7/site-packages/homeassistant/helpers/entity_platform.py", line 149, in _async_setup_platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
    return fut.result()
  File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/hass/local/lib/python3.7/site-packages/homeassistant/components/rpi_gpio/binary_sensor.py", line 45, in setup_platform
    port_name, port_num, pull_mode, bouncetime, invert_logic
  File "/home/hass/local/lib/python3.7/site-packages/homeassistant/components/rpi_gpio/binary_sensor.py", line 70, in __init__
    rpi_gpio.edge_detect(self._port, read_gpio, self._bouncetime)
  File "/home/hass/local/lib/python3.7/site-packages/homeassistant/components/rpi_gpio/__init__.py", line 60, in edge_detect
    GPIO.add_event_detect(port, GPIO.BOTH, callback=event_callback, bouncetime=bounce)
RuntimeError: Failed to add edge detection

I’m unfortunately stuck here, so would really appreciate suggestions on how to fix this or what other experiments might shed light on the problem. Thanks.

Thanks. It sounds like our situations are not quite the same, because for me the switch support works natively in homeassistant, just not the binary_sensor. Also, just reading isn’t quite good enough because I want to use state transitions to trigger things, so I’d need to be reading is a busy-loop, which is not good.

I suppose as a worst case I could write a separate program that monitors the GPIO pins and then calls web hooks. But given that the rpi_gpio module has implemented support for binary_sensor, I was hopping just to fix my configuration error or fix the bug…

Again, it sounds like we have two different problems. As I stated in the original post, both the gpio program and homeassistant’s switch support for gpio are working, just not the binary_sensor.

Perhaps we need two separate threads, one for each problem.

Yes @HomAut should delete his posts and put them somewhere else.

@haweb what OS are you using?

I’m using archlinuxarm, kernel 4.19.67-1-ARCH, armv71 architecture. My hass user is in the uucp group, and I put /dev/gpiomem in that group using the following udev rule:

KERNEL=="gpiomem", GROUP="uucp", MODE="0660"

I also manually changed permissions on other possibly related devices like /dev/gpiochip*, but I really don’t think this is the problem because everything else I do with gpio has no permission problems, and I don’t notice any permission complaints in the homeassistant log. For example:

$ python
Python 3.7.4 (default, Jul 30 2019, 12:47:58) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> GPIO.setmode(GPIO.BCM)
>>> GPIO.setup(11, GPIO.IN)
>>> GPIO.input(11)
0
>>> GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
>>> GPIO.input(11)
1
>>> GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
>>> GPIO.cleanup()
>>>

In case it’s relevant, I installed homeassistant in a python virtualenv. When I run pip list -o, it does show some possibly relevant outdated packages, specifically:

Package                 Version    Latest     Type 
----------------------- ---------- ---------- -----
hass-nabucasa           0.16       0.17       wheel
home-assistant-frontend 20190805.0 20190825.0 sdist
RPi.GPIO                0.6.5      0.7.0      sdist

I tried manually upgrading these, especially RPi.GPIO, but then homassistant downgrades them when I start it up again.

Ah, but as I was writing this I think I discovered something:

$ python
Python 3.7.4 (default, Jul 30 2019, 12:47:58) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import RPi.GPIO as GPIO
>>> GPIO.setmode(GPIO.BCM)
>>> GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
>>> GPIO.wait_for_edge(11, GPIO.RISING, timeout=1000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Error waiting for edge
>>> GPIO.cleanup()

Running with strace shows permission errors under /sys/class/gpio/, so I think maybe this is the problem. I thought the /sys interface to GPIO was deprecated, but maybe still required for edge detection. Sure enough, it works when I run the same commands as root (duh)!

Now I guess I should figure out what the standard “systemd” way is of setting those permissions. Is it in /etc/tmpfiles.d, or do I create a unit file to change the permissions? What do most people do who run homeassistant as non-root?

As you wished.
You might delete my account as well, If you have that power. But I was simply trying to help out a member. Probably I’m misleading.

Have you checked whether your pin are exported?

$ gpio exports

This way you probably get permission to use the pin.

Okay, I solved the problem in an ugly way by creating a systemd unit file to run a script on bootup. The script exports the exact input pins I want to use with homeassistant and makes them available to the uucp group:

#!/bin/sh -e

gid=uucp
cd /sys/class/gpio

for gpio in 22 23; do
        if test "x$1" = "x-d"; then
                echo $gpio > unexport
        else
                echo $gpio > export
                chmod -R g+w gpio$gpio/
                chgrp -R uucp gpio$gpio/
        fi
done

I placed this in /etc/systemd/init-gpio, then added a unit file /etc/systemd/system/gpio.service to run it as follows:

[Unit]
Description=Set GPIO permissions for uucp group

[Service]
Type=oneshot
ExecStart=/etc/systemd/gpio-init
ExecStop=/etc/systemd/gpio-init -d
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Finally obviously I enabled it with systemc enable --now gpio. Seems a bit clunky, so would be glad to hear suggestions on cleaner ways of doing it, but at least I can now use GPIO input pins!

I am having the same problems with my hass in docker installation.
Using the gpio cover function.
I can control the cover but do not get any state changes

cover:
  - platform: rpi_gpio
    covers:
      - relay_pin: 16
        state_pin: 20

Log output on hass 0.99.2 (0.98.4 gave no log entries at all - but the same behaviour)
rpi-gpio v0.7.0
RPI 4/Buster

Error while setting up platform rpi_gpio
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 150, in _async_setup_platform
    await asyncio.wait_for(asyncio.shield(task), SLOW_SETUP_MAX_WAIT)
  File "/usr/local/lib/python3.7/asyncio/tasks.py", line 442, in wait_for
    return fut.result()
  File "/usr/local/lib/python3.7/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/src/homeassistant/homeassistant/components/rpi_gpio/binary_sensor.py", line 45, in setup_platform
    port_name, port_num, pull_mode, bouncetime, invert_logic
  File "/usr/src/homeassistant/homeassistant/components/rpi_gpio/binary_sensor.py", line 70, in __init__
    rpi_gpio.edge_detect(self._port, read_gpio, self._bouncetime)
  File "/usr/src/homeassistant/homeassistant/components/rpi_gpio/__init__.py", line 60, in edge_detect
    GPIO.add_event_detect(port, GPIO.BOTH, callback=event_callback, bouncetime=bounce)
RuntimeError: Failed to add edge detection

This started working for me again after I updated to 101.2 yesterday.

So I am happy again! :wink:

Hi! I’ve the same issue, did you find another solution?

I also got this issue on a reinstall. I used gpio 26 en 16, when I changed the 26 to using 17, it functioned properly for me.