hvalev / dht22mqtt-homeassistant-docker

Docker container for the DHT11/DHT22/AM2302 sensors, able to relay sensor readings to a MQTT broker. Integrates with HomeAssistants' discovery protocol and incorporates a robust outlier detection scheme. All features are configurable, where the container can be used to simply log data too.
MIT License
7 stars 4 forks source link

RuntimeError on Raspberry Pi 4 #9

Closed fphammerle closed 3 years ago

fphammerle commented 3 years ago

Thanks for sharing this project!

Issue

$ sudo docker run --device=/dev/gpiomem -e pin=4 hvalev/dht22mqtt-homeassistant
Unable to find image 'hvalev/dht22mqtt-homeassistant:latest' locally
latest: Pulling from hvalev/dht22mqtt-homeassistant
b04429a21654: Pull complete 
82f54af1b798: Pull complete 
3b810ccad87e: Pull complete 
8c662cd360da: Pull complete 
8fc846f293ee: Pull complete 
1f4ab4519fe2: Pull complete 
2d8003f76842: Pull complete 
Digest: sha256:d62496030335df0d2c3540689fc4861a4cf566afc8be2594a45fdacb5b9459d2
Status: Downloaded newer image for hvalev/dht22mqtt-homeassistant:latest
Traceback (most recent call last):
  File "//dht22mqtt.py", line 7, in <module>
    import adafruit_dht
  File "/usr/local/lib/python3.9/site-packages/adafruit_dht.py", line 17, in <module>
    from digitalio import DigitalInOut, Pull, Direction
  File "/usr/local/lib/python3.9/site-packages/digitalio.py", line 15, in <module>
    from adafruit_blinka.microcontroller.bcm283x.pin import Pin
  File "/usr/local/lib/python3.9/site-packages/adafruit_blinka/microcontroller/bcm283x/pin.py", line 2, in <module>
    import RPi.GPIO as GPIO
  File "/usr/local/lib/python3.9/site-packages/RPi/GPIO/__init__.py", line 23, in <module>
    from RPi._GPIO import *
RuntimeError: This module can only be run on a Raspberry Pi!
$ sudo docker run hvalev/dht22mqtt-homeassistant pip freeze
Adafruit-Blinka==6.4.2
adafruit-circuitpython-dht==3.6.0
Adafruit-PlatformDetect==3.5.0
Adafruit-PureIO==1.1.8
paho-mqtt==1.5.1
pyftdi==0.52.9
pyserial==3.5
pyusb==1.1.1
RPi.GPIO==0.7.0

Background

Allegedly, RPi.GPIO supports the raspberry pi 4: 2021-05-02-104950_362x163_scrot https://pypi.org/project/RPi.GPIO/

However:

