Autostart python script

  • Hallo zusammen,


    leidiges Thema. Python-Scripte automatisch nach dem Boot-Vorgang zu starten...


    Mein erster Versuch ging über die rc.local.

    Code
    sleep 10
    usr/bin/python /home/pi/control_scripts/script.py

    Ich habe zwei Scripte, von denen sich das erste Script starten lässt und das zweite leider nicht. In beiden Scripten wird an den GPIOs herum gespielt. Script 2 benötigt allerdings Netzwerkzugang, da es einen MqttBroker anspricht und es lädt einigen Fremdcode ein. Meine Vermutung war, dass irgendetwas zum Zeitpunkt des Scriptstart noch nicht bereit war. Daher habe ich beschlossen, dass ich mich mit den systemd service units auseinanderzusetzen.


    Mein zweiter Versuch über systed.

    Habe es exakt so umgesetzt, wie es hier (Anleitung von raspberrypi-spy) beschrieben wurde.

    Einzig am "Type" habe ich aufgrund einiger Internetbeiträge herumprobiert: idle, forking, oneshot

    Auch hier hat sich ergeben, dass Script 1 startet, Script 2 aber nicht.


    Wenn ich im Fall von Script 2 den status nach dem Reboot abfrage...

    Code
    systemctl status myscript.service

    ... steht da, dass der Service inaktiv ist und der Fehlercode 1.


    Kann mir evtl. jemand weiterhelfen?

    Braucht Ihr mein gesamtes Script?


    Viele Grüße,

    Alex

  • Hallo,


    Quote

    Daher habe ich beschlossen, dass ich mich mit den systemd service units auseinanderzusetzen.

    Weise Entscheidung.

    Quote


    Habe es exakt so umgesetzt, wie es hier (Anleitung von raspberrypi-spy) beschrieben wurde.

    Nicht gut. a) ist die Anleitung von 2015 (=3,5 jahre alt) und systemd entwickelt sich weiter, b) legt man eigene Skripte nicht unter /lib/... ab - da liegen nur Skripte vom System. Eigene systemweiste Skripte sollten man unter /etc/systemd/system oder Nutzer-bezogene Skripte im Homeverzeichnis ab. Siehe auch https://wiki.ubuntuusers.de/systemd/

    Wobei das ziemlich sicher nicht der Grund ist, warum Skript zwei nicht startet.


    Du solltest systemd Units immer 1x manuell starten, damit die eventuell auftretenden Fehler direkt in der Ausgabe siehst. Und wenn du das journal von systemd über journalctl abfragst, siehst du eventuell auch noch weitergehende Fehlermeldungen.


    Laufen die Skripte fehlerfrei, wenn du sie von Hand startest?


    Gruß, noisefloor

  • Hallo zusammen,


    erst einmal danke für die vielen Antworten.


    Kurz zum Hintergrund: Ich habe im Rahmen eines Hausumbaus in jedem Raum einen RaspberryPi verbaut, der über ein eigenes IO-Board einige Dinge im Raum steuern kann. Die Raspberrys befinden sich mit einem Rechner mit OpenHab zusammen in einem separatem Netzwerk (ohne Internetzugang. Daher hatte ich aufgrund des Aufwands gehofft, mit wenig Screenshots und Zitaten auszukommen. ;) ) Die Raspberrys und OpenHab kommunizieren über Mqtt. Mein Script hat die Aufgabe, die Mqtt-Kommunikation und die IO-Steuerung zu übernehmen.


    hyle

    Das "After=" einfach in den Unit-Bereich einfügen? Also so?

    Linus

    Der "/" ist einfach beim Erstellen des Beitrags verloren gegangen


    noisefloor

    Wenn in ein Thema neu einsteigt, ist es manchmal nicht so einfach, "gute" und "schlechte" oder veraltete Informationen voneinander zu unterscheiden. Aber danke für den Hinweis. Wenn der Pfad der Units nicht die Fehlerquelle ist, würde ich den erst verlegen, wenn das erste Problem behoben ist.

    Manuell starten über "systemctl start myscript.service"?

    Ja zur Laufzeit gestartet, funktionieren meine Scripte. Einfach gestartet über den Aufruf "python autostart.py", wenn ich mich in meinem user-Verzeichnis befinde.


    Starte ich die Unit manuell, kommt folgende Meldung:

    Code
    pi@ControlPiArbeiten:~ $ systemctl start myscript.service
    Failed to start myscript.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
    See system logs and 'systemctl status myscript.service' for details.

    Die Abfrage des Status ergibt folgendes:

    Der ImportError "No module named events" wundert mich etwas, da das Script manuell gestartet ja funktioniert, inkl. der events.


    Viele Grüße,

    Alex

  • Starte ich die Unit manuell, kommt folgende Meldung:

    Code
    pi@ControlPiArbeiten:~ $ systemctl start myscript.service
    Failed to start myscript.service: The name org.freedesktop.PolicyKit1 was not provided by any .service files
    See system logs and 'systemctl status myscript.service' for details.

    Welche Meldung kommt wenn Du mit sudo startest?

    Code
    sudo systemctl start myscript.service

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

  • Hallo,


    das ist doch schon mal schön ausführlich :)


    Die `After=multi-user.target` macht IMHO keinen Sinn. Die Unit wird ja per deiner Direktiven vom multi-user.target verlangt bzw. im Rahmen dessen gestartet, d.h. `after` kann nicht sein.


    Es gibt auch ein `network-online.target` (müsstest du mal googlen, wie das genau heißt, damit ist nicht nur der Netzwerk Stack verfügbar, sondern der Pi sollte auch eine Verbindung zum Netz haben.


    Die PolKit Fehlermeldung ist komisch... die hat denke ich auch nichts mit deinem Skript zu tun, sondern das ist ein Rechteproblem, was normalerweise nicht existieren sollte. Kommt die Meldung bei der Unit, die du gepostet hast?


    Das der Import-Fehler nur bei der Unit kommt sollte eigentlich auch nicht sein, wenn das alles sauber installiert ist... Fragen:

    • Du verwendest wirklich noch Python 2?
    • Du hast du die Module alle für Python 2 installiert?
    • Wie hast du die Module installiert?

    Zum Logging: das Logging über das Umbiegen von stdout und stderr zu machen ist auch nicht so ideal für Anwendungen, die Produktiv laufen sollen. Python hat dafür das logging-Modul an Bord, was mit Sicherheit besser und mächtiger ist als deine selbstgebaute Lösung. Und damit hättest du auch Unterstützung für Logrotation.


    Gruß, noisefloor

  • Genau das wird ja über PolKit geregelt.

    Ja, aber evtl. ist PolKit nicht installiert oder nicht "richtig" installiert.


    EDIT:


    BTW: Evtl. hätte man hier die service unit auch als user-eigene service unit anlegen bzw. aktivieren können. Z. B.:

    Code
    systemctl --user enable myscript.service

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    Edited once, last by rpi444 ().

  • rpi444

    Mit "sudo" bekomme ich genau die gleiche Meldung.


    noisefloor

    After=multi-user.target schmeiß ich raus und seh zu, was passiert.


    Das network-online.target sieht bzgl. Netzwerk vielversprechend aus.

    network.target has very little meaning during start-up. It only indicates that the network management stack is up after it has been reached. [...]


    network-online.target is a target that actively waits until the nework is "up", where the definition of "up" is defined by the network management software. Usually it indicates a configured, routable IP address of some kind. Its primary purpose is to actively delay activation of services until the network is set up. [...]


    network-pre.target is a target that may be used to order services before any network interface is configured. [...]

    Mit PolKit-Fehler meinst Du die PolicyKit Meldung beim starten der Unit? Ja, passiert bei genau der Unit.


    Welches Python (ob 2 oder 3) genau verwendet wird, da bin ich noch nicht so richtig hinter gestiegen. Auf dem Pi läuft "Raspbian Stretch". Scheinbar sind beide Pythons direkt vorinstalliert. Nachinstalliert habe ich folgendes, um Mqtt in Python nutzen zu können.

    Code
    sudo apt-get install python-pip
    sudo pip install paho-mqtt

    Verstanden, logging wird umgebaut.


    rpi444

    Ich habe PolKit nicht aktiv installiert. Wenn ich es brauche, mache ich das natürlich noch. :)

  • Ich habe PolKit nicht aktiv installiert.

    Wie ist z. Zt. auf deinem PI, die Ausgabe von:

    Code
    apt-cache policy policykit-1

    ?

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

    • Official Post

    Nur zu Deinem Verständnis... ;)

    Welches Python (ob 2 oder 3) genau verwendet wird, da bin ich noch nicht so richtig hinter gestiegen.

    Wenn Du das Script mit

    Code
    /usr/bin/python /home/pi/control_scripts/script.py

    startest, dann verwendest Du Python2. Wenn es mit

    Code
    /usr/bin/python3 /home/pi/control_scripts/script.py 

    gestartet wird, dann verwendest Du Python3.


    Mit pip install paho-mqtt installierst Du das Modul für Python2.

    Mit pip3 install paho-mqtt installierst Du das Modul für Python3.

  • Habe in der Zwischenzeit die Unit, wie vorhin geschrieben, angepasst.

    Code
    [Unit]
    Description=Autostart meiner ControlPi Scripte
    After=network-online.target
    
    [Service]
    Type=forking
    ExecStart=/usr/bin/python /home/pi/autostart.py
    
    [Install]
    WantedBy=multi-user.target


    Der PolKit-Fehler beim Starten der Unit ist weg, sobald das Starten der Unit mit "sudo" gemacht wird. Der Unterschied ist mir vorhin durch die Lappen gegangen.

    Ansonsten bleibt der Fehler der Gleiche.

    Code
    pi@ControlPiArbeiten:~ $ sudo systemctl start myscript.service
    Job for myscript.service failed because the control process exited with error co                                                                                                      de.
    See "systemctl status myscript.service" and "journalctl -xe" for details.

    Auch die Meldung bei der Statusabfrage bleibt die Gleiche.


    rpi444:

    Code
    pi@ControlPiArbeiten:~ $ apt-cache policy policykit-1
    policykit-1:
      Installiert:           (keine)
      Installationskandidat: 0.105-18+deb9u1
      Versionstabelle:
         0.105-18+deb9u1 500
            500 http://raspbian.raspberrypi.org/raspbian stretch/main armhf Packages

    hyle:

    Ich erinnere mich schwach. Das Aufsetzen der Pis ist schon ein wenig her. Wenn ich mich richtig erinnere, hatte ich damals Probleme beim Installieren für Python3 (über pip3). Wenn das für diesen Vorgang wichtig ist, versuche ich mich noch einmal daran. Ansonsten würde ich die Baustelle später wieder auf machen.

  • In meinem Beitrag #5 habe ich gestern das Ergebnis der Statusabfrage meiner Unit gepostet. Da wurde unter anderem folgende Fehlermeldung geworfen.

    Python
    Feb 17 04:37:18 ControlPiArbeiten python[829]:     from events import Events
    Feb 17 04:37:18 ControlPiArbeiten python[829]: ImportError: No module named events

    Ich habe heute den Import des Moduls "events" und alle Verweise darauf aus meinem Script entfernt. Natürlich verliere ich dadurch wichtige Funktionen. Wenn ich nun aber die Unit über "sudo systemctl start myscript.service" starte, startet die Unit zunächst problemlos und ich kann übers Netzwerk mit meinem Script kommunizieren. Nach einigen Sekunden (ca. 10?) beendet die Unit dennoch mit einer Fehlermeldung.

    Code
    pi@ControlPiArbeiten:~ $ sudo systemctl start myscript.service
    Job for myscript.service failed because a timeout was exceeded.
    See "systemctl status myscript.service" and "journalctl -xe" for details.

    Die Statusabfrage ergibt folgendes Ergebnis.

    Vielleicht hat ja jetzt noch jemand eine Idee...


    Ich lege meinen Quellcode gerne offen, falls das hilft. Bitte verzeiht mir meinen Schreibstil. ;) Sind meine ersten Gehversuche in Python.



    Ich erwarte nicht, dass jeder sofort durch meine Software durchblickt. Allerdings scheint der Inhalt doch mit dem Erfolg oder Misserfolg der Unit zusammenzuhängen. In der Datei "SmartHomeItem.py" werden die events importiert, die zum Fehler führen. Beim manuellen Start über "python autostart.py" gibt das keine Probleme.

  • Wenn ich nun aber die Unit über "sudo systemctl start myscript.service" starte, startet die Unit zunächst problemlos und ich kann übers Netzwerk mit meinem Script kommunizieren. Nach einigen Sekunden (ca. 10?) beendet die Unit dennoch mit einer Fehlermeldung.

    Versuch mal in der service unit, statt mit "Type=forking", mit:

    Code
    Type=oneshot
    RemainAfterExit=yes

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

  • rpi444:

    Wir kommen der Lösung immer näher, danke. Nach den von Dir genannten Änderungen läuft das Script durch, also endlos, ohne Abbruch.


    Dann bleibt noch die Frage, warum ich das Module "events" beim manuellen Start nutzen kann, über die Unit aber nicht.

  • Dann bleibt noch die Frage, warum ich das Module "events" beim manuellen Start nutzen kann, über die Unit aber nicht.

    Hast Du auch nach der letzen Änderung, mit dem Modul "events"schon getestet?

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden

  • Hallo,

    nur als kleiner Einwurf, ich nutze bei meinen Service Units für Python Skripte welche endlos laufen: Type=simple


    Welches Python (ob 2 oder 3) genau verwendet wird, da bin ich noch nicht so richtig hinter gestiegen.

    Das musst du aber wissen welches Python verwendet wird, wie willst du sonst die passenden Module für die passende Version installieren?! Deswegen wohl das Problem mit events. Das Ziel ist übrigends Python 3 ;)

  • nur als kleiner Einwurf, ich nutze bei meinen Service Units für Python Skripte welche endlos laufen: Type=simple

    Ja. BTW: "Type=oneshot" (ist default) + "RemainAfterExit=yes" ist identisch mit "Type=simple".

    The most popular websites without IPv6 in Germany.  IPv6-Ausreden