Ankündigung

Einklappen
Keine Ankündigung bisher.

In der Tiefe: Validierungskonzept

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Zitat von enertegus Beitrag anzeigen
    Meine Vermutung: Zunächst wird initialisiert und change triggert nicht. Beim Überlauf (intern ist das sicher 32 Bit) wird ggf. versehentlich change getriggert. Ich hoffe mal nix großes - wir wollen ja bald nun eine neue Version freigeben.
    Klar. Dann hast du natürlich eine Menge Arbeit!

    Evtl. hast du dir ja mein Posting #194 noch nicht angeschaut. Hier einfach noch einmal die dortige Version, die das Problem auch zeigt und keinen Überlauf haben kann, oder? Ich vermute also eher, dass die Addition von Rollo_Sonnenuntergang_verzoegerung triggert ...

    [highlight=epc]
    // Sonnenuntergang
    Rollo_Sonnenuntergang_verzoegerung = 59u08

    Rollo_Sonnenuntergang_h = sunsethour()
    Rollo_Sonnenuntergang_m = sunsetminute() + Rollo_Sonnenuntergang_verzoegerung

    if change( Rollo_Sonnenuntergang_m ) then {
    if ( Rollo_Sonnenuntergang_m > 59u08 ) then {
    Rollo_Sonnenuntergang_m = Rollo_Sonnenuntergang_m - 60u08;
    Rollo_Sonnenuntergang_h = sunsethour() + 1u08;
    } endif
    } endif
    [/highlight]
    BR
    Marc

    Kommentar


      Zitat von saft6luck Beitrag anzeigen
      Klar. Dann hast du natürlich eine Menge Arbeit!
      Wir entwicklen ja fleissig an weiteren Produkten,..

      dass die Addition von Rollo_Sonnenuntergang_verzoegerung triggert ...
      Ich hab das nochmals getestet:
      Rollo_Sonnenuntergang_verzoegerung = 59u08
      => change wird (fälschlicherweise) getriggert
      Rollo_Sonnenuntergang_verzoegerung = 9u08
      => change wird erwartungsgemäß nicht getriggert
      (sunsetminute() steht auf 50)
      offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
      Enertex Produkte kaufen

      Kommentar


        Zitat von enertegus Beitrag anzeigen
        Ich hab das nochmals getestet:
        Rollo_Sonnenuntergang_verzoegerung = 59u08
        => change wird (fälschlicherweise) getriggert
        Rollo_Sonnenuntergang_verzoegerung = 9u08
        => change wird erwartungsgemäß nicht getriggert
        (sunsetminute() steht auf 50)
        Aber welchen Überlauf meinst du hier? Die innere Abfrage triggert fälschlicherweise?
        BR
        Marc

        Kommentar


          Zitat von saft6luck Beitrag anzeigen
          Aber welchen Überlauf meinst du hier? Die innere Abfrage triggert fälschlicherweise?
          Sorry, ich bin da wohl etwas undeutlich und selbst nicht ganz geordnet: Irgendwie triggert die innere Abfrage (>59) das change() beim Initialsieren.
          offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
          Enertex Produkte kaufen

          Kommentar


            Zitat von saft6luck Beitrag anzeigen
            Immerhin weiß ich jetzt auch, dass Änderungen von Variablen im nächsten Zyklus erscheinen.
            Das bedeutet, dass folgender Code so funktionieren würde:
            (trigger geht immer nur für einen Verarbeitungszyklus auf 1, z.B. bei Druck auf einen Webbutton)

            Code:
            a = 1b01
            trigger = 0b01
            
            if trigger then {
                 if a==1 then a=0; "mache noch irgendwas" endif;
                 if a==0 then a=1; "mache noch irgendwas anderes" endif
            } endif
            Wird trigger jetzt 1, dann wird das erste innere if aufgerufen und a=0 gesetzt, aber NICHT mehr das zweite innere if, da das Nullsetzen von a erst im folgenden Verarbeitungszyklus "aktiv" wird.

            Für den "Nicht-EibPC"-Programmierer ist das natürlich so nicht zu erahnen. Oder hab ich da etwas im Handbuch (ok, ich hab noch v15) überlesen? Sollte ansonsten vielleicht klar beschrieben werden.
            Gruss Pio

            Kommentar


              Zitat von pio Beitrag anzeigen
              Das bedeutet, dass folgender Code so funktionieren würde:
              (trigger geht immer nur für einen Verarbeitungszyklus auf 1, z.B. bei Druck auf einen Webbutton)

              [highlight=epc]
              a = 1b01
              trigger = 0b01

              if trigger then {
              if a==1 then a=0; "mache noch irgendwas" endif;
              if a==0 then a=1; "mache noch irgendwas anderes" endif
              } endif
              [/highlight]Wird trigger jetzt 1, dann wird das erste innere if aufgerufen und a=0 gesetzt, aber NICHT mehr das zweite innere if, da das Nullsetzen von a erst im folgenden Verarbeitungszyklus "aktiv" wird.
              Michael möge mir verzeihen, aber ich versuche mich mal in der Antwort:
              1. mit der Änderung von trigger hast du recht, der Wert ändert sich aber in deinem Beispiel nicht mehr -> man wird so nicht erkennen, ob es im nächsten Zyklus einen change() gibt.

              2. Die Zuweisung von a=0 wird sofort gültig, d.h. die nächste Abfrage wird auch wahr und somit wird a wieder 1. (Unverständlich finde ich, dass alle eingefügten writes(GA, a) nur den Endwert von a ausgeben würden, unabhängig von der Position im Code, aber das ist schon wieder ein anderes Thema).

              Das Verhalten (ich empfinde es als Problem) zeigt sich bei folgendem Konstrukt:

              [highlight=epc]
              a=sunriseminute()
              /* 5 Minuten addieren und Überlauf beachten */
              if change(a) then {
              if a>54 then a=a-55 else a=a+5 endif
              } endif
              [/highlight]

              Hier würde ich normalerweise erwarten, dass a um 5 erhöht wird und der Wert auf 59 begrenzt wird. Leider wird der change() aber im nächsten Zyklus erneut auftreten und somit a ständig hochzählen. (Abgesehen davon, dass das else noch im gleichen Zyklus ausgeführt wird ...).

              Oder anderes Beispiel:
              [highlight=epc]
              a = "Taster-GA"
              if change( a ) then {
              a = !a;
              write (a);
              } endif
              [/highlight]

              Hier wird a endlos toggeln.

              Beispiele sind leider ungetestet, da mein eibPC momentan loggen soll.
              BR
              Marc

              Kommentar


                Zitat von saft6luck Beitrag anzeigen
                1. mit der Änderung von trigger hast du recht, der Wert ändert sich aber in deinem Beispiel nicht mehr
                Ich hatte geschrieben, dass "trigger" durch einen pbutton gesetzt, und somit auch automatisch wieder rückgesetzt würde. Die dazu notwendige Logik zeigt mein Beispiel nicht. Ich will auch nicht auf change(trigger) was machen, sondern nur wenn trigger==1. Aber das nur zur Erläuterung ....

                2. Die Zuweisung von a=0 wird sofort gültig, d.h. die nächste Abfrage wird auch wahr und somit wird a wieder 1.
                So hatte ich das auch mal verstanden. Mich hatte jetzt nur dein Statement aus deinem Post 223 irritiert.

                (Unverständlich finde ich, dass alle eingefügten writes(GA, a) nur den Endwert von a ausgeben würden, unabhängig von der Position im Code, aber das ist schon wieder ein anderes Thema).
                Das würde der reinen SPS-Lehre entsprechen (Eingangsabbild aktualisieren --> komplett verarbeiten --> Ausgangsabbild auf die Ausgänge schreiben). Damit vermeidet man z.B., dass erst das Licht ein und dann gleich wieder ausgeschaltet wird (auf ein Beispiel des Eib übertragen und unter Vernachlässigung der Tatsache, dass die Zykluszeit des EibPC wesentlich schneller ist als die Zeit, 2 Telegramme direkt hintereinander auf den Bus zu schreiben).
                Andererseits kann ich mir auch Situationen vorstellen, in denen ich das Verhalten explizit möchte: ich mache eine Berechnung, als Ergebnis sende ich dann einen Trigger auf den Bus, der irgendwo überwacht wird. Wenn der Trigger länger ansteht als z.B. 500ms, dann löst das überwachende Device ne Aktion aus.
                Wenn ich jetzt im selben Zyklus des EibPCs noch ein invertierendes Telegramm in die Warteschleife setzten kann, noch bevor ich im selben Verarbeitungszyklus schon 10 weitere Telegramme in der Schlange platziert habe, und die Gesamtsendedauer aller 11 Folge-Telegramme die 500ms überschreitet, dann wird mein Eib-Device doch nichts machen.

                Oder landen die Telegramme etwa in zufälliger Reihenfolge im Sendepuffer?
                Gruss Pio

                Kommentar


                  Zitat von pio Beitrag anzeigen
                  Ich hatte geschrieben, dass "trigger" durch einen pbutton gesetzt, und somit auch automatisch wieder rückgesetzt würde. Die dazu notwendige Logik zeigt mein Beispiel nicht. Ich will auch nicht auf change(trigger) was machen, sondern nur wenn trigger==1. Aber das nur zur Erläuterung ....
                  [+]
                  So hatte ich das auch mal verstanden. Mich hatte jetzt nur dein Statement aus deinem Post 223 irritiert.
                  Darher bin ich auf trigger eingegangen, da meine Aussage (und die kommt ja von Michael) sich nur auf change() bezieht (was natürlich in dem if irgendwie enhalten ist), aber eben keine Auswirkung hat, wenn da unterschiedliche Variablen im Spiel sind.

                  Das würde der reinen SPS-Lehre entsprechen (Eingangsabbild aktualisieren --> komplett verarbeiten --> Ausgangsabbild auf die Ausgänge schreiben).
                  Das hatte ich ja auch schon festgestellt, nur sind da ein paar Leute explodiert. Es wagt jemand die Verarbeitung des eibPCs mit der einer SPS zu vergleichen, ts, ts, Steine, schöne frische Steine ...
                  BR
                  Marc

                  Kommentar


                    Irgendwo im Handbuch steht (oder stand zumindest in älteren Versionen), das man verschachtelte Strukturen vermeiden solle, weil sie überwiegend eben nicht zu dem Ergebnis führen, das ein "normaler" Programmierer entsprechend seinen Erfahrungen mit üblichen Sprachen erwarten wird. Hält man sich daran, ist es nicht mehr wichtig, ob eine Veränderung des Wertes einer Variable noch im selben oder erst im nächsten Zyklus im restlichen Code sichtbar wird.
                    Und ganz offensichtlich sind Statements wie
                    a=a+1
                    ausgesprochen problematisch, da sie je nach Situation/Abhängigkeit nur ein einziges Mal oder aber "endlos" in jedem Zyklus ausgeführt werden.
                    Entzerren läßt sich das, indem man für jeden Schritt eine neue Variable verwendet, wodurch der Output eben nicht den Input verändert und diesen so ständig wieder invalidiert. Das ist zunächst ungewohnt, aber der EPC folgt nun mal nicht den Regeln gewohnter Sprachen, also sind auch andere Lösungen angesagt.

                    Die Frage, was denn tatsächlich gesendet wird, wenn innerhalb eines Zyklus mehrfach und mit verschiedenen Werten auf eine GA geschrieben wird dürfte nur in absoluten Ausnahmefällen interessant sein, denn normalerweise sollten zwischen zwei "Zugriffen" auf die selbe GA mehr als nur ein Zyklus liegen - allein schon deshalb, weil der EPC während der Übertragung eines einzigen Telegramms normalerweise mehrere Zyklen schafft und mehrfaches Schreiben in einem Zyklus ziemlich schnell den Bus überfordert.

                    Im konkreten Fall würde ich den Zeitversatz rein mathematisch ohne if abhandeln - Uhrzeit erst in Minuten umrechnen, Versatz hinzurechnen, das Ergebnis wieder in Stunden und Minuten zerlegen. Wann welche Operation ausgeführt wird, entscheidet dann das Validierungsschema und solange dabei kein Ergebnis Werte beeinflußt, von denen es direkt oder indirekt abhängt, ist auch egal, ob die einzelnen Statements im selben oder in aufeinanderfolgenden Zyklen abgearbeitet werden.

                    So wie ich das bislang verstanden habe, gibt es ja nicht einmal eine Garantie dafür, das die Statements während eines Durchlaufs auch in der Reihenfolge bearbeitet werden, in der sie im Code stehen.
                    So wie ich das verstanden habe, muß man davon ausgehen, das alle Statements quasi parallel ausgeführt werden, so das die dabei in einem bestimmten Statement erfolgenden Änderungen erst im nächsten Zyklus für alle anderen Statements sichtbar werden. Wobei man sich darauf aber wiederum auch nicht verlassen sollte...

                    Mein ganz persönliches Problem ist, das ich trotzt aller bislang gelesenen Erklärungen in vielen Fällen immer noch nicht sicher vorhersagen kann, was ein gegebener Code tatsächlich tun wird, da ich nicht weiß, was der Compiler tatsächlich daraus macht und was da zur Laufzeit dann passiert.

                    Für die meisten Funktionen ist recht genau erklärt, was sie tun. Aber wann sie es tun, dafür wir immer auf das Validierungsschema verwiesen und genau dieses hat sich mir immer noch nicht lückenlos erschlossen.
                    Ich glaube vorhersagen zu können, was ein Statement machen wird, wenn es abgearbeitet wird, aber ich kann einfach immer noch nicht sicher sagen, wann ein Statement abgearbeitet wird, und wann nicht. Geht mir das jetzt allein so oder habe ich da noch Leidensgenossen?
                    Tessi

                    Kommentar


                      @Tessi:
                      Ich habe noch keinen Hinweis im Handbuch gefunden, dass die Reihenfolge im Code nicht der Ausführungsreihenfolge entspricht. Die angesprochene parallele Ausführung enthält auch hierzu keinen Anhaltspunkt (trägt eher zur Verwirrung bei). Wenn tatsächlich umsortiert wird, muss das entsprechend beschrieben werden oder soll die von Michael gerne zitierte Blondine sich da einen Reim drauf machen müssen???

                      Verschachtelungen sind beim eibPC leider notwendig, den nur auf der obersten Ebene gilt der vereinfachte Syntax (das Validierungsschema = Event-getrieben). Die nächsten Ebenen sind eigentlich normale Logik, auch wenn das im Handbuch stark verkompliziert ist. (Wo findest du denn den Hinweis, dass man Verschachtelungen vermeiden soll? Ich hab da nur else in Erinnerung?).

                      Ansonsten gebe ich dir Recht, ob ein Kommando ausgeführt wird, oder nicht definiert sich laufend neu
                      BR
                      Marc

                      Kommentar


                        Zitat von pio Beitrag anzeigen
                        Oder hab ich da etwas im Handbuch (ok, ich hab noch v15) überlesen? Sollte ansonsten vielleicht klar beschrieben werden.
                        Das steht im Handbuch 16 der Betaversion oder hier
                        https://knx-user-forum.de/attachment...skonzept-5.pdf
                        offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                        Enertex Produkte kaufen

                        Kommentar


                          Zitat von Tessi Beitrag anzeigen
                          Mein ganz persönliches Problem ist, das ich trotzt aller bislang gelesenen Erklärungen in vielen Fällen immer noch nicht sicher vorhersagen kann, was ein gegebener Code tatsächlich tun wird, da ich nicht weiß, was der Compiler tatsächlich daraus macht und was da zur Laufzeit dann passiert.

                          Für die meisten Funktionen ist recht genau erklärt, was sie tun. Aber wann sie es tun, dafür wir immer auf das Validierungsschema verwiesen und genau dieses hat sich mir immer noch nicht lückenlos erschlossen.
                          Ich glaube vorhersagen zu können, was ein Statement machen wird, wenn es abgearbeitet wird, aber ich kann einfach immer noch nicht sicher sagen, wann ein Statement abgearbeitet wird, und wann nicht. Geht mir das jetzt allein so oder habe ich da noch Leidensgenossen?
                          Ich helfe gerne, wenn es konkreter wird. saft6luck und pio mit dem SPS Konzept (Zustandsautomat) haben da recht (aber jeder nur ein Stein, und nicht bevor ich es sage).
                          Also frage, damit ich antworten kann.
                          offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                          Enertex Produkte kaufen

                          Kommentar


                            1. Könnte man nicht ein write_direct() Kommando einführen, dass den aktuellen Wert von Variablen in den Puffer schreibt?

                            Wie sieht das eigentlich mit Variablen aus?
                            z.B.
                            [highlight=epc]
                            a=1u08
                            b=a
                            if systemstart() then write(GA,a); write(GA,b) endif
                            a=a+1
                            c=a
                            if systemstart() then write(GA,c) endif
                            a=a+1
                            d=a
                            if systemstart() then write(GA,d) endif
                            [/highlight]
                            So wie ich das verstehe, wird bei allen writes doch der gleiche Wert ausgegeben, oder? Wie sieht es mit b,c,d aus? Sind die nach dem Zyklus auch alle gleich?

                            2. Kann die Darstellung von else nicht doch geändert werden? Es gibt wohl nur sehr wenige Leute, die bei einem else die sofortige Ausführung des alternativen Codes erwarten, oder? Und wenn man das brauch, kann man ja die Variante mit dem ! einbauen, oder?
                            Bei mir führt die eigenwillige Ausführung jedenfalls regelmäßig zu extrem umständlichen Konstrukten.
                            BR
                            Marc

                            Kommentar


                              So wie ich das verstehe, wird bei allen writes doch der gleiche Wert ausgegeben, oder?
                              So wie ich das sehe, wird's wahrscheinlich einen Compilerfehler geben wegen dem mehrfachen a=a+1.

                              Das einzige, wie Du das umgehen kannst, ist für jeden kritischen write eine eigene Variable anzulegen und den zu schreibenden Wert vorher dieser Variable zuzuweisen.
                              Im Falle eines Makros mußt Du dann eben mit einer lokalen variable arbeiten um sicherzustellen, das jeweils pro write eine andere Variable zuständig ist.

                              Gruß,
                              Bernd

                              Kommentar


                                Zitat von bmx Beitrag anzeigen
                                So wie ich das sehe, wird's wahrscheinlich einen Compilerfehler geben wegen dem mehrfachen a=a+1.
                                Hm, das wird wohl komplizierter, aber man darf sich das als beliebige Änderung von a vorstellen.

                                Das einzige, wie Du das umgehen kannst, ist für jeden kritischen write eine eigene Variable anzulegen und den zu schreibenden Wert vorher dieser Variable zuzuweisen.
                                Das ist der Grund für die Frage. So geht es eben leider nicht.

                                Im Falle eines Makros mußt Du dann eben mit einer lokalen variable arbeiten um sicherzustellen, das jeweils pro write eine andere Variable zuständig ist.
                                Folgendes geht jedenfalls nicht:
                                [highlight=epc]
                                //Inline-Makros
                                :begin write_direct(GA, Value, Name)
                                Name^temp = Value
                                :return Name^temp = Value; write(GA, convert( Name^temp, Value))
                                :end
                                [/highlight]
                                BR
                                Marc

                                Kommentar

                                Lädt...
                                X