Pythonプログラムをサービスとして使用することはできません。

Pythonプログラムをサービスとして使用することはできません。

起動時に非常に単純なPythonプログラムを実行し、それ自体を再起動しようとしています。

Pythonプログラムは端末で正しく実行されます。サービスは失敗メッセージのみを表示します。

sudo systemctl status logger_autostart.service
logger_autostart.service - Logging Signal Strength of Rockblock Iridium
     Loaded: loaded (/etc/systemd/system/logger_autostart.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Thu 2023-12-07 07:55:57 CET; 1s ago
    Process: 3340 ExecStart=/usr/bin/python3 /home/pi/Downloads/signal_test.py (code=exited, status=1/FAILURE)
   Main PID: 3340 (code=exited, status=1/FAILURE)
        CPU: 204ms

Dec 07 07:55:57 raspberrypi systemd[1]: logger_autostart.service: Scheduled restart job, restart counter is at 5.
Dec 07 07:55:57 raspberrypi systemd[1]: Stopped Logging Signal Strength of Rockblock Iridium.
Dec 07 07:55:57 raspberrypi systemd[1]: logger_autostart.service: Start request repeated too quickly.
Dec 07 07:55:57 raspberrypi systemd[1]: logger_autostart.service: Failed with result 'exit-code'.
Dec 07 07:55:57 raspberrypi systemd[1]: Failed to start Logging Signal Strength of Rockblock Iridium.

私のサービスファイル:

[Unit]
Description=Logging Signal Strength of Rockblock Iridium
After=multi-user.target

[Service]
Type=simple
User=pi
ExecStart=/usr/bin/python3 /home/pi/Downloads/signal_test.py
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n

[Install]
WantedBy=multi-user.target

以下を使用すると、エラーログは表示されません。 journalctl -f -u echo-logger_autostart.service

プログラム:

import time
from datetime import datetime
import RPi.GPIO as GPIO
import time
import serial
from adafruit_rockblock import RockBlock
import logging
import random
import os
from threading import Event

# GPIO pins for LEDs
led_pins = [17, #green (no connection)
            27, #yellow (bad connection)
            22, #red (good connection)
            23] #blue (during startup / for )
# GPIO pin for the button
button_pin = 18

loop_active = False

def Board_Setup():
    # Set GPIO mode and warnings
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    # Setup LED pins as output
    for pin in led_pins:
        GPIO.setup(pin, GPIO.OUT)
        GPIO.output(pin, GPIO.LOW)

    # Setup button pin as input with pull-up resistor
    GPIO.setup(button_pin, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

def rockblock_setup() -> RockBlock:
    uart = serial.Serial("/dev/ttyUSB0", 19200)
    return RockBlock(uart)

def all_leds_off():
    for pin in led_pins:
        GPIO.output(pin, GPIO.LOW)

def red_led_on():
    GPIO.output(led_pins[2], GPIO.HIGH)

def yellow_led_on():
    GPIO.output(led_pins[1], GPIO.HIGH)

def green_led_on():
    GPIO.output(led_pins[0], GPIO.HIGH)

def toggle_blue_led():
    state = GPIO.input(led_pins[3])
    if state == GPIO.HIGH:
        GPIO.output(led_pins[3], GPIO.LOW)
    else:
        GPIO.output(led_pins[3], GPIO.HIGH)

def button_pressed_callback(channel):

    global loop_active

    loop_active = not loop_active

def create_log_file():
    # Create logfile using current time in Y-M-D
    if not os.path.exists("logs/"):
        os.makedirs("logs/")

    current_datetime = datetime.now()
    timestamp = current_datetime.strftime("%Y-%m-%d")
    log_file_name = f"log_{timestamp}.txt"
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(message)s",
        datefmt="%H:%M:%S",
        filename = "logs/" + log_file_name
    )

def run_logger():
    # log signal strength every 10s
    global loop_active
    create_log_file()
    rb = rockblock_setup()
    # wait until button is pressed
    GPIO.add_event_detect(button_pin, GPIO.BOTH, callback=button_pressed_callback)
    print("use switch to start logging")
    while not loop_active:
        pass
    print("logging started")
    while loop_active:

        
        quality = rb.signal_quality
        # random int while antenna gets fixed
        # quality = random.randint(0,5)
        logging.info(quality)
        print(quality)
        if quality == 0:
            all_leds_off()
            red_led_on()
        elif quality <= 3:
            all_leds_off()
            yellow_led_on()
        elif quality <= 5:
            all_leds_off()
            green_led_on()

        time.sleep(3)

def main():
    Board_Setup()
    # Run Logger after button press
    toggle_blue_led()

    try:        
        run_logger()
    finally:
        all_leds_off()
        GPIO.cleanup

if __name__ == '__main__':
    main()

私が見つけることができる唯一の「興味深い」動作は、sudoを使用してもPythonプログラムは機能しませんが、sudo -Eを使用すると動作します。

私はPythonやUbuntuサービスに慣れていないので、現在これをデバッグするのは本当に難しいです。

サービスが.shプログラムで起動しようとしましたが、サービスにUser = piを追加しましたが、成功しませんでした。

関連情報