Autostart Python Script

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Hallo zusammen,


    ich habe mich jetzt ein wenig mit dem Autostart von Python Scripte befasst und wollte mal Eure Meinung wissen, ob das so jetzt die beste Lösung ist.


    Python Script (Wenn ein Signal am GPIO 25 ankommt, wird in die Datenbank der Zähler um eins hochgezählt. Dies kann alle paar Sekunden passieren, aber auch nur einmal in der Woche):



    Bisher hatte ich 2 Möglichkeiten:


    1.

    in /etc/rc.local diese Zeile hinzugefügt ->

    /usr/bin/python3 /home/pi/programm.py &


    2.

    in /etc/xdg/autostart/display.desktop ->

    [Desktop Entry]

    Name=programm

    Exec=/usr/bin/python3 /home/pi/programm.py &


    Jetzt bin ich aber auf systemd gekommen und habe unter /etc/systemd/system einen neuen Dienst mit folgendem Inhalt erstellet:



    Alle 3 Möglichkeiten funktionieren und meine Frage ist nun, welche von den ist die Beste oder gibt es noch eine bessere?


    Es läuft auf einem Raspberry 3 B+ (Raspbian Buster) inkl. 7" Touch-Display mit einer ScanDisk ultra 32GB.


    Gruß

    Tamia

  • Hier hätte ich jetzt auch noch ein Problem.


    Das Python Script aus #1 funktioniert nicht, wenn längere Zeit kein Signal am GPIO 25 ankommt.

    In die Datenbank wird nichts geschrieben. Nach einem Restart des Scripts oder einem kompletten reboot vom Raspberry funktioniert es wieder. Wenn durchgehend immer wieder ein Signal ankommt gibt es keine Aussetzer. Eben nur wenn längere Zeit gar nichts kommt.


    An was kann das liegen bzw. was kann man dagegen machen?


    Wenn ich den Status von dem Service abfrage, wäre dieser angeblich aktive.


    Gruß

    Tamia

  • Den Service haben ich um 13:14 Uhr neu gestartet, es läuft also wieder.

    Code
    ****@****:~ $ journalctl -u zaehler
    -- Logs begin at Tue 2022-03-29 09:17:05 CEST, end at Wed 2022-03-30 13:58:31 CE
    Mär 29 09:25:51 **** systemd[1]: Started zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Stopping zaehler Service...
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Main process exited, code=ki
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Succeeded.
    Mär 30 13:14:33 **** systemd[1]: Stopped zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Started zaehler Service.
    lines 1-7/7 (END)


    Hier mal eine Notdürftige Skizze, wie ich es verkabelt habe, damit der GPIO 25 sein Signal bekommt, wenn das Relais schaltet.



    Ist es eigentlich richtig, dass ich im Script pull_up=False drin habe bzw. fehlt da noch etwas?

    Kann es am sleep(3) oder pause() liegen, dass das Script irgendwann nicht mehr reagiert wenn länger kein Signal an GPIO 25 ankommt?


    EDIT:

    pause() brauche ich ja, ansonsten wird das Script beendet.

    sleep(3) brauche ich nicht unbedingt, aber nach einem Signal wird 3 Sekunden gewartet, sollte innerhalb dieser Zeit ein Signal kommen, wird es nicht gezählt.


    Gruß

    Tamia

  • Das sleep(3) nehme ich dann mal raus, weiß nicht mehr warum ich es damals (war irgendwann letztes Jahr) da reingetan habe.


    btn.when_held deshalb, weil es doch für hold_time=0.3 notwendig ist oder? Zumindest lese ich das hier raus.

    Ich möchte ja das pressed ausgeführt wird, wenn mind. für 0.3sec das Signal am GPIO 25 anliegt.


    Ich schalte deshalb gegen 3V3 weil ich dachte, es wäre für das Relais und GPIO besser. Denn ansonsten liegen da ja immer die 3V an, außer das Relais schaltet. Wenn also kein Signal kommt, sind permanent 3V drauf. In meinem Fall nur dann, wenn das Relais kurz schaltet.


    Oder habe ich da einen Denkfehler drin?


    Aber kann dies alles dazu führen, dass mein Script nicht mehr reagiert?


    EDIT:

    Ich habe es jetzt mal zum testen so geändert, dass gegen GND geschaltet wird. GND geht vom Raspberry zum Relais, wenn das schaltet wird GND durchgeschleift und geht wieder zurück zum Raspberry.

    Funktioniert soweit auch. Das Python Script sieht jetzt so aus:



    Da ich ja einen externen 10k Widerstand benutze, brauche ich pull_up=true in diesem Fall nicht oder?


    Trotzdem bleibt offen, warum mein Script nach einer gewissen Zeit nicht mehr reagiert bzw. reagiert hat.


    Gruß

    Tamia




  • btn.when_held deshalb, weil es doch für hold_time=0.3 notwendig ist oder? Zumindest lese ich das hier raus.

    Ok, wenn Du die 0,3 Sekunden brauchst, dann ist es richtig so.


    Ich schalte deshalb gegen 3V3 weil ich dachte, es wäre für das Relais und GPIO besser. Denn ansonsten liegen da ja immer die 3V an, außer das Relais schaltet. Wenn also kein Signal kommt, sind permanent 3V drauf. In meinem Fall nur dann, wenn das Relais kurz schaltet.


    Oder habe ich da einen Denkfehler drin?

    Das stimmt zwar, aber der Stromverbrauch ist nur minimal und das erkennen eines Flankenwechsels ist optimaler als andersherum.


    Da ich ja einen externen 10k Widerstand benutze, brauche ich pull_up=true in diesem Fall nicht oder?

    Das brauchst Du bei einem Pullup eh nicht, weil das per default aktiv ist. Der externe 10k hat da auch wenig Sinn, aber der stört zumindest erstmal nicht.


    trotzdem bleibt offen, warum mein Script nach einer gewissen Zeit nicht mehr reagiert bzw. reagiert hat.

    Die Ausgabe im Beitrag #5 von journalctl -u zaehler ist am Ende der Zeilen abgeschnitten. Zeile 5 wäre ggf. interessant. Ansonsten warten wir bis der Fehler wieder auftaucht und Du postest die Ausgabe erneut.

  • Der externe 10k hat da auch wenig Sinn, aber der stört zumindest erstmal nicht.

    Ah ok, dachte der muss drin sein. Soll/kann ich den rausnehmen?


    Die Ausgabe im Beitrag #5 von journalctl -u zaehler ist am Ende der Zeilen abgeschnitten. Zeile 5 wäre ggf. interessant. Ansonsten warten wir bis der Fehler wieder auftaucht und Du postest die Ausgabe erneut.

    Sorry, das war mein Fehler. Aber das um 13:14 war mein Restart von dem Service.

    Code
    ****@****:~ $ journalctl -u zaehler
    -- Logs begin at Tue 2022-03-29 09:17:05 CEST, end at Wed 2022-03-30 18:41:10 CEST. --
    Mär 29 09:25:51 **** systemd[1]: Started zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Stopping zaehler Service...
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Main process exited, code=killed, status=15/TERM
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Succeeded.
    Mär 30 13:14:33 **** systemd[1]: Stopped zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Started zaehler Service.


    Gruß

    Tamia

  • Soll/kann ich den rausnehmen?

    Nö, lass den erstmal da.


    Das Python Script aus #1 funktioniert nicht, wenn längere Zeit kein Signal am GPIO 25 ankommt.

    Dazu hätte ich mal eine Frage: Das Signal zum GPIO 25 kommt ja von dem Relais. Funktioniert das Relais vielleicht in diesem Moment nur nicht oder das Skript?

  • Guten Morgen zusammen,


    neuer Tag neues Glück.


    Das Script hängt wieder, so ein Mist.

    Code
    ****@****:~ $ journalctl -u zaehler
    -- Logs begin at Tue 2022-03-29 09:17:05 CEST, end at Thu 2022-03-31 07:38:28 CEST. --
    Mär 29 09:25:51 **** systemd[1]: Started zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Stopping zaehler Service...
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Main process exited, code=killed, status=15/TERM
    Mär 30 13:14:33 **** systemd[1]: zaehler.service: Succeeded.
    Mär 30 13:14:33 **** systemd[1]: Stopped zaehler Service.
    Mär 30 13:14:33 **** systemd[1]: Started zaehler Service.


    Was passiert eigentlich, wenn aus irgendeinem Grund pressed nicht ausgeführt werden kann. Macht das Script dann trotzdem weiter und warten auf das nächste Signal oder bleibt es hängen? Das könnte ja eine Erklärung sein, warum das Script nicht beendet war und trotzdem nichts in die Datenbank geschrieben wurde.



    Dazu meine nächste Frage.

    Die Datenbank ist ja auf dem Raspberry. Auf unserem großen Server ist auch eine Datenbank, mit dieser kommuniziert der Raspberry auch, aber nur lesen, er schreibt nix rein. Wäre es nicht sinnvoller, nicht mehr in die Datenbank auf dem Raspberry zu schreiben sondern gleich in die große Datenbank?

    Ich war mir da nicht sicher ob das gut ist. Im "schlimmsten" Fall kann es ja sein, das diese Datenbank von 35 Raspberrys alle 20 Sekunden Daten bekommt.

    Wieviel hält so eine Datenbank denn aus, also wieviel gleichzeitige Zugriffe sind kein Problem und ab wann kann es kritisch werden?

    Info zur Datenbank:


    Der Server hat keinen Zugriff von außen, also die Leitung ins Internet ist gekappt falls das relevant sein sollte. Auf diesen Server kann man nur von intern aus zugreifen.


    Gruß

    Tamia

  • Grüß dich,


    du könntest statt journalctl -u zaehler auch bei systemctl status zaehler.service schauen ob da eine Fehlermeldung aufgelistet wird. Vorrausgesetzt du hast das Script jetzt noch nicht neu gestartet.


    Ansonsten würde ich folgendes Probieren:

    Normalerweise müsste dann, wenn irgendein Fehler kommt, dieser mittels systemctl status zaehler.service angezeigt werden können bzw. dein Script sollte bei einem Fehler trotzdem weiterlaufen.

    Ich weiß jetzt nicht ob da nicht noch ein sudo vor der Statusabfrage müsste?


    Kannst du das so mal testen?


    Edit:

    Was passiert eigentlich, wenn aus irgendeinem Grund pressed nicht ausgeführt werden kann. Macht das Script dann trotzdem weiter und warten auf das nächste Signal oder bleibt es hängen?

    Theoretisch ja. Da das pause() das Script am laufen hält.

    Könnte sein das irgendwas beim beschreiben der DB etwas schiefläuft und deswegen das Script abschmiert. Bzw. innerhalb der def pressed():

    Probleme auftreten.

    Das ist aber alles nur eine Vermutung.

    Edited once, last by keepfear ().

  • Zum sleep(3), auch wenn Du Dich nicht mehr erinnerst, wozu das eigentlich war:


    Zum "Hänger":

    neuer Tag neues Glück.


    Das Script hängt wieder, so ein Mist.

    Kann es sein, dass MySQL einen Timeout hat, wenn eine offene Verbindung lange nichts meldet?


    Ich würde zum Testen den DB-Teil auskommentieren, nur ein print(...) nutzen und dann längere Zeit laufen lassen.

    Dann kann man den "Hänger" besser eingrenzen.

  • Leider hab ich es schon neu gestartet. Wenn es aber wieder nicht funktioniert, mache ich Deine Abfrage.

    Zu Deinem Script, was bedeutet, bzw. was bewirkt


    Python
    except Exception as e:
        print(e)

    ?


    Kann es sein, dass MySQL einen Timeout hat, wenn eine offene Verbindung lange nichts meldet?


    Kann ich das mit dem Timeout auch wo nachsehen, oder geht das nur über testen wie Du es geschrieben hast?

    Danke für den Tipp mit  sleep(3)


    Gruß

    Tamia

  • Kann es sein, dass MySQL einen Timeout hat, wenn eine offene Verbindung lange nichts meldet?

    Deswegen das try - except und das Auslesen der Fehler via status meine_unit.service


    Zu Deinem Script, was bedeutet, bzw. was bewirkt

    Ich sag es grob mit meinen Worten.

    Wenn Fehler -> gib Fehler aus (deswegen print) bzw. akzeptiere den Fehler -> Script läuft weiter