Wirkleitstungscontroller

  • Guten Abend,

    vielen Dank an Dennis89 für diese ausführliche Antwort.


    Ich wusste ja, dass ich am Anfang stehe aber durch deine Erläuterungen habe ich erkannt wie katastrophal das eigentlich ist.


    Soweit ich konnte habe ich alles (was ich verstanden habe) in einem neuen Ansatz untergebracht.

    Da es völlig anders aufgebaut ist wie das vorhergehende habe ich einen neuen Namen für die Datei vergeben.


    Aktuell macht mir hier nur das "finally" in der Zeile 131 Probleme.

    Das bekomme ich irgendwie nicht hin.


    Ist das so richtig, dass ich in Zeile 130 diese drei Werte mit übergebe?


    Ich würde mich freuen, wenn hier nochmal wer drüber schauen könnte.

    Vielen Dank!


    Generell, und da ich noch nicht ausreichend Zeit zum Testen hatte gilt:

    Anwendung auf eigene Gefahr!

    Keine Garantie oder Gewährleistung!


    Gruß

    Homemade

    Edited once, last by Homemade ().

  • Hallo,



    'SELLWERT' wird im Laufe deines Programms verändert, von daher ist das keine Konstante.

    Zeile 30, der Code definiert keine Konstante, keine Funktion und keine Klasse, das bedeutet er gehört nicht auf Modulebene.

    Zeile 37 'parser' wird definiert aber nicht weiter verwendet.

    Zeile 46 'BaseException' soll so nicht verwendet werden. Grundsätzlich soll immer so genau wie Möglich auf Fehler reagiert werden, hier findest du mehr Informationen und häufig verwendete Ausnahmen. Wenn ich mir unsicher bin, nehme ich 'Exception'. Du solltest dir die Ausnahme auch ausgeben lassen, damit du weist, was los ist.

    Zeile 51 du definierst 'emparts' und in der nächsten Zeile definierst du 'emparts' wieder neu. Zeile 51 kann also weg.

    Zeile 69 STELLWERT ist aktuell noch eine Konstante, die muss nicht als Argument übergeben werden. Sprich die Funktion greift "direkt" darauf zu, da sie im "obersten" Namensraum steht (oder wie vorhin genannt: auf Modulebene)

    Zeile 72, 73 und 74 Variablen schreibt man ganz_klein. Zu dem sollten nur Zeichen aus der ASCII - Tabelle verwendet werden.

    Zeile 81 das kann man kompakter schreiben: if 10000 > ueberschuss > 1000:

    Zeile 82 das kann man auch kompakter schreiben STELLWERT += 10

    Das gilt für nachfolgende Zeilen auch.

    Zeile 118 benutze kein 'except' ohne Ausnahmebehandlung. Hier würde jetzt nur 'Fehler' erscheinen. Das ist zwar nett, aber wo fängst du mit der Fehlersuche an, wenn die einzigste Information 'Fehler' ist. Wieso ist ein 'sleep' in der Ausnahme? Das macht meiner Meinung nach nicht viel Sinn. Das würde ich eher in die Dauerschleife einbauen.

    Zeile 127 'parser' wird wieder definiert und wieder nicht weiter verwendet.

    Zeile 131 STELLWERT ist aktuell noch eine Konstante und muss nicht als Argument übergeben werden.

    Zeile 132 'finally' funktioniert nicht alleine. Dazu benötigst du ein try. Dann stimmen deine Einrückungen in Zeile 133 nicht.

    Die letzten zwei Funktionen werden gar nicht aufgerufen.


    Das fällt mir zu deinem Code ein. Funktionell und von der Logik habe ich nichts geändert. Ich habe auch keine Erfahrung mit 'socket' und kann dir dazu leider nichts sagen. Außer das man keine Abkürzungen benutzen soll wie 'sock', sondern aussagekräftige Namen. Ein paar Buchstaben mehr kosten nichts, auch wenn ich schon etwas von Tastaturabnutzung gelesen habe. :P



    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Guten Morgen,


    nochmals vielen Dank an Dennis89 für die Unterstützung.

    Solche Mitglieder bereichern ein Forum und braucht ein Forum um in der Spitzenklasse mitspielen zu können. Top :thumbup:


    Ich habe nun den Code wieder so gut wie möglich umgebaut und einen Tag lang erfolgreich getestet.



    Generell kann ich sagen:

    Das mit "Exeption as e" ist ja der Wahnsinn! Tolle Sache! Das kannte ich noch nicht. (leider in meinem Python Buch auch nicht zu finden)

    Gibt es hier die Möglichkeit diese Ausgabe noch genauer zu gestalten? (mit Angabe der Zeilennummer?)

    Da ich davon so begeistert bin habe ich nun alle "exeptions" so gelöst. Ich hoffe das ist nicht übertrieben?


    Die Schleife in Zeile 116 bei dem Code aus Beitrag #22 musste ich an dieser Stelle rausnehmen, da der Stellwert (Zeile 59) bei jedem Durchlauf mit 0 gestartet hat. Dafür wurde bei nachfolgendem Code diese Schleife in Zeile 61 realisiert. Kann man das so stehen lassen? (funktionieren tut es)


    Soweit wie möglich habe ich nun alles Überflüssige an Code entfernt. (Auch wenn ich nicht jede Zeile erklären kann, steht jetzt denke ich nur noch das wichtigste drinnen. Hoffe ich ^^ )


    Ich hätte da noch eine Frage zu den Fehlermeldungen von den GPIO die man ja nicht mit "GPIO.setwarnings(False)" blockieren sollte.

    Wie kann ich dann folgende Meldung deuten? Was müsste ich da dann anders machen?


    Wenn nun alle soweit einverstanden mit dem Code sind, dann werde ich im nächsten Beitrag dann alles nochmal zusammenfassen, damit es leichter zum Nachbasteln wird und man nicht den ganzen Verlauf in diesem Thema durchsuchen muss. Natürlich werde ich davor noch ausreichend testen.


    Generell, und da ich noch nicht ausreichend Zeit zum Testen hatte gilt:

    Anwendung auf eigene Gefahr!

    Keine Garantie oder Gewährleistung!


    Gruß

    Homemade

  • Hallo,


    danke für die netten Worte. Nur das du keinen falschen Eindruck bekommst, ich bin selbst gerade dabei Python zu lernen. Es gibt hier im Forum aber einige "richtige" Programmierer, die bei konkreteren Problemen sehr gut und ausführlich weiter helfen können. Eventuell gibt hier noch einer seinen Senf dazu.


    Gibt es hier die Möglichkeit diese Ausgabe noch genauer zu gestalten? (mit Angabe der Zeilennummer?)

    Du müsstest doch einen Traceback erhalten und der enthält die Zeilennummer und die Stelle an der der Interpreter den Fehler erkannt hat?


    Zu dem 'try'-Block ab Zeile 41: Der Inhalt des Blocks gibt ja "nur" definierten Inhalt von 'emparts' aus. Wäre es nicht sinnvoller den Teil in einen 'try'-Block zu setzen in dem 'emparts' definiert wird? Da könnten ja eher Probleme entstehen.


    Wie kann ich dann folgende Meldung deuten? Was müsste ich da dann anders machen?

    Die Fehlermeldung sollte nicht erscheinen, wenn vor dem Programmende 'GPIO.cleanup()' aufgerufen wird. Das geschieht mit dem 'finally' in deiner 'main'-Funktion. Wieso rufst du dort nach dem 'cleanup' wieder 'main' auf? Das gehört hier nicht rein.

    Ich weis nicht wie du dein Programm beendest, aber wenn es beendet wird, dann wird der 'finally'-Block ausgeführt, da hat ein Aufruf von 'main' nichts mehr zu suchen. Schau mal ob sich dadurch dein Problem löst.


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?

  • Guten Abend zusammen,


    hätte noch eine grundlegende Frage.

    Der Raspberry hat im Leerlauf rund 3-5% Auslastung, nach Start des oben dargestellten Codes sind es rund 8-10% Auslastung, nach einer Laufzeit von ca. 5 Stunden sind es 25-30% und spätestens nach 2 Tagen ist der Thonny automatisch geschlossen.

    Woher kommt das? Was muss ich ändern damit das nicht mehr passiert?


    Du müsstest doch einen Traceback erhalten und der enthält die Zeilennummer und die Stelle an der der Interpreter den Fehler erkannt hat?


    Hallo Dennis89,

    ich habe mal einen Schreibfehler eingebaut um einen Fehler zu erhalten.

    So sieht das dann bei mir aus: (name 'Überschuss' is not defined)

    Leider keine Zeilennummer, was ist da dann falsch eingestellt bei mir?


    Quote from Dennis89

    Die Fehlermeldung sollte nicht erscheinen, wenn vor dem Programmende 'GPIO.cleanup()' aufgerufen wird. Das geschieht mit dem 'finally' in deiner 'main'-Funktion. Wieso rufst du dort nach dem 'cleanup' wieder 'main' auf? Das gehört hier nicht rein.

    Bei mir erscheint diese Fehlermeldung nur 1x gleich nach dem Start des Programms.

    Das Programm soll 24/7 laufen, daher soll es bei einem Fehler nicht irgendwann aufhören, sondern am besten wieder von vorne anfangen.

    Was Besseres ist mir da nicht eingefallen ;)


    Danke schon mal im Voraus für die Antworten. :thumbup:


    Gruß

    Homemade

  • Hallo zusammen,


    ich konnte nun eine Stabile Version erzeugen. Leider nicht auf die „saubere“ art.

    Die Vorgänger Version hat nach einer gewissen Zeit den Raspberry sehr stark ausgelastet, dies war den regelmäßigen und vielen „print“ geschuldet.

    Aus diesem Grund habe ich diese nun auskommentiert, da ich hierfür keine bessere Lösung gefunden habe. (Lösungsvorschläge erwünscht!!!)

    Aktuell läuft diese Version schon rund 1 Woche bei mir Stabil, daher will ich euch diese nicht vorenthalten.



    Generell, und da ich noch nicht ausreichend Zeit zum Testen hatte gilt:

    Anwendung auf eigene Gefahr!

    Keine Garantie oder Gewährleistung!


    Gruß

    Homemade

    • Official Post

    dies war den regelmäßigen und vielen „print“ geschuldet.

    Und jetzt ist es besser? Nicht wirklich oder?


    Das Problem dürfte die ungebremste Schleife (Zeile 67) sein, die eine hohe CPU-Last verursacht, soweit ich das beim Überfliegen richtig deute.

  • Hallo,


    'ConfigParser' nutzt du gar nicht, aber du hast es importiert.

    Das ist nun doch schon etwas her, ich glaube das mit dem wählen von sinnvollen Namen hatten wir schon mal, in Zeile 35 das 'mreq' zum Beispiel.

    In Zeile 41 siehst du gleich ein Problem, das *-Importe mit sich bringt. Es ist nicht eindeutig nachvollziehbar wo 'decode_speedwire' herkommt. Man kann zwar erraten, dass das von 'speedwiredecoder' kommt. Aber mit mehreren Namen wird dass dann schnell unübersichtlich und kann auch zu Namenskollisionen führen. Besser nur dass importieren was gebraucht wird oder beim importieren des ganzen Moduls, dieses immer direkt ansprechen.

    Ich würde nicht das 'return' aus Zeile 56 in einen 'try'-Block setzen, denn wenn Fehler auftreten dann bei Zeile 41 und die gilt es dann abzufangen.

    Zeile 60 benutzt 'sys', das wird gar nicht importiert und sollte so deswegen auch nicht funktionieren.

    Namen schreib man in Python klein_mit_unterstrich Ausnahmen sind Konstanten die schreibt man GANZ_GROSS und Klassen in CamelCase-Schreibweise. Das wäre bei dir zum Beisiel Zeile 70. Wobei du die Zeile eh nicht brauchst, da du 'Bezug_gesamt' zwar definierst aber nicht weiter verwendest bzw. auskommentiert hast.

    Zeile 110, 'pass' nutzt man eigentlich nicht um ein 'else' abzuschließen, dann könntest du das 'else' eigentlich auch weglassen.

    Zeile 117 ist wieder wie weiter oben, 'sys' ist nicht importiert.

    Zeile 133 hat wieder eine Ausnahme ohne Ausnahmebehandlung.

    Das 'GPIO.cleanup()' gehört in den 'finally' Block. Das muss aufgerufen werden, bevor das Programm beendet wird.

    Die Dauerschleife die du durch das 'Except' und dem 'main'-Aufruf machst ist so nicht üblich. Die Schleife hast du ja schon in 'regeln'. Das 'pwm.stop()' würde ich auch in den 'finally'-Block packen.

    So ungetestet und die Namen kann man noch anpassen:


    Was die Auslastung angeht, habe ich die gleiche Meinung wie hyle


    Grüße

    Dennis

    ... ob's hinterm Horizont wirklich so weit runter geht oder ob die Welt vielleicht doch gar keine Scheibe ist?