Fehlermeldung und Programmabbruch nach einigen Wochen Betrieb

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

    auch durch dieses Forum läuft meine Solarthermieanlage seit fast 2 Jahren und hat schon eine Menge Energie eingespart. Die Anlage und damit der Raspberry ist permanent an. Es gibt ca. alle 2 Monate eine Fehlermeldung (die soweit ich das sehe auch immer die selbe ist), womit auch das Programm abbricht. Das ist natürlich ärgerlich und könnte sogar gefährlich werden, da die gesamte Steuerung der Anlage damit brach liegt. Daher meine Frage: Woran liegt das bzw. was kann man dagegen tun? Fehler

    Wäre toll wenn ich das in den Griff bekommen könnte,

    viele Grüße

    Axel

  • Fehlermeldung und Programmabbruch nach einigen Wochen Betrieb? Schau mal ob du hier fündig wirst!

  • Es gibt ca. alle 2 Monate eine Fehlermeldung (die soweit ich das sehe auch immer die selbe ist), womit auch das Programm abbricht. Das ist natürlich ärgerlich und könnte sogar gefährlich werden, da die gesamte Steuerung der Anlage damit brach liegt. Daher meine Frage: Woran liegt das bzw. was kann man dagegen tun? Fehler

    Wie wird das Programm gestartet bzw. wie wird das aktiv sein des Programms überwacht?

    Ist es auch dann noch gefährlich, wenn das Programm sofort nach dem Abbruch, wieder gestartet wird?

    BTW: Den Link mit dem "Fehler" kann ich nicht benutzen bzw. nicht öffnen.

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

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • Hallo,

    bitte poste auch noch das Programm dazu.

    Da scheint es Probleme mit i2c zu geben. Möglich dass da ein Buffer vollläuft oder ähnliches.

    Wenn man auf den Link klickt, erhält man dieses Bild:

    Bitte in Zukunft die Fehlermeldung im Code-Block (der </> - Button) posten und den Code auch.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Immer wieder Wahnsinn, wie schnell es hier Feedback gibt. Lieben Dank!

    Hier der Code

  • Wie wird das Programm gestartet bzw. wie wird das aktiv sein des Programms überwacht?

    Ist es auch dann noch gefährlich, wenn das Programm sofort nach dem Abbruch, wieder gestartet wird?

    BTW: Den Link mit dem "Fehler" kann ich nicht benutzen bzw. nicht öffnen.

    Das Programm starte ich einfach in "Thonny Python IDE". Da läuft es dann und steuert lustig. Weiß auch nicht ob das so eine gute Idee ist. Wenn das Programm nach Abbruch sofort wieder gestartet werden würde, würde das vermutlich klappen.

  • Hallo,

    starte das Programm nicht über Thonny.

    Um den Fehler abzufangen, kannst du sowas versuchen:

    Allerdings musst du dann noch auf die Exception entsprechend reagieren. Die Werte 'None' setzen oder je nach dem was halt zum Programm passt.

    Das ganze wird aber irgendwo anders im Programm nochmal ausgelesen. Kann es sein dass das ganze zeitgleich passiert und es da zu Probleme kommt?

    Du solltest das strukturieren. Eine Funktion, eine Aufgabe. Eine Funktion liest aus und wenn man die Werte braucht ruft man die Funktion auf.

    Die "Ergebnisse" des auslesens sind ja im ganzen Programm global verfügbar. Da weis kein Mensch wo wann wie welche Werte herkommen. Du musst die Namen durch die Funktionen reichen und wieder zurück geben. So blickt ja selbst Python nicht mehr durch, wie man sieht.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Wenn das Programm nach Abbruch sofort wieder gestartet werden würde, würde das vermutlich klappen.

    Dann versuch mal das Programm, mit einer service-unit zu (re)starten. Als Beispiel die service-unit mit der ich einen MusicBot (re)starte:

    Spoiler anzeigen

    Du wirst für dein Programm nicht alle Optionen brauchen.

    BTW: Falls es damit funktioniert, kannst Du zusätzlich (... zur Herstellung von Redundanz) den Status der service-unit mit einem shell-Script und einem cronjob (oder timer-unit) abfragen und entsprechend agieren lassen.

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

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • Zu deinem Code im Allgemeinen:

    'os', 'sys', 'datetime' wird importiert aber nicht genutzt.

    Importe von unterschiedlichen Modulen schreibt man nicht in eine Zeile, sondern jeden Import für sich.

    Auf Modulebene (der Code ohne Einrückungen) darf kein ausführbarer Code stehen. Ausnahme ist der Einstiegspunkt in die 'main'-Funktion. Alles andere gehört in eine Funktion. Auf Modulebene steht nur Code, der Klassen, Funktionen oder Konstanten definiert. Jeder Wert, der änderlich ist, muss einer Funktion beim Funktionsaufruf übergeben werden und wird, wenn nötig, wieder an die aufrufende Funktion zurück gegeben. Global dürfen diese Werte nicht verfügbar sein.

    In Python schreibt man Namen klein_mit_unterstrich, Ausnahmen sind Klassen in PascalCase-Schreibweise und Konstanten KOMPLETT_GROSS. Namen sollten dabei sprechend sein und keine nichtssagende Abkürzungen. Wenn einem kein Name einfällt oder man gezwungen wird die Namen durchzunummerieren ohne dass die Nummern einen wirklichen Mehrwert bieten, braucht man vielleicht keine Namen, sondern man packt die Objekte besser in eine Liste oder eine andere Datenstruktur.

    'result' ist ein seltsamer Name für eine Zeit.

    'pi2' lässt eher an Pi im Quadraht erinnern, anstatt an 2 * pi. Zu dem verwirrd dein Kommentar auch. Du schreibst es wird der Sonnenuntergang bestimmt und dann folgt 2*pi, nur pi und pi im Bogenmaß.

    Dann erstellst du in deiner Dauerschleife immer wieder die gleichen Funktionen. Funktionen erstellt man einmal und ruft sie dann nur noch auf.

    'if' benötigt keine Klammer.

    Anstatt monat = monat +12 kann man  monat += 12 schreiben. Später bei 'x += pi2' machst du das ja.

    In 'BerechneZeitgleichung' hast du viele 'if'-Abfragen.

    Du musst dabei beachten, dass wenn die erste erfüllt ist, danach, also durch die anschleißende Addition, vielleicht auch die zweite erfüllt wird. Ist das so gewollt? Wenn nicht dann gibt es 'elif', dann wird nur dieser Zweig ausgeführt, der die Bedingung erfüllt.

    In 'Sonnenauf_untergang' wir 'Minute' berechnet aber nicht weiter verwendet.

    Dann wird schon wieder 'localtime' verwendet, das hast du doch noch als 'result'. Und ein paar Zeilen später kommt 'result' nochmal.

    Die 'if'-Abfragen nach 'lt_monat' sollten 'elif' bekommen, denn es kann ja in einem Durchgang nur eine einzige zu treffend sein. Das gilt für 'lt-tag' auch.

    Deine Zirkulationspumpe, wenn die auf 'AUS' steht, aber der 'temp_speicher' > 76 ist, dann schält die Pumpe ein. Wiederspricht sich das nicht?

    Zu was die Abfrage nacht 'tm_hour == 8' und nach 'tm_hour == 20', wenn beides mal genau das gleiche passiert? Das könnte man sicherlich zusammen fassen.

    Was soll in der 'for'-Schleife 'a' bedeuten?

    An dieser Stelle würde man jetzt die Funktion aufrufen, die die i2c Channels ausliest, anstatt alles noch mal nieder zu schreiben. Auch der Kommentar 'FÜLLPHASE AN' ist seltsam, was wird da denn gefüllt? Es wird 15 mal ein paar Daten ausgelesen, etwas gerechnet und wieder einmal 'result' überschrieben. Wenn dann sollte dass vielleicht dahin, wo eine Pumpe eingeschaltet wird und nicht da wo sie schon läuft.

    Nach dem 'FÜLLPHASE beendet' ist läuft P1 aber noch mit 80%. Ich weis nicht was P1 sein soll, aber ist das Absicht?

    Und so zieht sich das durch.

    Der Code ab Zeile 417 wird durch deine Dauerschleife nie ausgeführt. Also auch dein 'cleanup'-Aufruf wird nicht erreicht.

    Wie du siehst ist da viel quer und durcheinander, nicht nur das es für einen Fremden sehr schwer lesbar ist, sondern auch das immer wiederkehrende definieren von gleichen Objekten und Funktionen.

    Es wäre sicherlich kein Fehler und würde zur Problembehebung nur beitragen, wenn man den Code ordentlich neu aufbaut.

    Da ich leider noch einige Fragezeichen im Kopf habe und auch durch die Namensgebung und Kommentare eher verwirrter wurde, macht es für mich gerade nicht viel Sinn den Code zu überarbeiten.

    Um Schritt für Schritt an dein Ziel zu kommen, wirst du hier aber auf jeden Fall unterstützt.


    Als kleines Beispiel, nur ein Programm, dass die Sensoren ausliest, könnte so aussehen. Du siehst in 'main' wird definiert, dann wird eine Funktion aufgerufen, dabei wird eine Liste mit den i2c_channels übergeben. In der Funktion werden die Werte der Sensoren ausgelesen und eine Liste mit den Daten wird zurück an 'main' gegeben.

    Die Nächste Funktion wäre jetzt, die Daten zu verarbeiten/auszusortieren nach Verwendung etc.


    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Dann versuch mal das Programm, mit einer service-unit zu (re)starten. Als Beispiel die service-unit mit der ich einen MusicBot (re)starte:

    Spoiler anzeigen

    Du wirst für dein Programm nicht alle Optionen brauchen.

    BTW: Falls es damit funktioniert, kannst Du zusätzlich (... zur Herstellung von Redundanz) den Status der service-unit mit einem shell-Script und einem cronjob (oder timer-unit) abfragen und entsprechend agieren lassen.

    Hallo rpi444,

    das ist mir einfach zu hoch. Komme ich leider nicht mit klar, aber trotzdem vielen Dank!

  • Es gibt ca. alle 2 Monate eine Fehlermeldung (die soweit ich das sehe auch immer die selbe ist), womit auch das Programm abbricht.

    Wenn das Programm so lange fehlerfrei läuft, dann aber (fast) immer an der gleichen stelle abbricht, könnte es ein, dass eine Systemressource nicht mehr aussreicht.

    Zum Beispiel kann das bei langlaufenden System die es Prozess-ID sein. (Muss es hier aber nicht)

    Dazu gibt es einige Mölichkeiten, einmal das hochsetzen der maximalen Anzahl, wenn die vom System begrenzt wird), man könnte natürlich auch einfach das System in einer "Schwachlastzeit", in dem es nicht gebraucht wird, eu starten.

    Es kann auch ganz einfach sein dass der freie Speicher vollläuft, so dass einige Funktionen nicht mehr durchgeführt werden können. Um eine Datei/ein Gerät öffnen zu können, werden auch Ressourcen benötigt.

    In deinem Fall wird es nicht so einfach sein, die Fehlerursache zu finden, denn es läuft ja. Nur eben nicht nach zwei Monaten ;) Und wenn man mehr Logdaten sammelt, um die Ursache einschränken zu können, könnte es sein,dass man dadurch die eingeschränkte Systemressource früher einschränkt.

    Oder, durch leicht geänderte Aufrufe, der Fehler eben nicht mehr auftritt.

    Computer ..... grrrrrr

  • Hallo Dennis,

    vielen Dank für das umfangreiche Feedback. Vieles ist "unkonventionell", ich bin da halt komplett mit trail and error rangegangen.

    Habe nur ca. 30 Jahre alte Basic- und TurboPascal-Erfahrungen. Der erste Teil zur Bestimmung der Sonnenuntergangszeit ist "aus dem Netz". Insofern verstehe ich diesen Teil auch nicht. Und sicher, das ist für einen Fremden schwer nachvollziehbar.

    Grobe Struktur ist:

    Bestimmung der Sonnuntergangszeit

    Monatsbezogene Differenzen zum Abschalten der Anlage

    7 Tage im Monat startet die Zirkulationspumpe

    Zirkulationspumpe zur Speichertemp.begrenzng

    P2 zur Umschichtung und Vermischung starten (P = Pumpen, es gibt 3 Stück)

    Start eigentliches Programm

    - Plausibilitätsprüfung

    - Startsequenz (Füllung)

    - Aufwärmphase

    - Arbeitsphase (Mit verschiedenen Bedingungen zu Ausstieg, u.a. auch durch die Sonnenuntergangszeit)

    Hier noch einige Kommentare zu deinen Textstellen:

    Deine Zirkulationspumpe, wenn die auf 'AUS' steht, aber der 'temp_speicher' > 76 ist, dann schält die Pumpe ein. Wiederspricht sich das nicht?

    --> Nein, das soll genau so sein da ich mit der Zirkulationspumpe die Anlage kühle (jaja, das ist unkonventionell)

    Zu was die Abfrage nacht 'tm_hour == 8' und nach 'tm_hour == 20', wenn beides mal genau das gleiche passiert? Das könnte man sicherlich zusammen fassen.

    --> Um 8:00 Uhr und 20:30 Uhr (die Anlage ist das sonnenstandsbedingt auf jeden Fall aus) wird ggf. 10 Min umgeschichtet, ist so gewollt

    Was soll in der 'for'-Schleife 'a' bedeuten?

    --> Es ist eine Art Taktung hinterlegt, die mit dem Faktor a verändert wird, z.B. weil der Temperaturdifferenz zw. Kollektor und Speicher über einem Wert ist. Dann wird das Hochzählen von a beschleunigt.

    'FÜLLPHASE AN' ist seltsam, was wird da denn gefüllt?

    --> Ist eine Drain-Back-Anlage, die wird gefüllt und wenn sie aus ist läuft das Wasser zurück.

    Nach dem 'FÜLLPHASE beendet' ist läuft P1 aber noch mit 80%. Ich weis nicht was P1 sein soll, aber ist das Absicht?

    --> Ja, es gibt 2 Pumpen im Kollektorkreis und eine im Speicherkreis

    Der Code ab Zeile 417 wird durch deine Dauerschleife nie ausgeführt. Also auch dein 'cleanup'-Aufruf wird nicht erreicht.

    --> Ich weiß, habe ich irgendwie nie gelöscht


    Du hast sicher recht, dass das Programm nicht nach den "normalen" Konventionen gemacht ist. Ich denke trotzdem, dass der Fehler damit nicht behoben werden würde. Denn es ist doch das Auslesen der analogen Temp.- und des Durchflusswertes, was aber auch immer wieder an diversen (4) Stellen aktuell passieren muss, was den Fehler auslöst (I/O-Error). Daher wäre ich eher bei deinem ersten Eintrag, der (soweit ich das verstehe) diesen Prozess kontrollieren will. Ich würde versuchen den Block des Auslesens an den 4 Stellen entsprechen an zu passen. Und ich würde sagen das passiert nie zeitgleich, er ist ja immer an einer der 4 Stellen. Könntest Du mir deine Ausführung unten nochmal etwas erklären.

    "Allerdings musst du dann noch auf die Exception entsprechend reagieren. Die Werte 'None' setzen oder je nach dem was halt zum Programm passt."

    Das wäre toll.

    Vielen Dank nochmal!

    Grüße

    Axel

  • könnte man zusammenfassen zu

    Code
       # Zuweisung Monat zu der Differenzeit, wie viele Minuten vor Sonnunenuntergang die Anlage ausgeschaltet wird (SU_STOP = AN)
       SU_grenze = (40, 50, 50, 60, 110, 130, 110, 60, 50, 50, 40, 40)[lt_monat]


    Und

    zu:

    Code
       # Zirkulationspumpe jeden 1., 4., 8., 12., 16., 20., 25. 6.20 Uhr an wegen Hygiene
       if lt_tag in (1, 4, 8, 12, 16, 20, 25):
          Zirkpumpe_hygiene = 'AN'
  • das ist mir einfach zu hoch. Komme ich leider nicht mit klar,...

    Du wirst doch mit nano eine Textdatei erstellen können, oder?

    Poste mal die Ausgabe von:

    Code
    ps aux | grep -i [p]ython

    , wenn dein Programm aktiv ist.

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

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

  • Hallo Axel,

    da Dein geschilderter Fehler auf Probleme mit der Library bzgl. sm.bus bzgl. I2C hindeutet, würde ich an Deiner Stelle folgendes machen:

    • drastisches Erhöhen der Kommunikationsfrequenz (also häufigeres Senden von Kommandos, Auslesen von Ergebnissen).

    Wenn das Programm um den entsprechenden Faktor schneller "abstürzt", dann hast Du die Quelle entdeckt. Irgendeine Ressource ist "vollgelaufen".

    Wenn das Programm unverändert nach Abgleich der bekannten Zeit abstürzt, dann liegt etwas anderes als Ursache vor.

    Loggt Dein Programm irgendwelche Ereignisse mit? Kann es sein, dass die Datei zu groß wird? Wird diese Log-Datei vielleicht im RAM abgelegt?

    Hast Du logrotate aktiviert?


    Ich würde ein kleines Monitor-Programm schreiben, das allgemeine Zustände ermittelt, wie

    • CPU-Temperatur
    • Freier RAM
    • Freier Speicher der SD-Karte oder des Mediums, von dem Du bootest
    • Takt-Frequenz der CPU-(Kerne)
    • Verlauf der Load-Averages

    und diese und ggf. andere Parameter graphisch auftragen lassen.

    Das Monitoring-Programm kann auch gleichzeitig prüfen, ob Deine Anwendung noch läuft - und ggf. neu starten.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (16. Mai 2022 um 10:16)

  • Du wirst doch mit nano eine Textdatei erstellen können, oder?

    Poste mal die Ausgabe von:

    Code
    ps aux | grep -i [p]ython

    , wenn dein Programm aktiv ist.

    Moin, das ist das Ergebnis:

    Code
    pi@raspberrypi:~ $ ps aux | grep -i [p]ython
    pi        1055  3.0  0.9  86860 38996 ?        Sl   07:21   5:28 /usr/bin/python3 /usr/bin/thonny
    pi        1060  0.0  0.0      0     0 ?        Z    07:21   0:00 [python3] <defunct>
    pi        1115  0.9  0.4  33608 16464 ?        S    07:21   1:37 /usr/bin/python3 -u -B /usr/lib/python3/dist-packages/thonny/backend_launcher.py
    pi@raspberrypi:~ $ 
  • Hallo Andreas,

    gute Idee, ich könnte über Nacht nur die analog-Werte permanent auslesen lassen um das so zu prüfen. Allerdings ist die Fehlermeldung, die ich hier gepostet habe, nicht die erste in der Art, sprich: Der Fehler ist immer im I/O-Bereich.

    Es wird keine Log-Datei oder sonstwas angelegt.

    "Hast Du logrotate aktiviert?" nein

    Ja, so ein kleines Progrämmchen schreiben ... hört sich super an. Macht man das auch in Python, die laufen dann parallel?

    Viele Grüße

    Axel

  • Hallo Axel,

    das Monitor-Programm kannst Du mit jeder Programmiersprache erstellen, die Du dafür nützen möchtest. Zwei meiner Beispiele:

    Hier werden 3 Betriebsspannungen, Umgebungstemperatur, CPU-Temperatur, freier, Arbeitsspeicher, freier SD-Speicher und die CPU-Auslastung angezeigt.

    Außerdem wird die Ausgabe von dmesg in umgekehrter Reihenfolge ausgegeben.

    Ein anderes Beispiel:

    Hier wird eine Konfigurationsdatei gelesen, in der zu überwachende Programme und deren Pfade enthalten sind. Die Programme werden gestartet. Bei Bedarf kann man die Programme beenden und neustarten. Programme mit negativer PID laufen gerade nicht. Ist der Button daneben ohne Text, dann kann das Programm auch nicht gestartet werden (falscher Pfad).

    Mal als Anregung für Dich.

    Beste Grüße

    Andreas

    Bilder

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • ... das ist das Ergebnis:

    Code
    pi@raspberrypi:~ $ ps aux | grep -i [p]ython
    pi        1055  3.0  0.9  86860 38996 ?        Sl   07:21   5:28 /usr/bin/python3 /usr/bin/thonny
    pi        1115  0.9  0.4  33608 16464 ?        S    07:21   1:37 /usr/bin/python3 -u -B /usr/lib/python3/dist-packages/thonny/backend_launcher.py

    Und jetzt noch die Ausgaben von:

    Code
    ps -o ppid= -p 1055
    ps -o ppid= -p 1115
    sudo lsof -p 1055
    sudo lsof -p 1115
    ps aux | grep -i [t]honny
    systemctl list-units --all | grep -i thonny

    ?

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

    Meine PIs

    PI4B/8GB (border device) OpenBSD 7.4 (64bit): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server

    PI3B+ FreeBSD 14.0-R-p3 (arm64): SSH-Serv., WireGuard-Serv., ircd-hybrid-Serv., stunnel-Proxy, Mumble-Serv., ddclient

    PI4B/4GB Bullseye-lite (64bit; modifiziert): SSH-Server, WireGuard-Server, ircd-hybrid-Server, stunnel-Proxy, Mumble-Server, botamusique, ample

Jetzt mitmachen!

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