I figured it out! I now have a button that will turn off a raspberry pi AND wake it from the same pins (5 & 6) using no power and only two wires. I wanna make this into a repository and share it for people who need this button functionality. I may have some stuff in here that is extra (extra packages that may not be needed) so I’m going to reine this a bit but this all works just fine. Any suggestions or comments about things that could be better would be greatly appreciated.
One big issue was trying to use dbus-python but that has been depreciated and is VERY difficult to work with.
Dockerfile
FROM balenalib/%%BALENA_MACHINE_NAME%%-debian-python:3.7.4
# Enable systemd init system
ENV INITSYSTEM off
# Set the working directory
WORKDIR /usr/src/app
RUN install_packages git dbus gnome-common
RUN apt-get update
RUN apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0
# Upgrade pip
RUN pip install --upgrade pip
COPY requirements.txt .
RUN pip install --user -r requirements.txt --no-cache-dir --disable-pip-version-check \
--index-url https://www.piwheels.org/simple
# Copy everything into the container
COPY . ./
#Make sure scripts in .local are usable:
ENV PATH=/root/.local/bin:$PATH
ENV DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket
# Start application
CMD ["python", "button.py"]
requirements.txt
RPi.Gpio
pydbus
Pycairo
PyGObject
button.py
#!/usr/bin/env python3
#!
import RPi.GPIO as GPIO
import time
import pydbus
import gi
# Set GPIO mode: GPIO.BCM or GPIO.BOARD
GPIO.setmode(GPIO.BOARD)
# Set pin 5 an an input, and enable the internal pull-up resistor
GPIO.setup(5, GPIO.IN, pull_up_down=GPIO.PUD_UP)
oldButtonState1 = True
while True:
buttonState1 = GPIO.input(5)
if buttonState1 != oldButtonState1 and buttonState1 == False :
bus = pydbus.SystemBus()
logind = bus.get('.login1')['.Manager']
logind.PowerOff(True)
oldButtonState1 = buttonState1
time.sleep(1)
Thank you @KingstonSteele for your help. I struggled with that too, but in the end, I preferred using the API to do so, as it has less dependencies:
(you need to enable API access with: io.balena.features.supervisor-api: 1)
Wire a push button between GPIO3 (pin 5) and GROUND (pin6).
By default (and you cannot change this) pushing it will boot up the pi if it’s off.
Then add gpio-shutdown to your dtoverlay (either using balena cloud or config.txt).
It will initiate a clean shutdown process when the button is pressed and the pi in on.
By default it will be on GPIO3 as well, which makes it handy, but you can change the pin if you like.
Voilà you got your ON/OFF button without writing a line of code
Notes :
the shutdown is the same as if you typed shutdown in a terminal or called the shutdown using dbus or the supervisor
when the shutdown process is finished the act led will blink 10 times to inform that it properly shutdown
the board is in a low power mode, but still consume power
in the same idea, 5v and 3.3v pins from the 40pins header will continue to provide power to any peripheral connected
if you need a deeper shut down, you need to use more complex circuitry and have a look at the gpio-poweroff dto which would turn a GPIO HIGH when the soft shutdown is done (up to you to use that to actually turn off power)