The power_button.py below works perfectly fine when executed as user.
If executed as a service, it fails to blink.
Please note that my main user is not "pi" but "pilot" - you may need to change that if running the "User=pilot" in install.sh
this is my install.sh, which creates the service:
this is my power_button.py :
If executed as a service, it fails to blink.
Please note that my main user is not "pi" but "pilot" - you may need to change that if running the "User=pilot" in install.sh
this is my install.sh, which creates the service:
Code:
set -eSCRIPT_PATH="/usr/local/bin/power_button.py"SERVICE_PATH="/etc/systemd/system/power-button.service"echo "Installing Python script..."install -m 0755 power_button.py "$SCRIPT_PATH"echo "Creating systemd service..."cat > "$SERVICE_PATH" <<'UNIT'[Unit]Description=CM4 Power Button & Status LEDWants=dev-gpiomem.device dev-gpiochip0.deviceAfter=dev-gpiomem.device dev-gpiochip0.device multi-user.targetConditionPathExists=/dev/gpiochip0[Service]Type=simpleWorkingDirectory=/home/pilotEnvironment=PYTHONUNBUFFERED=1Environment=GPIOZERO_PIN_FACTORY=lgpioExecStart=/usr/bin/python3 -u /usr/local/bin/power_button.pyRestart=on-failureRestartSec=2User=pilotSupplementaryGroups=gpioPrivateDevices=noStandardOutput=journalStandardError=journal[Install]WantedBy=multi-user.targetUNITecho "Reloading systemd and enabling service..."systemctl daemon-reloadsystemctl enable --now power-button.serviceecho "Service installed and started."systemctl status power-button.service --no-pagerthis is my power_button.py :
Code:
from gpiozero import LED, Buttonimport timeimport threadingimport subprocessimport sys# --- begin: service-sanity ---import os, timeprint(f"[boot] uid={os.getuid()} gid={os.getgid()} groups={os.getgroups()}", flush=True)for path in ("/dev/gpiochip0", "/dev/gpiomem"): for _ in range(50): if os.path.exists(path): break time.sleep(0.1)# --- end: service-sanity ---LED_PIN = 21BUTTON_PIN = 20led = LED(LED_PIN)button = Button(BUTTON_PIN, pull_up=True, bounce_time=0.05, hold_time=3.0)shutdown_triggered = threading.Event()def forever_pulse_led(): print("[worker] awaiting btn...", flush=True) while not shutdown_triggered.is_set(): led.toggle() time.sleep(0.1 if button.is_pressed else 0.5)def on_button_held(): # handling continuous long press print("[event] Button longpress -> SHUTDOWN requested", flush=True) shutdown_triggered.set() led.on() time.sleep(0.5) try: subprocess.run(["sudo", "poweroff"], check=False) except Exception as e: print(f"[error] poweroff failed: {e}", file=sys.stderr, flush=True)button.when_held = on_button_heldtry: print("[main] Starting...", flush=True) led.off() pulse_thread = threading.Thread(target=forever_pulse_led) # non-daemon pulse_thread.start() # Keep main alive until shutdown while not shutdown_triggered.is_set(): time.sleep(0.5)except KeyboardInterrupt: print("[main] KeyboardInterrupt", flush=True)Statistics: Posted by Anders1 — Thu Sep 25, 2025 10:59 am