Script läuft nicht wenn mit rc.local gestartet

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
mini1954
User
Beiträge: 3
Registriert: Donnerstag 9. Januar 2025, 15:11

Hallo,
ich habe ein kleines script (button.py) erstellt, dass die zuletzt gespeicherte MQTT Message aus einem csv-file liest und auf einem OLED-Display anzeigt.
Das script funktioniert ohne Fehlermeldung, wenn es in der Console mittels sudo python3 button.py aufgerufen wird, unabhängig davon, ob bereits ein pythonscrpt läuft oder nicht.

Code: Alles auswählen

import RPi.GPIO as GPIO
import time
from time import *
import csv
from luma.core.interface.serial import i2c, spi
from luma.core.render import canvas
from luma.oled.device import ssd1309
from PIL import ImageFont, ImageDraw, Image
from pathlib import Path

serial = i2c(port=1, address=0x3C)
device = ssd1309(serial)
font1 = ImageFont.truetype('/home/pi/oled/fonts/DejaVuSansMono.ttf', 11)
font2 = ImageFont.truetype('/home/pi/oled/fonts/C&C Red Alert [INET].ttf', 12)
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(27, GPIO.RISING, bouncetime=200)

while True:
    if GPIO.event_detected(27):
        print('Edge detected on channel', 27)
        with open('msg.csv', 'r') as file:
            reader = csv.reader(file)
            data = file.readlines()
            lastrow = data[-1]
            split_row = lastrow.rstrip('\n').split(',')
            event_date = split_row[0]
            event_time = split_row[1]
            topic = split_row[2]
            msg = split_row[3]
            print(event_date)
            print(event_time)
            print(topic)
            print(msg)
        with canvas(device) as draw:
            device.show()
            draw.text((5,3),event_date, font = font1, fill = "white")
            draw.rectangle((5, 19, 128, 20), outline="white", fill="white")
            draw.text((5,25), topic, font = font2, fill = "white")
            draw.text((5,39), msg, font = font2, fill = "white")
            draw.text((5,55), event_time, font = font2, fill = "white")
            file.close()
            sleep(5)
            device.hide()
    sleep(2)
Damit des script beim starten des pi aufgerufen wird, habe ich es mit

Code: Alles auswählen

python3 /home/pi/oled/button2.py &
in rc.local eingefügt. Nach einem reboot wird das script gestartet, funktioniert aber nicht. Habe ebenfalls versucht, das script mittels Service oder bash - file beim booten zu starten.
Ergebnis ist ebenfalls negativ.

Egal ob ich das script alleine über rc.local starte oder mit einem anderen script zusammen, keine Funktion.

Nun weiß ich nicht mehr weiter und wäre für einen Tipp dankbar.
Sirius3
User
Beiträge: 18115
Registriert: Sonntag 21. Oktober 2012, 17:20

rc.local benutzt man seit einigen Jahrzehnten nicht mehr. Aktuell sollte man eine Service-Unit mit systemd schreiben. Dann ist es auch relativ einfach, auf die Fehlermeldungen zu schauen. Ohne Fehlermeldung kommt man hier nämlich nicht weiter.
`as` bei Import ist zum umbenennen da. GPIO nennst Du aber gar nicht um, warum also `as`?
Du importierst einmal time und einmal mit * alles aus time. Erster Import wird nicht benutzt, beim zweiten solltest Du nur sleep importieren.
`spi`, `ImageDraw` und `Path` werden importiert, aber nicht benutzt.
Warum erzeugst Du einen csv-Reader, den Du dann gar nicht benutzt?
Du schließt eine Datei, die schon längst wieder per with-Block geschlossen worden ist.
Warnungen sind dazu da, dass man sie behebt, nicht dass man sie ignoriert.
Statt alle zwei Sekunden auf ein Event zu schauen, benutzt man GPIO.wait_for_edge.
Das ganze könnte dann ungefähr so aussehen:

Code: Alles auswählen

from RPi import GPIO
from time import sleep
import csv
from luma.core.interface.serial import i2c
from luma.core.render import canvas
from luma.oled.device import ssd1309
from PIL import ImageFont

EVENT_PIN = 27
MESSAGE_FILENAME = "/home/pi/oled/msg.csv"


def read_last_message():
    with open(MESSAGE_FILENAME, encoding="utf8") as file:
        reader = csv.reader(file)
        for lastrow in reader:
            pass
        return lastrow


def display_message(device, font1, font2, message):
    event_date, event_time, topic, msg = message
    with canvas(device) as draw:
        device.show()
        draw.text((5, 3), event_date, font=font1, fill="white")
        draw.rectangle((5, 19, 128, 20), outline="white", fill="white")
        draw.text((5, 25), topic, font=font2, fill="white")
        draw.text((5, 39), msg, font=font2, fill="white")
        draw.text((5, 55), event_time, font=font2, fill="white")
        sleep(5)
        device.hide()


def main():
    try:
        serial = i2c(port=1, address=0x3C)
        device = ssd1309(serial)
        font1 = ImageFont.truetype("/home/pi/oled/fonts/DejaVuSansMono.ttf", 11)
        font2 = ImageFont.truetype("/home/pi/oled/fonts/C&C Red Alert [INET].ttf", 12)
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(EVENT_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

        while True:
            if GPIO.wait_for_edge(EVENT_PIN, GPIO.RISING):
                print("Edge detected on channel", EVENT_PIN)
                message = read_last_message()
                display_message(device, font1, font2, message)
    finally:
        GPIO.cleanup()


if __name__ == "__main__":
    main()
mini1954
User
Beiträge: 3
Registriert: Donnerstag 9. Januar 2025, 15:11

Hallo und Danke für die Ratschläge.
Zu den Fragen: Wenn man nicht wirklich weiß was man tut, passieren solche Dinge. Ich suche mir aus verchiedenen scripts einzelne Teile, von denen ich meine, dass sie für mein Vorhaben geeignet sind.
Dann probiere ich so lange herum, bis es funktioniert oder eben auch nicht.
Ich werde jetzt mit Deinen Hinweisen auch mein script 1 auf Überflüssiges überprüfen.
Herzlichen Dank für das script. Ich habe es eben probiert und es funktioniert mit rc.local.

Kann ich noch irgendwo ein except KeyboardInterrupt einbauen? Das script lässt sich bein Testen nicht mit STRG - c stoppen.
Benutzeravatar
__blackjack__
User
Beiträge: 13764
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@mini1954: Ein ``except KeyboardInterrupt:`` wird daran nichts ändern. Das ermöglicht nicht den Abbruch, damit kann man festlegen was passieren soll *wenn* es mit Strg+C abgebrochen wird. Oder allgemeiner formuliert, wenn ein SIGINT-Signal an den Prozess gesendet wird.
“The city's central computer told you? R2D2, you know better than to trust a strange computer!” — C3PO
mini1954
User
Beiträge: 3
Registriert: Donnerstag 9. Januar 2025, 15:11

@ blackjack: Danke für die Info. Ich muss wohl noch einiges lernen.
Antworten