$ grep -n -r -B 2 'This module can only be run on a Raspberry Pi' RPi.GPIO-0.7.0
RPi.GPIO-0.7.0/source/py_gpio.c-1006-   if (get_rpi_info(&rpiinfo))
RPi.GPIO-0.7.0/source/py_gpio.c-1007-   {
RPi.GPIO-0.7.0/source/py_gpio.c:1008:      PyErr_SetString(PyExc_RuntimeError, "This module can only be run on a Raspberry Pi!");

source/cpuinfo.c from RPi.GPIO-0.7.0.tar.gz:

// ...
int get_rpi_info(rpi_info *info)
{
   // ...
   if ((fp = fopen("/proc/device-tree/system/linux,revision", "r"))) {
      uint32_t n;
      if (fread(&n, sizeof(n), 1, fp) != 1) {
         fclose(fp);
         return -1;
      }
      sprintf(revision, "%x", ntohl(n));
      found = 1;
   }
   else if ((fp = fopen("/proc/cpuinfo", "r"))) {
      while(!feof(fp) && fgets(buffer, sizeof(buffer), fp)) {
         sscanf(buffer, "Hardware   : %s", hardware);
         if (strcmp(hardware, "BCM2708") == 0 ||
             strcmp(hardware, "BCM2709") == 0 ||
             strcmp(hardware, "BCM2835") == 0 ||
             strcmp(hardware, "BCM2836") == 0 ||
             strcmp(hardware, "BCM2837") == 0 ) {
            found = 1;
         }
         sscanf(buffer, "Revision   : %s", revision);
      }
   }
   else
      return -1;
   fclose(fp);
   // ...

/proc/device-tree/system/linux,revision is not available in non-privileged docker container:

/ # stat -c%N /proc/device-tree
'/proc/device-tree' -> '/sys/firmware/devicetree/base'
/ # ls -1 /sys/firmware/devicetree/base
ls: /sys/firmware/devicetree/base: No such file or directory

due to a shadowing tmpfs at /sys/firmware:

/ # ls -1 /sys/firmware
/ # 

and get_rpi_info does not compare against RPi4's chip version:

/ # grep -i hardware /proc/cpuinfo
Hardware    : BCM2711

This issue will be fixed RPi.GPIO v0.7.1: https://sourceforge.net/p/raspberry-gpio-python/tickets/190/

Question

Could you install v0.7.1a4 instead of v0.7.0 to support rRPi4 (without --privileged)?

https://github.com/hvalev/dht22mqtt-homeassistant-docker/blob/main/requirements.txt#L3

fphammerle commented 3 years ago

Confirmed that an upgrade to RPi.GPIO v0.7.1a4 fixes the issue:

$ sudo docker run -it --device=/dev/gpiomem -e pin=4 hvalev/dht22mqtt-homeassistant:1.1.2 ash
Unable to find image 'hvalev/dht22mqtt-homeassistant:1.1.2' locally
1.1.2: Pulling from hvalev/dht22mqtt-homeassistant
Digest: sha256:d62496030335df0d2c3540689fc4861a4cf566afc8be2594a45fdacb5b9459d2
Status: Downloaded newer image for hvalev/dht22mqtt-homeassistant:1.1.2
/ # python3 -u dht22mqtt.py
Traceback (most recent call last):
  File "//dht22mqtt.py", line 7, in <module>
    import adafruit_dht
  File "/usr/local/lib/python3.9/site-packages/adafruit_dht.py", line 17, in <module>
    from digitalio import DigitalInOut, Pull, Direction
  File "/usr/local/lib/python3.9/site-packages/digitalio.py", line 15, in <module>
    from adafruit_blinka.microcontroller.bcm283x.pin import Pin
  File "/usr/local/lib/python3.9/site-packages/adafruit_blinka/microcontroller/bcm283x/pin.py", line 2, in <module>
    import RPi.GPIO as GPIO
  File "/usr/local/lib/python3.9/site-packages/RPi/GPIO/__init__.py", line 23, in <module>
    from RPi._GPIO import *
RuntimeError: This module can only be run on a Raspberry Pi!
/ # apk add --no-cache gcc musl-dev
[...]
/ # pip install RPi.GPIO==0.7.1a4
Collecting RPi.GPIO==0.7.1a4
  Using cached RPi.GPIO-0.7.1a4.tar.gz (29 kB)
Building wheels for collected packages: RPi.GPIO
  Building wheel for RPi.GPIO (setup.py) ... done
  Created wheel for RPi.GPIO: filename=RPi.GPIO-0.7.1a4-cp39-cp39-linux_armv7l.whl size=24929 sha256=92c61194b4da4c2467c62b76a90f6fed4423b9c8f3ca1c9e2537c9f6841c4c41
  Stored in directory: /root/.cache/pip/wheels/6f/1c/5c/113894ea5785c8856518ad0d88803c2ec7cbc6cb88e47f2e04
Successfully built RPi.GPIO
Installing collected packages: RPi.GPIO
  Attempting uninstall: RPi.GPIO
    Found existing installation: RPi.GPIO 0.7.0
    Uninstalling RPi.GPIO-0.7.0:
      Successfully uninstalled RPi.GPIO-0.7.0
Successfully installed RPi.GPIO-0.7.1a4
WARNING: You are using pip version 21.0.1; however, version 21.1.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
/ # logging=log2stdout python3 -u dht22mqtt.py
2021-05-02T09:13:14Z Starting dht22mqtt...
2021-05-02T09:13:14Z Setup dht22 sensor success...
fphammerle commented 3 years ago

for reference, why /proc/device-tree / /sys/firmware/devicetree/base is not available in non-privileged docker containers: https://github.com/docker/docker-ce/blob/v19.03.15/components/engine/oci/defaults.go#L127

hvalev commented 3 years ago

Looks good to me! Thank you for your contribution. I've accepted your pull request and will update the docker container on docker hub shortly.

fphammerle commented 3 years ago

great, thanks!