Skip to content
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

Add gpio access and control #37

Open
6 tasks
LongLiveCHIEF opened this issue Apr 4, 2020 · 25 comments
Open
6 tasks

Add gpio access and control #37

LongLiveCHIEF opened this issue Apr 4, 2020 · 25 comments

Comments

@LongLiveCHIEF
Copy link
Member

On a test of the OctoPrint PSU control plugin via docker, I believe it is necessary to enable and document a few things related to using GPIO for our users.

The following 2 docker container settings are required for gpio dependent plugins to work:

  • cap-add SYS_RAWIO
  • --device /dev/mem

Additionally, the gpio device tree needs to be made writeable, and any pins that are controlled by octoprint plugins need to have corresponding INPUT/OUTPUT modes set, and the pin number registered in the /sys/class/gpio device tree.

This can be done manually with the gpio ubuntu package available from the wiringpi package in the default ubuntu registry.

I'm not sure if these plugins use this program, as I can't remember if I had to set things up manually the first time I installed PSU Control on a normal Octopi Raspbian image.

Tasks:

  • determine best practice for adding gpio channel manipulation so that the users have easiest possible experience when using plugins that utilize gpio controls
  • add any updates needed to Dockerfile or entrypoint script based on the determined best practice
  • determine if gpio plugins will automatically control pin mode if the appropriate system devices and packages are present, or if these need to be set manually

Documentation:

  • add docs about any necessary host commands/configs
  • docker-compose settings for cap_add and --device /dev/mem
  • any downstream Dockerfile changes needed to support gpio control if turns out that's the best practice
@LongLiveCHIEF LongLiveCHIEF self-assigned this Apr 4, 2020
@LongLiveCHIEF LongLiveCHIEF changed the title Add gpio access and control and docs Add gpio access and control Apr 4, 2020
@LongLiveCHIEF
Copy link
Member Author

The more native way of accessing things would be to use the sysfs interface. It's possible that's how PSU Control and other plugins work (via whatever python packages they use), and we merely need to map in /sys/class/gpio in addition to using cap-add SYS_RAWIO.

@LongLiveCHIEF
Copy link
Member Author

looks like at least PSU Control imports and uses RPI.GPIO to do what it does.

@LongLiveCHIEF
Copy link
Member Author

Looks like no matter what we do, even adding udev rules to hosts and giving the user godlike permissions, the final result is that the specific library i'm using to test (PSU Control) uses RPI.GPIO module. Even with all permissions between host and container fixed, it will throw an error:

octoprint.plugins.psucontrol - ERROR - Not running on a RPi!

@OctoPrint/octoprint-maintainers something to consider here... It might be a best practice moving forward if plugins avoid the use of libraries that make an assumption about the OS they are run on. For example we could recommend to use https://github.com/vitiral/gpio import gpio for OctoPrint which aims to use the same api as RPI.GPIO, but uses the native sysfs interface on all linux kernels, instead of packages that only exist on raspbian.

Not sure what next steps to go for this one just yet, as there is still some of the documentation pieces that are good to cover. @OctoPrint/docker-maintainers any thoughts here?


/cc @kantlivelong I wanted to open an issue in the PSU Control plugin github repo, but issues are turned off. Is that repo migrating to the OctoPrint org and that's just temporary, or should issues with that plugin be opened in OctoPrint repo? I believe we can add a few lines of code to the existing code so it will run smoothly even in a container even without changing libraries, and wanted to get the issue on paper in case someone else has time to work on it. I won't be able to get to it for a while.

I also saw an opportunity to improve some guidance in the wiki for your plugin. The troubleshooting question "can't access /dev/mem" links to a SO post has a technically correct answer, but only under a small number of conditions. The best fix for that problem is to create a udev rule for gpio devices assigning them the group and controls required to survive reboots. Let me know if that sounds ok to you and I'll drop the changes in gist that you can copy.

@LongLiveCHIEF LongLiveCHIEF moved this from In Progress to Blocked in Stable automated Docker Releases Apr 4, 2020
@kantlivelong
Copy link

