immer doppelt

  • Hallo, vielleicht ist es völlig einfach und zu erklären ...

    Ich frage einen Zähler ab, den ich per IP erreichen kann. Dieser gibt einen String zurück mit den Werten. Im String suche ich dann nach meinem Wert und weise diesen einer Variable zu.

    Dieser Inhalt soll dann gespeichert werden. Aufgerufen wird das als Modul.

    Im Ergebnis erfolgt die Ausgabe aber immer doppelt, es wird doppelt gespeichert oder doppelt per print ausgegeben. Es läuft, warum auch immer, 2 mal durch. Das weiß ich, weil ich auch Momentanwerte abfrage. Die beiden Werte unterscheiden sich dann. (Ist noch die 2er Version, der Pi steuert schon Jahre meine Heizung).

    Woran liegt das?

    Beispiel Aufruf

    Code
    if zeit == '06:00' :
        try :
          zaehler.szaehler2()
          zaehler.szaehler3()
        except :
         print "schade"

    2 Mal editiert, zuletzt von ruediger (30. März 2023 um 11:38)

  • Hi,

    Python 2 wird nicht mehr gepflegt und solltest dann doch nach Python 3 schwenken.

    Deine Einrückungen im try-except sind nicht richtig und ein nacktes except benutzt man nicht. Da sollte schon stehen was die Ausnahme ist. Zumindest sollte da ein except Exception stehen, damit du auch mitbekommst das da was nicht funktioniert.

    Python
    try:
        #mach was
    except Exception as e:
        print (e)

    Wenn du dann weißt welche Fehler auftreten können, sollte man die auch angeben.

    https://docs.python.org/2.7/tutorial/errors.html

    Wenn es da ein def szaehler2 () : gibt, ist da sicher auch noch ein def szaehler1 ():. Vllt kann man beide Funktionen zusammenfassen?

    Dazu müsstest du aber das ganze Script zeigen. :)

    Dateien öffnet man am besten mit with, dann brauchst du dich nicht mehr um das schließen kümmern, da das with für dich macht.

    Python
    with open("/home/pi/solarertrag1.txt", "a") as file:
        file.write((jetzt + " " + "Arbeit Verbrauch " + forward_kwh + " kWh \n"))

    Wobei man Strings nicht mit + zusammenbaut. Da nutzt man am besten f-strings oder die format()-Methode. Das macht das ganze lesbarer. ABER f-strings gibts erst ab Python 3.6 oder so.

    Python
    file.write(f"{jetzt} Der momentane Verbrauch liegt bei: {forward_kwh} kWh \n")

    mit  format():

    Python
    file.write("{0} Der momentane Verbrauch liegt bei: {1} kWh \n".format("jetzt", "forward_kwh"))

    Wie gesagt, zeig einfach mal alles. Vllt gibt es jemanden der dir hilft dein Script auf Python 3 zu hiefen.

    Einmal editiert, zuletzt von keepfear (29. März 2023 um 19:59)

  • url2 = "http://192.168.2.234/get_table"

    ...suggeriert m.M.n. mehrere Spalten und ggf. Zeilen.

    Kannst Du bitte mal einen String der von werte2 = w2.read() kommt zeigen?

  • Ich glaube es brennt dem TE erst einmal auf den Naegeln das dopplete Lottchen zu eliminieren und dann danach mal das Script nach Python3 zu migrieren :shy:

    Moin,

    der Start Deines Scriptes erfolgt um 06:00 Uhr.

    Ich weiss nicht wie der Rest Deines Aufrufes aussieht, aber ist es vorstellbar, dass innerhalb von 60 (06:00:00 - 06:00:59 Uhr) Sekunden der Aufruf mehrfach durchgeführt wird?

    Das wird der Grund sein.


    Dennoch wäre eine Modernisierung und Vereinfachung angebracht.

    Das Programm am besten extern via Cronjob aufrufen. Hier ein Ansatz, wie man das vereinfachen könnte:

  • Moin,

    der Start Deines Scriptes erfolgt um 06:00 Uhr.

    Ich weiss nicht wie der Rest Deines Aufrufes aussieht, aber ist es vorstellbar, dass innerhalb von 60 (06:00:00 - 06:00:59 Uhr) Sekunden der Aufruf mehrfach durchgeführt wird?

    Der Aufruf war ein Beispiel, auch wenn man es einmal aufruft zum Test passiert es. Den Effekt mit mehrfachen Aufrufen kenne ich.

  • Du hast schon Recht, alte Version. Das steuert meine Heizung und da läuft das schon ein paar Jahre. Es gibt auch ein Tool, was das Skript automatisch auf 3 umbaut. Dann muss ich aber auch die Version auf dem Pi anpassen, vorher noch mal die Karte sichern...

    Es betrifft bei mir vorrangig auch nur Print, was ich aber auch nur benötige, wenn ich mal was ändern möchte. Da hängt kein Monitor dran. Also bisher keinen Druck verspürt.

    Die anderen Tipps schaue ich mir noch mal genauer an. Try soll nur Abstürze verhindern, da das ja Monate nebenbei läuft. Bei Neustart, schreibt er das Ereignis mit except auch in eine Datei. Sonst fange ich damit ab, dass das Internet fehlt für Temperaturkurve hochladen, ein Fühler nicht erreichbar ist, oder das Display spinnt. Das fängt sich dann später wieder oder verwendet Festwerte. Das läuft wirklich in der Praxis Jahre ohne Probleme.

    Der Effekt mit dem doppelten Ausgaben, wundert mich einfach nur. Passiert eben auch, wenn man das Modul per "Hand" aufruft. Ja auch bei Zähler 1 oder 3. Die Unterschiede sind nur die Adressen und Strings, die ich suche.

    Danke für die Beispiele.

  • Moinsen,

    warum nimmst du dir nicht einen Aktiv- Zeiger ?

    Python
    if TIME and not GESCHRIEBEN:
        # Abfrage
        try:
            # Schreibecode
            GESCHRIEBEN = True
        except :
            GESCHRIEBEN = False
    else:
        GESCHRIEBEN = False

    Damit hast du dein Zeitfenster von einer Minute ( oder was du auch immer in der TIME als Zeitraum festlegst ) und wenn du außerhalb der Zeit bist, wird der Merker wieder auf False gesetzt so das beim nächsten Durchlauf wieder das recht besteht einen neuen Schreibvorgang auszuführen.
    Wenn jedoch der Schreibvorgang erfolgreich ausgeführt wurde, wird dieser Zeiger auf True gesetzt und damit für dieser aktuellen Zeitraum gespeert.

    Franky

  • Franky07 Das funktioniert nicht. Diese Variable existiert ja nur solange das Programm läuft und weiss nichts vom vorherigen Programmaufruf.

    Zudem heissen Flags immer noch nicht ”Zeiger”. Zeiger sind, und waren es auch in DDR-Fachliteratur, etwas anderes. ?

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Hallo,

    zu #8 Konstanten schreibt man in Python groß, du hast aber keine Konstanten, denn du änderst ja den Wert, sogar in deinem kurzen Beispiel. Wenn du mit 'try/except'-Code arbeitest, dann schreib kein 'except' ohne Ausnahmebehandlung. Der nächste schreibt das ab, findet die Fehler nicht, weil die alle verschluckt werden und ärgert sich dumm und dämlich.

    Wenn man immer wieder was zu einem Zeitpunkt ausführen will, dann gibts auch schedule, falls dass Programm durchgehend laufen soll.

    Man könnte natürlich auch die Datei erst mal lesen und anhand des letzten Eintrags entscheiden, ob geschrieben werden soll oder nicht.

    Grüße

    Dennis

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

  • Diese Variable existiert ...

    Variablen ist aber auch irreführend, wenn man über Python spricht.

    Ich weiß zwar nicht, wie das Fachwort dafür heißt, aber die Referenzen der Objekte zeigen auf Namen. Das sind keine Variablen.

  • @DeaD_EyE Doch in diesem Fall schon Variable. Eine Variable aus Sicht von Compilern und manchmal auch Laufzeitumgebungen setzt sich aus Dingen wie Name, Wert, Speicherort, und Datentyp zusammen und all das existiert ja nur solange das Programm läuft. Die Verwirrung die bei Python manchmal entsteht ist das der Speicherort und Datentyp zum Wert gehören, im Gegensatz zu beispielsweise C wo der Speicherort und Datentyp zum Namen gehören.

    “Dawn, n.: The time when men of reason go to bed.” — Ambrose Bierce, “The Devil's Dictionary”

  • Moinsen

    Diese Variable existiert ja nur solange das Programm läuft und weiss nichts vom vorherigen Programmaufruf.

    Was spricht überhaupt dagegen, und damit würde das Programm wieder funktionieren, wenn dieser Teil solange durchlaufen wird, und erst unter der Betrachtung des abgeschlossenen Schreibvorgangs verlassen wird ? Das heißt, der Aufruf kommt weil das Zeitfenster erreicht ist, als der Aufruf von Extern erfolgt, das diese Schleife mit allen Abfrage Routinen startet, und erst mit dem festgestellten gültigen abgeschlossenen Schreibvorgang beendet wird. Damit kann sich dieser Teil im Kreis drehen, pollen bis ein Datensatz eingelesen und auch gespeichert wurde.
    Also muss man noch mehr Gedönst machen als unbedingt notwendig. Denn so wie ich das verstanden habe erfolgt dieser Zwischenspeichervorgang nur in immer zu einer bestimmten Tageszeit, die nicht an ein Minutenfenster gebunden ist, sondern rein in der Wiederholung der Stunde - des Tages liegt.
    Warum soll dann der Script von extern wiederkehrend und wiederholt gestartet werden. Hier reicht ein einmaliger Startaufruf von Extern, um diesen einen Prozess anzuschieben. Die reine Verwirklichung liegt dann in der Hand des aufgerufenen zweiten Scripts. Dabei ist es egal, ob dieser Auslösevorgang durch einen Cron, oder durch einen anderen Python Script erfolgt, wenn der zweite ausführende Script nur einmal zur Eventzeit aufgerufen wird, und die Funktion auch sicherstellt, bzw in der Ergänzung mit einem Timeout, dann auch eine Fehlermeldung im abgelegten Protokoll hinterläßt.
    Es gibt viele Wege die nach Rom führen, also sollte und kann man auch den Weg wählen, der nur den Protokoll-Event anschiebt, und diese Protokollierung als abgeschlossenen Prozess betrachtet.
    Damit, sorry muss ich dir sagen, ohne die Rahmenbedingungen und den gesamten Ablauf nicht näher zu beleuchten ist deine Aussage falsch.

    Franky

  • Moinsen,

    warum nimmst du dir nicht einen Aktiv- Zeiger ?

    Python
    if TIME and not GESCHRIEBEN:
        # Abfrage
        try:
            # Schreibecode
            GESCHRIEBEN = True
        except :
            GESCHRIEBEN = False
    else:
        GESCHRIEBEN = False

    Damit hast du dein Zeitfenster von einer Minute ( oder was du auch immer in der TIME als Zeitraum festlegst ) und wenn du außerhalb der Zeit bist, wird der Merker wieder auf False gesetzt so das beim nächsten Durchlauf wieder das recht besteht einen neuen Schreibvorgang auszuführen.
    Wenn jedoch der Schreibvorgang erfolgreich ausgeführt wurde, wird dieser Zeiger auf True gesetzt und damit für dieser aktuellen Zeitraum gespeert.

    Das ist so nicht ganz richtig, glaube ich. Wenn dieser Programmteil innerhalb der maßgeblichen Minute dreimal aufgerufen wird, passiert folgendes:

    - Der Wert wird abgefragt und geschrieben und GESCHRIEBEN wird auf True gesetzt.
    - Im zweiten Durchlauf ist TIME True und GESCHRIEBEN ist False - die UND-Bedingung ist nicht erfüllt, somit wird der else-Zweig ausgeführt und GESCHRIEBEN wird auf False gesetzt.

    - Im dritten Durchlauf ist wieder TIME = True und GESCHRIEBEN = False, die Bedingung ist erfüllt und es wird wieder der Wert abgefragt und geschrieben.

    Das setzt sich so fort - jeder ungerade Schleifendurchlauf führt dazu, dass der Wert abgefragt und geschrieben wird. Es kommt also dann nur darauf an, wie lange die Antwort für die Abfrage braucht und ob man innerhalb dieser Minute 3, 5 7 oder noch mehr Abfragen schafft und entsprechend oft in die Logdatei schreibt.

    Statt dem else wär hier eher ein "if not TIME and GESCHRIEBEN:" sinnvoll.

    Und selbstverständlich müssen die Werte von TIME und GESCHRIEBEN erhatlen bleiben. Wiederholte Programmaufrufe würden hier also gar nicht funktionieren. Bei Funktionsaufrufen müsste man die Varablen static definieren oder ggf. auch globale Variablen nutzen.

    Trotzdem ist mir nach wie vor unverständlich, warum das zweimal passieren soll, sofern nicht diese Minuten-Zeitproblematik dafür verantwortlich ist. Da der gesamte Code keine Schleife enthält und nur den einen Schreibbefehl, kann das wohl kaum sein. Vielleicht sollten wir doch mal den gesamten Code sehen. Hier kann was nicht stimmen.

    Oh, man kann hier unliebsame Nutzer blockieren. Wie praktisch!

Jetzt mitmachen!

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