Problem mit Autostart und darauffolgender zerschossene SQlite3 Datenbank

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo allerseits,

    vorneweg, ich hoffe ich bin hier im richtigen Forenbereich? Falls nicht hoffe ich man kann den Thread ohne Probleme verschieben?

    Das eigentliche Problem:

    Ich habe, leider erfolglos, versucht 3 python scripts auf meinem Raspberry Pi 3B automatisch nach einem Neustart starten zu lassen.

    Dazu habe ich die gängigen Möglichkeiten via rc.local und crontab -e, zu denen es ja zahlreiche Forenbeiträge und Tutorials gibt, versucht, allerdings hat keine der

    Methoden letztendlich zum Erfolg versucht. Enttäuscht habe ich dann einfach wieder die 3 Skripte manuell im Hintergrund ausgeführt.

    Die Skripte im Überblick:

    1. ein python script welches Sensordaten im 3 Min. Takt in eine Text sowie eine CSV schreibt

    2. ein pythonn script welches selbige Sensordaten an die IOT-Plattform thingspeak sendet

    3. ein python script welche selbige Sensordaten zusätzlich im 5 Min. Takt in einer sqlite3 Datenbank speichert

    Der positive Teil, alle Skripte funktionieren wenn ich sie standesgemäß mittels sudo python test.py & starte und solange ich den Raspberry Pi nicht ausschalte, passt das ja auch (falls relevant alle Skripte und erstellte Datenbank + CSV + Textdatei sind im selben Ordner /home/pi). Nun wollte ich den Autostart einrichten, was sich in der Theorie und den Tutorials auch als ziemlich schnelle und einfache Sache angehört hat.

    Dazu habe ich folgendes versucht:

    1. über sudo nano /etc/rc.local vor exit 0 eingefügt (beispielhaft für das Skript welches die Textdateiund CSV erstellt):

    Code
    python /home/pi/asd2.py &

    Als das nicht funktioniert hat, habe ich in verschiedenen Forenbeiträgen gelesen man solle den Start via Sleep verzögern. Dazu hatte ich unterschiedliche Syntax gefunden die ich dann folgendermaßen versucht habe einzubinden:

    Code
    /bin/sleep 15 && python /home/pi/asd2.py 

    bzw. :

    Code
    (sleep 15 && python /home/pi/asd2.py &)

    Hier habe ich leider schon nicht rausgefunden, welche der beiden Sleep Varianten theoretisch die korrekte sein sollte, bzw. was der Unterschied zwischen beiden Varianten ist (vlt. kann mir da jemand aushelfen?). Ergänzend habe ich noch getestet (so hat es mir das Internet geraten) zu testen, ob ich die rc.local via einfachem sudo /etc/rc.local ausführen kann, das hat funktioniert da ich zuvor einen echo Befehl in die rc.local eingefügt hatte, der mir ein paar Wörter in eine Textdatei schreib und diese Wörter anschließender in der Textfile vorhanden waren.

    Die Codes habe ich natürlich für alle 3 Scripte versucht. Als es dann weiterhin nicht geklappt hat habe ich mich mit 1:0 zu Gunsten der rc.local geschlagen gegeben und versucht die Sache via crontab -e, folgerndermaßen, zu lösen:

    crontab -e eingeben, anschließend wurde ich gefragt welchen Editor ich haben möchte worauf ich nano gewählt habe. Dann habe ich folgendes eingegeben ans Ende der Crontab-Datei:

    Code
    @reboot python /home/pi/asd2.py &

    Der Befehl wurde auch wieder für alle 3 Skripte eingegeben. Nach einem Neustart hat leider keines der 3 automatisch gestartet. Daher war nun folgender Zwischenstand erreicht:

    Raspberry Autostart VS Ich 2:0.

    Als ich daraufhin die Skripte wieder manuell startete hatte ich folgenders Problem meine sqlite3 Datenbank mit dem Namen sensordata.db war plötzlich doppelt im Ordner vorhanden, was mich schon stutzig gemacht hatte. Als ich via. sqlite3 sensordata.db darauf zugegriffen hatte und per. SELECT * FROM temps; (temps ist der Tabellenname in dem die Daten gespeichert werden) testen wollte, ob dort noch alles beim Alten ist, bekam ich den Error: no such table: temps. Mittels ,fullschema habe ich festgestellt das keine Tabelle in der Datei existiert. Dann dachte ich, dass die entsprechende Tabelle demnach bestimmt in der anderen, aus heiterem Himmel erschienen, sensordata.db sein muss. Dementsprechend habe ich sie in sensordata3.db umbenannt und siehe da diese Datenbank hatte sogar 2 Tabellen, an die ich mich vage erinnern konnte sogar damals zum Test erstellt zu haben, die gesuchte Tabelle temps war allerdings auch hier nicht mehr vorhanden (Raspberry erhöht auf 3:0). Da ich in diversen Foren etwas von den Zugriffsrechten in Verbindung mit dem Autostart gelesen hatte, habe ich irgendwann (zeitlich nich mehr zu 100 Prozent einzuordnen) mal noch den Befehl

    Code
    sudo chmod +x asd2.py

    für alle 3 Scripts eingegeben, dort kam aber, wenn ich mich recht erinnere sogar eine Fehlermeldung. Ich weiß nicht, ob das eine Rolle spielt, dass ich den Befehl ausgeführt habe? Und ja, mir ist bewusst, "tue nichts, bei dem du dir nicht sicher bist!" aber ich habe aus Verzweiflung vorschnell gehandelt :blush:.

    Nun die große Frage, kann das überhaupt sein, dass die fehlende Tabelle das Resultat der vergeblichen Bemühung ist bzw. könnte es im besten Fall sogar sein, dass sich die Tabelle der SQlite3 Datenbank sogar noch irgendwo versteckt? Und vlt. hat ja jemand der sich die Mühe macht meinen Text zu lesen eine Ahnung, warum der Autostart nicht so will, wie ich? Verzweifelter Anfang hofft auf Hilfe und wird sich mit lebenslänglicher Dankbarkeit revanchieren, ansonsten wird der PI einfach seine Lebenszeit eingeschaltet verbringen!

    PS: Falls der Text zu lange ist und keiner bereit ist ihn zu lesen, verstehe ich das natürlich, meine Intention war lediglich direkt alle womöglich wichtigen Infos zu liefern, um nicht stückweise alles nachzuliefern.

    PPS: Wenn ich schon dabei bin, eines der Python Scripts wurde ausversehen zwei mal ausgeführt und meine Daten werden aktuell zwei mal statt einmal pro Minute an Thingspeak geliefert, wie kann ich einen der beiden Prozesse stoppen (jobs zeigt mir gar nichts an leider)

  • Problem mit Autostart und darauffolgender zerschossene SQlite3 Datenbank? Schau mal ob du hier fündig wirst!

    • Offizieller Beitrag

    Hallo und willkommen im Forum!

    Da ich hier am Handy sitze, habe ich den langen Text nur grob überflogen. Nur kurz zum Autostart:

    In gefühlt 99% der Fälle bei denen ein Autostart nicht funktionierte, waren fehlende absolute Pfade zum oder im Script der Grund. Das könnte in Deinem Fall ein Pfadzur DB oder Textdatei sein.

  • In gefühlt 99% der Fälle bei denen ein Autostart nicht funktionierte, waren fehlende absolute Pfade zum oder im Script der Grund.

    Und in den anderen 99% war das Netz noch nicht verfügbar, wurde aber benötigt....

    8o, STF

    • Offizieller Beitrag

    So, jetzt hab ich alles gelesen... vorweg, zur Datenbank kann ich nichts sagen, z.Zt. ist bei mir keine installiert und deshalb nicht nachvollziehbar.

    meine Intention war lediglich direkt alle womöglich wichtigen Infos zu liefern, um nicht stückweise alles nachzuliefern

    :thumbup: Ich wünschte das würden alle so sehen...

    eines der Python Scripts wurde ausversehen zwei mal ausgeführt

    Mit: ps -eo pcpu,pid,user,args | sort -r -k1 | less kannst Du Dir u.a. die PIDs anzeigen lassen und notieren. Aus dieser Anzeige kommst Du mit q (das kleine "Q") wieder raus.

    Mit kill -SIGTERM PID (PID ersetzen mit der zuvor angezeigten Nummer) wird das von Dir gewählte Script beendet.

    (sleep 15 && python /home/pi/asd2.py &)

    Diese Variante ist m.E. nicht richtig, denn das würde das Script rc.local blockieren. Richtiger wäre denke ich wenn schon Klammern, dann so (sleep 15 && python /home/pi/asd2.py)&.

    BTW: Das "&" am Ende ist in der Crontab auch nicht nötig, zum Verständnis wie Operatoren funktionieren hier ein Link: https://wiki.ubuntuusers.de/Shell/Operatoren.

    Ich weiß nicht, ob das eine Rolle spielt, dass ich den Befehl ausgeführt habe?

    Schaden kann es bei einem Autostart jedenfalls nicht. Haben die Scripte einen Shebang? Du übergibst zwar Deine Scripte an den Interpreter (python), aber wenn ein gültiger Shebang vorhanden ist, kannst Du Dir das auch sparen. Sind die wirklich alle in Python2?

    Was wir übrigens noch nicht kennen sind die Inhalte der Dateien. ;)

  • Vielen, vielen Dank schon einmal für die Antworten!

    Mit: ps -eo pcpu,pid,user,args | sort -r -k1 | less kannst Du Dir u.a. die PIDs anzeigen lassen und notieren. Aus dieser Anzeige kommst Du mit q (das kleine "Q") wieder raus.

    Mit kill -SIGTERM PID (PID ersetzen mit der zuvor angezeigten Nummer) wird das von Dir gewählte Script beendet.

    Vielen Dank, das habe ich mir gerade angeschaut und scheint wunderbar zu funktionieren! Der Start macht Hoffnung, alles erfolgreich zu lösen :).


    Diese Variante ist m.E. nicht richtig, denn das würde das Script rc.local blockieren. Richtiger wäre denke ich wenn schon Klammern, dann so (sleep 15 && python /home/pi/asd2.py)&.

    BTW: Das "&" am Ende ist in der Crontab auch nicht nötig, zum Verständnis wie Operatoren funktionieren hier ein Link: https://wiki.ubuntuusers.de/Shell/Operatoren.

    Auch hier für zunächst einmal vielen Dank für die Mühen, das werde ich mir definitiv genauer anschauen müssen, ich denke in dieser Hinsicht (nennen wir es Grundlagenverständnis) wird der Link nicht das Ende der Fahnenstange sein, um Raspbian als auch Python etc. letztendlich vollends zu verstehen, davon gehe ich jetzt einfach mal aus ;). Eine Frage dazu, angenommen der Autostart mit vorangestelltem sleep 15 würde funktionieren, würde dann nach 15 Sekunden Script 1 nach 30 Sekunden Script 2 und nach 45 Script 3 starten, wenn die Sleep 15 vor allen dreien stehen?

    Schaden kann es bei einem Autostart jedenfalls nicht. Haben die Scripte einen Shebang? Du übergibst zwar Deine Scripte an den Interpreter (python), aber wenn ein gültiger Shebang vorhanden ist, kannst Du Dir das auch sparen. Sind die wirklich alle in Python2?

    Okay, das ist ein Hinweis auf den ich so nie gekommen wäre, ich bin in meinem Leichtsinn (nur bezüglich des Raspberrys), zum einen davon ausgegangen, dass "default" Interpreter Python 3 ist, demnach war das aber eine Fehlannahme? Shebang steht nur in einem der drei Skripte und zwar als:#!/usr/bin/env python Gehe ich richtig in der Annahme, dass /env pythondie default Einstellung verwendet statt einer expliziten Zuordnun? Den Shebang bin ich während meiner Recherchen nach Ursachen auch schon gestoßen und wenn ich mich recht erinnere hatte ich gedacht, dass ich den nicht brauche da ich chmod ausgeführt hatte, was natürlich aber keinen Sinn macht wenn nach dessen Ausführung eine Fehlermeldung kam. Jetzt bin ich aber trotzdem etwas verwirrt, da ich ja sämtliche Varianten in crontab und rc.local für alle drei Skripte versucht hatte, sprich hätte dann theoretisch nicht wenigstens das mit dem Shebang funktionieren sollen?

    Was wir übrigens noch nicht kennen sind die Inhalte der Dateien. ;)

    Das stimmt natürlich! Darf man sich als Anfänger im Vorfeld schon für seine, wahrscheinlich völlig verpfuschten, Skripte rechtfertigen und entschuldigen? Die Skripte basieren alle auf der selben While-Schleife und habe ich mir aus anderen Forenbeiträgen bzw. den von grovepi mitgelieferten Scripts zusammengereimt, daher hat mich da auch verwundert, dass diese scheinbar funktionieren. Auch bei den Scripts freue ich mich über konstruktive Kritik :)! Ich hänge diese nun einfach mal an und riskiere, dass ich dadurch sämtliche Python Gurus und Profis zum Kopfschütteln verleite.

    Script 1 (.txt/.csv)

    Ich hoffe das sprengt jetzt nicht den Rahmen und es gibt einen Button um das Script ein bzw. auszuklappen!?

    Script 2 (Iot thingspeak)

    Und zu guter Letzt Script 3:

    So, ich hoffe damit kommen wir der Sache evtl. noch einmal einen Schritt näher :)!

    Und natürlich noch einmal vielen Dank für die Mühen ;)!

  • Hallo,

    Skripte starten: wenn du deine Skripte über systemd Service Untis starten würdest, dann könntest du a) über die Abhängigkeiten icherstellen, dass alle Dienste laufen, die dein Skript braucht, b) kannst du über das Logging von systemd Fehlermeldungen bekommen, wenn was nicht funktioniert, c) die Skripte automatisch neu starten, falls diese im laufenden Betrieb crashen.

    Zu den Skripten:

    Hat du einen konkrteten Grund, Python 2 statt Python 3 zu nehmen?

    Skript 1:

    `file` ist ein schlechtet Name unter Python2, weil du damit die Build-In Funktion `file`überschreibst. Da kann unerwünschte und schwer nachzuvollziehende Nebeneffekte haben. Unter Python3 wäre es egal, weil es da das Build-In `file`nicht mehr gibt.

    Benutze zum Öffnen von Dateien das `with` Statement. Dann hast du die Garantie, dass die Datei geschlossen wird. Bie dir ist es so, dass die Datei offen bleibt, wenn das Skript zwischen `open` und `file.close()`crasht.
    Die eckigen Klammern in Zeile 51 machen nicht so viel Sinn.

    Skript 2:

    Nachte `try...excpet` sind schlecht, weil du damit jegliche Fehler abfängst, auch Programmierfehler. Das kann zu unerwünschten Nebeneffekten und einem "überraschenden" Programmverlauf führen. Fehler fängt man gezielt ab.
    Nach der Zeile 31 fehlt was...?
    Du öffnest eine Verbindung zur DB und einen Cursor, nutzt diesen aber nirgendwo im Skript.

    Skript 3:

    Wenn das Skript in der `while` Schleife crasht, bleibt die Datenbankverbindung offen. Auch die Verbindung zu SQLite kannst du in ein `with` Statement einbetten, so dass die Verbindung geschlossen wird.

    Die eckigen Klammern in Zeile 18 machen nicht so viel Sinn.

    Anstatt das Skript 5 Minuten im Leerlauf warten zu lassen macht es IMHO mehr Sinn, es periodisch alle 5 Minuten zu starten, z.B. über eine systemd Timer Unit.

    Alle Skipte: Unter Python wird mit 4 Leerzeichen pro Ebenen eingerückt.

    Gruß, noisefloor

  • Hallo noisefloor,

    vielen, vielen Dank für die Erklärung zu den drei Skripten!

    Skripte starten: wenn du deine Skripte über systemd Service Untis starten würdest, dann könntest du a) über die Abhängigkeiten icherstellen, dass alle Dienste laufen, die dein Skript braucht, b) kannst du über das Logging von systemd Fehlermeldungen bekommen, wenn was nicht funktioniert, c) die Skripte automatisch neu starten, falls diese im laufenden Betrieb crashen.

    Wenn ich das richtig verstehe soll ich quasi das hier befolgen, richtig?: https://www.raspberrypi.org/documentation/…sage/systemd.md

    Zu den Skripten: Hat du einen konkrteten Grund, Python 2 statt Python 3 zu nehmen?

    Ich muss gestehen, dass das das Resultat von Unwissenheit und Unbekümmertheit ist :angel:. Logischerweise würde ich zu Python 3 tendieren, wovon ich die ganze Zeit ausgegangen bin, dass es auch benutzt wird (peinlich, ich weiß).

    Skript 1:

    Das mit der Variable "file" macht die Wahl von Python3 natürlich noch logischer!

    Die eckigen Klammern in Zeile 51 machen nicht so viel Sinn.

    Okay, das ist echt seltsam weil das ein Teil des vorgefertigten Codes des Seeed Grove Temo. + Hum. Sensors ist, da bin ich einfach davon ausgegangen, dass diese Codes "fehlerlos" sind bzw. dem Optimalcode zumindest ziemlich nahe kommen sollten :). Sollten dort dementsprechend runde Klammern, sprich () stehen? Das mit den Klammern, dazu werde ich natürlich selbstständig recherchieren, um ein Gefühl dafür zu bekommen. Aber ist das dann nicht seltsam, dass es trotzdem läuft wenn das die falschen Klammern sind, in Matlab beispielsweise geht bei falschen Klammern in der Regel nicht viel.

    Skript 2:

    Nach der Zeile 31 fehlt was...?
    Du öffnest eine Verbindung zur DB und einen Cursor, nutzt diesen aber nirgendwo im Skript.

    Vollkommen richtig, ist beim kopieren verloren gegangen, danach steht folgendes:

    Code
    if __name__ == "__main__":
            channel = thingspeak.Channel(id=channel_id, write_key=write_key, api_ke$
            while True:
                    measure(channel)
                    time.sleep(60)

    Große Frage, der Cursor wird trotzdem nicht verwendet, wenn ich das richtig sehe!? Aber die Daten kommen im Minutentakt fleißig bei thingspeak an, ich muss sagen den Code finde ich auch (für mich als Laien) nicht 100 Prozent nachzuvollziehen :).

    Skript 3:

    Das mit der While-Schleife macht natürlich Sinn, dass das absolut besser wäre. Das with Statement muss ich mir definitiv anschauen, dass das in Zukunft besser läuft!

    Systemd Timer Unit nehme ich an verläuft nach dem selben Prinzip, wie ich es mit dem obigen Link versucht habe darzustellen oder bin ich da auf dem Holzweg (Google wird mir wahrscheinlich ansonsten die Antwort binnen Sekunden geben, aber ich frage jetzt trotzdem einfach mal :)). Das heißt die Timer Unit macht aber nur für das dritte Skript Sinn, die anderen sind in Ordnung per Endlosschleife laufen zu lassen, aber bei 5 Minuten Intervallen wäre es sinnvoller, es mit der von dir beschriebenen Lösung zu machen?

    Zu den 4 Leerzeichen ebenfalls vielen Dank, Matlab ist da nicht so streng mit den Einzügen, daran muss ich mir definitiv noch gewöhnen ;).

    Vielen, vielen Dank für die Super Hilfe auch an dieser Stelle, ich werde schnellstmöglich versuchen die angesprochenen Dinge umzusetzen!

    Grüße

  • Hallo,

    Zitat

    Sollten dort dementsprechend runde Klammern, sprich () stehen?

    Nein, gar keine. Python unterstützt die gleichzeitige Zuweisung von mehreren Variablen. Das Stichwort laute: "unpacking". Mini-Demo:

    Python
    >>> my_list = ['foo', 'bar']
    >>> spam, egg = my_list
    >>> spam
    'foo'
    >>> egg
    'bar'
    >>>

    Wenn eine Funktion, wie in deinem Falle, mehrere Rückgabewerte hat, kannst du diese direkt mehreren Variablen zuweisen.Aber ist das dann nicht seltsam, dass es trotzdem läuft wenn das die falschen Klammern sind,

    Warum Python das in diesem Fall ignoriert und die korrekte Zuweisung macht weiß ich auch nicht.

    In Skript 2 nutzt du ja gar keine Datenbank - also brauchst du auch keine Verbindung dazu aufbauen.

    Bzgl. `with`: das Stichwort das ist "Context Manager". Das muss man im Detail nicht verstehen - wichtig ist nur zu wissen, dass der Context-Manager sich automatisch um das Schließen (der Datei, der Verbindung, ...) kümmert.

    systemd: Im von dir genannten Link ist es ziemlich knapp erklärt, richtig. Wen du es auch deutsch Lesen möchtest: bei wiki.ubuntuusers.de/systemd ist es ausführlicher erklärt. Gilt weitestgehend auch für Raspbian, was da steht.

    Python2 vs. 3: deine Skripte sollten IMHO auch ohne Probleme unter Python3 laufen. Vorausgesetzt, du hast `grovepi` auch für Python3 installiert. Die Shebang-Zeile #!/usr/bin/env python ruft explizit Python2 auf, für Python3 wäre es #!/usr/bin/env python3

    Gruß, noisefloor

  • Wenn eine Funktion, wie in deinem Falle, mehrere Rückgabewerte hat, kannst du diese direkt mehreren Variablen zuweisen.Aber ist das dann nicht seltsam, dass es trotzdem läuft wenn das die falschen Klammern sind,

    Das erklär mal bitte noch einigen Python-Anfängern. Komischerweise gehen irgendwie immer fast alle davon aus, das man bei Mehrfachzuweisungen ein Tuple erstellen muss und packen auf der linken Seite Klammern drum.

    Warum Python das in diesem Fall ignoriert und die korrekte Zuweisung macht weiß ich auch nicht.

    Ich gehe mal schwer davon aus, dass du Python-Opcode lesen kannst ;)

    Wie sie sehen... sehen sie, dass beide Arten von Klammern einfach ignoriert werden. Tuple auf der rechten Seite auspacken, a und b zuweisen (und None zurückgeben weil wir in der Python-Shell sind). Ich habe im Moment keine Zeit, im CPython Source die Quelle dieses Verhaltens zu finden, aber naja. Es geht.

    Python2 vs. 3: deine Skripte sollten IMHO auch ohne Probleme unter Python3 laufen. Vorausgesetzt, du hast `grovepi` auch für Python3 installiert. Die Shebang-Zeile #!/usr/bin/env python ruft explizit Python2 auf

    Nicht wenn du den Befehl python auf Python 3 umbiegst! Unter einem Standard-Raspbian stimmt deine Aussage, aber nicht pauschal. Nimmste ein "rohes" Linux und packst nur Python 3 drauf, gehen python und python3 (und python3.x) alle zu Python 3. Jede Wette.

    Werde ich jedes mal auf der Arbeit daran erinnert, ist zwar ein Windows aber nur mit Python 3. Den Befehl python3 gibt's gar nicht per default, nur python. Ist aber auch ne Anaconda-Installation :daumendreh2:

  • Hallo,

    Zitat


    Nicht wenn du den Befehl python auf Python 3 umbiegst!

    Nee, wer macht denn sowas? ;) Habe ich auch nicht vorgeschlagen.

    Es verwirrt mich auch jedes Mal aus neue, wenn ich auf meinem Win Büro-Rechner `python` eintippe und es kommt Python 3.5 aus der Anaconda Installation. Wobei Anaconda unter Win viiiiiel mehr Sinn macht als unter Linux - aber das ist off-topic :)

    Gruß, noisefloor

    • Offizieller Beitrag

    Hallo fred0815,

    die Pfade

    Code
    PATH=/usr/local/bin:/usr/local/sbin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/bin/X11

    kennt die Cron, zumindest bei Ubuntu. Ich habe hier leider gerade keinen RPi in der Pampa und kann so nicht schnell mal crontab -e aufrufen, um nachzusehen ob der Eintrag bei Raspbian der selbe ist. :denker:

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!