@LongLiveCHIEF I turned it off as people were abusing it as support instead of a tracker. I was actually looking at replacing RPi.GPIO with generic GPIO support using python-periphery. Have even thought of creating a separate GPIO plugin with exposed helpers to be used by other plugins. I believe the biggest problem would be compatibility with other plugins that continue to use RPi.GPIO.

@kantlivelong
Copy link

PS: I'm generally in #octoprint on Freenode if you want to discuss it. 😄

@gaetancollaud
Copy link
Member

Regarding the RPI detection and the error octoprint.plugins.psucontrol - ERROR - Not running on a RPi! I think that the plugin should detect that we are on docker on a RPI. We could of course ease this detection by providing some environments variables or create a file at a specified location.

For the GPIO I'm not an expert but can't we just mount devices and volumes ? I don't think we need to do anything specific (except maybe document it).

@LongLiveCHIEF
Copy link
Member Author

@gaetancollaud It's not the plugin that throws this error, it's the RPI.GPIO module it uses internally.

https://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/source/py_gpio.c

The changelog for that module has some notes about updating detection for aarch64, and also some open issues about this.

@LongLiveCHIEF
Copy link
Member Author

so yeah... looks like it's not specific to docker, which is good to know.

@eduncan911
Copy link

eduncan911 commented Aug 4, 2020

I'll give another scenario... Raspberry clones, specifically Intel-based ones.

I have a large collection of UP Boards (Intel Atom, Celeron, and Pentium x64 powered). They are direct RPi formats, using the same 40-pin GPIO.

