Ankündigung

Einklappen
Keine Ankündigung bisher.

Validierungsschema / change() Funktion Verständnisfrage

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

    Validierungsschema / change() Funktion Verständnisfrage

    Ich denke ich habe verstanden, dass durch Ereignisse ausgelöste Änderungen zur Invaliderungen von Variablen und deren abhängigen Variablen führen. Dies führt dann in der nächsten Ereignisschleife zur Ausführung des betreffenden Codes.
    Mein Frage ist, gilt das auch für Funktionsaufrufe, bei denen sich ein Parameter ändert?
    Hintergrund. Ich bin über das Beispiel auf Seite 250 des (V3) Handbuchs gestolpert:

    [highlight=epc] [EibPC]
    inputstring=webinput(1)
    if change(inputstring) then weboutput(2,inputstring) endif
    [/highlight]
    Würde ohne die change() Funktion der weboutput() Aufruf erfolgen, wenn sich inputstring ändert oder nicht, denn der 2. Parameter ich ja identisch mit dem Argument der change() Funktion.

    Ciao, Peter

    #2
    Es funktioniert.
    Man sollte aber beachten, das change() , soweit ich das beobachten konnte, immer dann den Wert 1b01 zurück gibt, wenn die beobachtet Variable neu geschrieben wurde, auch wenn diese sich garnicht geändert hat!

    Korrektur:
    Habe diese vermeindliche Eigenschaft von change() mit Version 3.004 nicht mehr reproduzieren können.
    Bitte meinen Einwand ignorieren!

    alexander

    Kommentar


      #3
      Zitat von asc570 Beitrag anzeigen
      Es funktioniert.
      Hm, hatte die Frage falsch verstanden ...

      Man sollte aber beachten, das change() , soweit ich das beobachten konnte, immer dann den Wert 1b01 zurück gibt, wenn die beobachtet Variable neu geschrieben wurde, auch wenn diese sich garnicht geändert hat!
      Bei einem derart empfindlichen Gerüst wie dem "Validierungsschema" des eibPCs ist es nicht hilfreich, Vermutungen, die auch noch falsch sind, als "man sollte aber beachten" zu postulieren!!!

      Oder du belegst deine Vermutungen. Dann würde mich aber interessieren, wie dies zu folgendem Beispiel von Michael passt : klick, welches zwar nicht die Antwort auf die dort gestellte Frage war, dein Beispiel aber wohl recht gut trifft.
      BR
      Marc

      Kommentar


        #4
        Zitat von saft6luck Beitrag anzeigen
        Bei einem derart empfindlichen Gerüst wie dem "Validierungsschema" des eibPCs ist es nicht hilfreich, Vermutungen, die auch noch falsch sind, als "man sollte aber beachten" zu postulieren!!!
        Stimmt!
        Hab das Verhalten mit Version 3.004 auch nicht mehr reproduzeiren können.
        Werde versuchen mich zu bessern...

        Alexander

        Kommentar


          #5
          Zitat von asc570 Beitrag anzeigen
          Stimmt!
          Hab das Verhalten mit Version 3.004 auch nicht mehr reproduzeiren können.
          Werde versuchen mich zu bessern...
          Wobei webinput in der V2 noch gar nicht existierte.
          Das Verhalten von change wurde zudem auch nicht verändert.
          offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
          Enertex Produkte kaufen

          Kommentar


            #6
            Um mal zur Frage zurück zu kommen:
            Zitat von kermit42 Beitrag anzeigen
            Ich denke ich habe verstanden, dass durch Ereignisse ausgelöste Änderungen zur Invaliderungen von Variablen und deren abhängigen Variablen führen.
            Das ist so richtig, aber mit einer Einschränkung:
            Wenn eine abhängige Variable trotz der Änderungen von Variablen, von denen sie abhängt, ihren Wert nicht ändert, so wird sie nicht invalid. Dadurch wird verhindert, das wiederum von ihr abhängige Variablen neu berechnet werden, obwohl klar ist, das sich nichts ändern kann.

            Zitat von kermit42 Beitrag anzeigen
            Dies führt dann in der nächsten Ereignisschleife zur Ausführung des betreffenden Codes.
            Ja, sofern mit betreffender Code nur diejenigen Ausdrücke gemeint sind, deren Resultate entweder anderen Variablen zugewiesen werden oder (Teil einer) Bedingung einer If-then(-else)-Struktur sind.

            Zitat von kermit42 Beitrag anzeigen
            Mein Frage ist, gilt das auch für Funktionsaufrufe, bei denen sich ein Parameter ändert?
            Nein, die Parameteränderung allein genügt nicht. Ausdrücke, deren Parameter sich geändert haben, werden nur dann ausgewertet, wenn ihr Ergebnis einer Variablen zugewiesen wird oder sie (Teil einer) Bedingung (für if) sind.

            Zitat von kermit42 Beitrag anzeigen
            Hintergrund. Ich bin über das Beispiel auf Seite 250 des (V3) Handbuchs gestolpert:

            [highlight=epc] [EibPC]
            inputstring=webinput(1)
            if change(inputstring) then weboutput(2,inputstring) endif
            [/highlight]
            Würde ohne die change() Funktion der weboutput() Aufruf erfolgen, wenn sich inputstring ändert oder nicht, denn der 2. Parameter ich ja identisch mit dem Argument der change() Funktion.
            Hier haben wir den Fall, das die Funktion weder Teil einer Bedingung ist, noch in einer Variablenzuweisung verwendet wird. Daher wird weboutput() auch nicht automatisch durch Parameteränderungen getriggert.

            Das es so
            [highlight=epc] [EibPC]
            weboutput(2,inputstring)
            [/highlight]
            nicht geht und das Kommando nie ausgeführt wird, sondern ich explizit so triggern muss
            [highlight=epc] [EibPC]
            if change(inputstring) then weboutput(2,inputstring) endif
            [/highlight]
            soll die Programmierung angeblich sicherer machen. Verstehen tue ich das nicht, denn weil ich weiß, das die erste Version nicht geht verwende ich halt immer die zweite (und wenn ich schreibfaul bin, verpacke ich das auch noch in ein Makro das es mir erlaubt, die Sache wieder so zu schreiben wie in Version 1). Das ich ein Kommando an ungünstigen Stellen im Code und/oder mit ungünstige Argumenten/Parametern verwende, das verhindert die Variante 2 genau so wenig, wie die Variante 1.

            Das Validierungsschema gilt überdies nur auf der "obersten" Ebene. Alles, was in einem then- oder else-Zweig enthalten ist, wird statisch (also ohne Berücksichtigung irgendwelcher Parameteränderungen) immer dann ausgeführt, wenn der then- oder else-Zweig ausgeführt wird.

            Das Validierungsschema ist auch "Schuld" daran, das auf der obersten Ebene die Reihenfolge der Auswertung nicht unbedingt der Reihenfolge der Statements im Code entspricht.

            So, jetzt hoffe ich, das ganze war einerseits verständlich und andererseits auch richtig.
            An sich ist das Validierungsschema gar nicht so kompliziert, es ist nur irgenwie nicht so einfach, es verständlich zu beschreiben. Und es ist für "normale" Programmierer ziemlich ungewohnt...
            Tessi

            Kommentar


              #7
              Zitat von Tessi Beitrag anzeigen
              ...
              An sich ist das Validierungsschema gar nicht so kompliziert, es ist nur irgenwie nicht so einfach, es verständlich zu beschreiben. Und es ist für "normale" Programmierer ziemlich ungewohnt...
              Hallo Tessi,

              vielen Dank für die Erläuterung. Ich finde, Du hast das sehr verständlich beschrieben.

              Ciao, Peter

              Kommentar


                #8
                Ich häng mich mal hier dran, obwohl ich nicht sicher bin das mein Problem mit dem Titel dieses Beitrags zu tun hat. Folgendes Testprogramm:

                [highlight=epc]
                Performance]
                20
                70
                15
                [Macros]
                [MacroLibs]
                [ETS-ESF]

                [EibPC]
                TestID=1
                Testbutton=2
                Schalter=AUS

                if ( pbutton (Testbutton,TestID) ==1) and !Schalter then Schalter=EIN endif
                if ( pbutton (Testbutton,TestID) ==1) and Schalter then Schalter=AUS endif

                if change( Schalter) and !Schalter then pdisplay (Testbutton, $Aus$, CLOCK, DARKRED, GREY, TestID) endif
                if change( Schalter) and Schalter then pdisplay (Testbutton, $Ein$, CLOCK, ACTIVE, GREEN, TestID) endif

                [WebServer]
                page(TestID)[$Test$,$Test$]
                design $black$
                pbutton (Testbutton) [CLOCK] $Testbutton$
                [/highlight]

                Ich habe erwartet, dass die Variable "Schalter" bei mehrfachem Druck auf den "Testbutton" zwischen EIN und AUS wechselt und dass dies auch per pdisplay angezeigt wird. In Wirklichkeit wechselt "Schalter" nur einmal auf EIN, aber nie mehr auf AUS.

                Wenn ich "Schalter" mit dem Debugger setze funktioniert die Anzeige.

                Wenn ich die Variable "Schalter" durch write(GA,EIN/AUS) ersetze funktioniert der Code wie ich erwartet habe.

                Kann mir bitte jemand auf die Sprünge helfen? Was mache ich hier falsch, oder was habe ich falsch verstanden?

                Vielen Dank

                Rüdiger

                Kommentar


                  #9
                  Moin Rüdiger,

                  Zitat von rehell Beitrag anzeigen
                  [highlight=epc]
                  if ( pbutton (Testbutton,TestID) ==1) and !Schalter then Schalter=EIN endif
                  if ( pbutton (Testbutton,TestID) ==1) and Schalter then Schalter=AUS endif

                  if change( Schalter) and !Schalter then pdisplay (Testbutton, $Aus$, CLOCK, DARKRED, GREY, TestID) endif
                  if change( Schalter) and Schalter then pdisplay (Testbutton, $Ein$, CLOCK, ACTIVE, GREEN, TestID) endif
                  [/highlight]
                  Naja, wenn Du mit "AUS" startest wie vorgegeben und dann den Button drückst, passiert folgendes:

                  Die erste if-Abfrage prüft, ob der Button gedrückt ist, wenn ja prüft die Abfrage noch ob !Schalter = true ist. Da !AUS = EIN ist, setzt die nächste Anweisung den Schalter auf EIN.
                  Die nächste Zeile wird automatisch danach ausgeführt. Dort wird geprüft ob der Button gedrückt ist (ja, ist er jetzt ja gerade) und ob Schalter auf EIN ist. Auch das ist ja gerade eben passiert. Der Schalter ist auf EIN, also wird Schalter auf aus gesetzt.
                  Je nachdem wie der Eibparser das ganze optimiert wird dabei mal die erste oder vielleicht auch die zweite Zeile zuerst im fertigen Programmcode auftauchen.
                  Merke: Das ganze ist kein Basic Programm, was sequentiell abgearbeitet wird sondern das Programm wird übersetzt und dabei in einen Abhängigkeitsbaum überführt.

                  Du kannst die beiden Zeile abändern und schreiben:

                  [highlight=epc]
                  if ( pbutton (Testbutton,TestID) ==1) then Schalter = !Schalter endif
                  [/highlight]

                  Gruß,
                  Bernd

                  Kommentar


                    #10
                    Bernd,
                    erstmal vielen Dank, die von Dir vorgeschlagene Änderung funktioniert natürlich. Soweit die gute Nachricht.

                    Ich wollte mich eigentlich mit den Tiefen der Validierung und des Abhängikeitsbaums gar nicht beschäftigen, deshalb habe ich folgenden Code, der genau das macht was ich mir vorgestellt habe einfach kopiert und modifiziert
                    [highlight=epc]
                    if pbutton (ID,PageID)==1 and GA then write (GA,AUS) endif
                    if pbutton (ID,PageID)==1 and !GA then write (GA,EIN) endif
                    if change(GA) and GA then pdisplay (ID,$Ein$,SWITCH,ACTIVE,GREEN,PageID) endif
                    if change(GA) and !GA then pdisplay (ID,$Aus$,SWITCH,INACTIVE,GREY,PageID) endif
                    [/highlight]

                    Dieser Codeauschnitt aus einem Makro entspricht genau meinem originalen Code und funktioniert wie von mir beabsichtigt, ich habe lediglich das write(GA,EIN/AUS) durch das Setzen einer Variablen ersetzt. Warum macht das einenso gravierenden Unterschied? Du siehst, ich hab es immer noch nicht voll verstanden.Sorry.

                    mit freundlichen Grüßen Rüdiger

                    Kommentar


                      #11
                      Moin Rüdiger,

                      Zitat von rehell Beitrag anzeigen
                      die vorgeschlagene Änderung funktioniert
                      Ok, halbe Miete...

                      Zitat von rehell
                      ich habe lediglich das write(GA,EIN/AUS) durch das Setzen einer Variablen ersetzt. Warum macht das einenso gravierenden Unterschied?
                      Das ist relativ klar, wenn Du Dir im Handbuch auf S. 133 die Warteschlangenbehandlung durchliest. In Zusammenfassung ist das in etwa folgendes: Die Ausgabe für write wird erst durchgeführt, wenn der Programmlauf für den aktuellen Zyklus abgeschlossen ist.

                      Für Dein Beispiel bedeutet das folgendes:

                      (Es ist etwas doof, das Du die Reihenfolge umgedreht hast, ich mach das mal so wie vorher das Beispiel)

                      [highlight=epc]if pbutton (ID,PageID)==1 and !GA then write (GA,EIN) endif
                      if pbutton (ID,PageID)==1 and GA then write (GA,AUS) endif
                      [/highlight]

                      Beim Button drücken ist die erste Bedingung wahr und auch die zweite !GA ist ja Not AUS also EIN auch wahr. Daher wird für das Schreiben auf die GA ein EIN vorgemerkt. Da jetzt die GA aber nicht geändert wird, wird die zweite If-Abfrage nicht ausgeführt da ja GA derzeit noch den Wert AUS hat.
                      Die gewünschte GA wir also erst nach diesem Zyklus auch tatsächlich EIN.
                      Beim nächsten Zyklus wird aber der Button nicht mehr als gedrückt gemeldet und damit sind beide IF Abfragen ohne Wirkung.

                      Gruß,
                      Bernd




                      Kommentar


                        #12
                        Zitat von bmx Beitrag anzeigen
                        Merke: Das ganze ist kein Basic Programm, was sequentiell abgearbeitet wird sondern das Programm wird übersetzt und dabei in einen Abhängigkeitsbaum überführt.
                        Mal abgesehen davon, dass ich an den angeblichen Abhängigkeitsbaum nicht glaube, hat der keinen Einfluss auf die Abarbeitungsreihenfolge, analog einer auto-of-order execution. Man überzeuge mich gerne vom Gegenteil!

                        Zudem hat das Problem nichts damit zu tun und ist auch in Basic falsch.
                        BR
                        Marc

                        Kommentar


                          #13
                          Zitat von bmx Beitrag anzeigen
                          Das ist relativ klar, wenn Du Dir im Handbuch auf S. 133 die Warteschlangenbehandlung durchliest. In Zusammenfassung ist das in etwa folgendes: Die Ausgabe für write wird erst durchgeführt, wenn der Programmlauf für den aktuellen Zyklus abgeschlossen ist.
                          Gleiches gilt für change(). Auch hier steht das Ergebnis erst im nächsten Zyklus bereit.

                          Dies führt zum Effekt, dass der (aktuelle) Wert einer Variable im gleichen Zyklus verfügbar ist, eine Änderung aber erst im nächsten Zyklus erkannt wird.
                          BR
                          Marc

                          Kommentar


                            #14
                            Vielen Dank and Bernd und Marc!

                            Nun habe es auch ich soweit verstanden. Ich bin einfach davon ausgegangen dass die Änderung der Variablen "Schalter" aus dem ersten if statement erst im nächsten Zyklus für das zweite if statement zur Verfügung steht und dann wäre ja der Button nicht mehr gedrückt gewesen. Falsche Annahme.

                            Interessant der Punkt über change(). Schon wieder was gelernt.

                            mit freundlichen Grüßen

                            Rüdiger

                            Kommentar


                              #15
                              ...
                              if pbutton(xy)==1 then {
                              write(GA, !GA);
                              } endif

                              if change(GA) then {
                              if GA then {
                              pdisplay("Ein-anzeige");
                              } else {
                              pdisplay("Aus-anzeige");
                              } endif;
                              } endif

                              Invertiere die GA einfach und nach der Änderung reagierst Du auf den Zustand der GA.
                              ACTIVE und INACTIVE könntest Du über convert (GA, 0u08)+1u08, auch gleich direkt setzen. Fragt sich, ob GREEN und GREY auch noch wechseln muss...

                              (Wird jetzt bescheiden aussehen, aber auf dem Tablet find' ich kein TAB...

                              Kommentar

                              Lädt...
                              X