I've done some development on RPi hats for these boards, and it basically comes down to:

  • The drivers and software must be buildable under x64 arch. A lot of the HATs release proprietary blobs built only for ARM arch, preventing their use on x64 without qemu.
  • Run as root :(

I think root is because of the GPIO hacks to the x64 Linux kernel that requires root to access the GPIO bridge's DMA across these Intel-based boards.

To sum up, just an FYI to not prevent things running as root as there are use cases that we may have to.


I'm going to set this up soon, with the docker work I see in this repo. Most likely will be using Klipper's GPIO access instead of Octo though.

@shift
Copy link
Contributor

shift commented Sep 2, 2020

@LongLiveCHIEF
Copy link
Member Author

LongLiveCHIEF commented Sep 2, 2020

yeah, doesn't surprise me. I already wrote some stuff that uses the new character device libraries instead of relying on wiringpi. Forgot where I put it though.

@kantlivelong and I were tossing around some ideas using python-periphery (utilizes the native character device interface of recent kernels), but at the time octoprint was still python v2, and arm64 hadn't really become officially supported by Ubuntu yet, meaning wiringpi worked for most things, so it wasn't too much of a problem.

Might be about time to take a closer look now though.

@jneilliii
Copy link

The python 2 will be dropped in the next octopi release 0.18, whenever that is. The nightlies are already building python 3 only images.

@OctoPrint OctoPrint deleted a comment from Oxmaster Sep 27, 2020
@LongLiveCHIEF LongLiveCHIEF added this to Planned in Roadmap Sep 29, 2020
@LongLiveCHIEF LongLiveCHIEF moved this from Planned to Research/Help Wanted in Roadmap Dec 9, 2020
@albertopc
Copy link

Hi all,
my relay is connected to gpio18 and it works on the host raspi system.
And I managed to make PSU Control works for me adding this to docker-compose:

volumes:
  - /sys/class/gpio/gpio18:/sys/class/gpio/gpio18

and this commands under PSU Control plugin:

  • On System Command: echo "out" > /sys/class/gpio/gpio18/direction
  • Off System Command: echo "in" > /sys/class/gpio/gpio18/direction

@LongLiveCHIEF
Copy link
Member Author

@albertopc that is the deprecated interface we're talking about.

@LL1r1k
Copy link

LL1r1k commented Feb 27, 2021

@albertopc, what exactly needs to install PSU Control plugin? I get an error:

unable to execute 'gcc': No such file or directory
error: command 'gcc' failed with exit status 1
----------------------------------------
ERROR: Failed building wheel for RPi.GPIO

@LongLiveCHIEF
Copy link
Member Author

added gcc back in with #178, however you should know that RPi.GPIO is deprecated and no longer maintained.

@morganchristiansson
Copy link

morganchristiansson commented Mar 7, 2021

I just got this working thanks for advise in this thread.

@albertopc I see you are setting mode=input to turn off relay. I was struggling with the same issue and couldn't get it to work normally. Turns out it should be powered by 3.3v not 5v. After changing vcc to 3.3v it triggers normally - even though product spec says it should have 5v power. Setting direction=input with 5v powered board could damage your Pi according to comments at https://raspberrypi.stackexchange.com/questions/59668/5v-relay-will-not-close-unless-using-gpio-cleanup

With this issue resolved I got the following system commands working:

  • On: echo 1 >/sys/class/gpio/gpio4/value
  • Off: echo 0 >/sys/class/gpio/gpio4/value
  • Sensing: grep 1 /sys/class/gpio/gpio4/value

Also running echo 4 > /sys/class/gpio/export from /etc/rc.local on host boot.

See https://www.kernel.org/doc/Documentation/gpio/sysfs.txt for gpio sysfs documentation.

@LongLiveCHIEF
Copy link
Member Author

@morganchristiansson This kernel interface (sysfs) is deprecated, and tools that support it RPi.GPIO for example, have also dropped support or discontinued development.

The new interface for gpio manipulation is the chardev interface.

@morganchristiansson
Copy link

morganchristiansson commented Mar 8, 2021

Oh yeah it says in gpio/sysfs.txt

THIS ABI IS DEPRECATED, THE ABI DOCUMENTATION HAS BEEN MOVED TO
Documentation/ABI/obsolete/sysfs-gpio AND NEW USERSPACE CONSUMERS
ARE SUPPOSED TO USE THE CHARACTER DEVICE ABI. THIS OLD SYSFS ABI WILL
NOT BE DEVELOPED (NO NEW FEATURES), IT WILL JUST BE MAINTAINED.

It does seem to say it will be maintained and included in future kernels but no new features.... But yeah. Deprecated.

There's a bunch of shell tools: raspi-gpio gpio gpioset etc that do the same thing. I wasn't sure they're in the docker image so it was nice to use just echo and grep. Hopefully PSU control plugin can just support running inside docker in future version.

Btw the auto-power on/off by relay is like magic. So satisfying when it turns off 10 minutes after print. And turns on when you click print button in your slicer.

@jneilliii
Copy link

I know the PSU Control plugin has a version that kantlivelong has been working on that utilizes periphery instead of RPi.GPIO which may open it up to better docker compatibility.

@LongLiveCHIEF
Copy link
Member Author

Btw the auto-power on/off by relay is like magic. So satisfying when it turns off 10 minutes after print. And turns on when you click print button in your slicer.

For what it's worth, I've completely decoupled power features in octoprint from the printer and the octoprint host, and instead use home assistant with an esp01 to control a relay. OctoPrint can send a mqtt message when print is finished, and that auto-switches the printer to off. This also means I can control shutdown in case of crash of octoprint as well.

@morganchristiansson
Copy link

morganchristiansson commented Mar 14, 2021

use home assistant with an esp01 to control a relay

I also considered this. I've seen you can integrate octoprint with homeassistant. And I have a couple Sonoff S20 plugs which have esp8266 inside and you can flash your own mqtt firmware on them.

But I'm quite enjoying my integrated 3d printing tower with 2x Ender 3 pro connected to single Pi4 with 2x octoprint docker containers. I hotglued the relays inside the original PSU and turn the printers off by sending the 3.3v signal. Here's my build log https://imgur.com/a/y5Rth03

I'm going to attach ws2811b LED strip to my SKR Mini E3 2.0 boards next and get better lighting for the 2x connected cameras.

@LongLiveCHIEF
Copy link
Member Author

Nice. Here's mine. The photos at the bottom are the most recent. https://photos.app.goo.gl/ZiyXs526jnhR8kLz6

@oerkel47
Copy link

Fyi, with the new version of PSU-Control I found that it's enough to mount /dev/gpiochip0

nothing else necessary for me.

@morganchristiansson
Copy link

morganchristiansson commented May 1, 2021

I saw PSU Control 1.0 was released with python periphery which should fix this. Thanks for testing it!

https://github.com/kantlivelong/OctoPrint-PSUControl/releases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Roadmap
Research/Help Wanted
Development

No branches or pull requests

10 participants