Ankündigung

Einklappen
Keine Ankündigung bisher.

Bug in Funktion gettime()

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

    [Firmware] Bug in Funktion gettime()

    Hallo,

    wie es scheint dürfte die Funktion gettime() einen Fehler haben. Sobald diese Funktion verwendet wird (selbst in einem IF-Zweig der nie aufgerufen wird), wird die Systemzeit auf 00:00:00 gesetzt.

    Beispiel:

    a = AUS
    if a == EIN then gettime("Uhrzeit-0/2/1") endif

    Die gettime() Funktion wird in diesem Beispiel nie aufgerufen. Trotzdem wird beim Programmstart die Systemzeit auf 00:00:00 zurück gesetzt (weil "Uhrzeit-0/2/1" noch keinen Wert besitzt) . Sobald vom Bus ein entsprechendes Zeit-Telegramm kommt passt die Uhrzeit dann (obwohl gettime() eigentlich nicht aufgerufen werden dürte).

    Bei der getdate() Funktion besteht dieses Problem übrigens nicht.

    Hier dürfte es ein Problem mit der Validierung der gettime() Funktion geben. Vermutlich ist diese Funktion immer invalid, weil die Funktion immer aufgerufen wird, unabhängig davon ob sie Teil einer IF Anweisung ist (habe schon unterschiedliche IF-Varianten mit event(), after() und systemstart() probiert).

    Bis jetzt habe ich dafür nur folgenden Workaround:

    knx_time = settime()
    if event("Uhrzeit-0/2/1") then knx_time = "Uhrzeit-0/2/1"; gettime(knx_time) endif

    Da die gettime() Funktion aber wohl bei jedem Programmdurchlauf aufgerufen wird, ist das wohl auch für die Performance vom EibPC sicher nicht so optimal.

    Schöne Grüsse,
    Klaus

    #2
    Zitat von klaus Beitrag anzeigen
    Hallo,
    a = AUS
    if a == EIN then gettime("Uhrzeit-0/2/1") endif
    Das von Dir berichtete Verhalten stimmt wohl. Allerdings wäre das Problem wenn das Verhalten anders wäre, dass der EibPC die zuletzt auf dem Bus gesendete Zeit übernimmt, aber erst dann, wenn a auf EIN wechselt.

    Performanceprobleme macht das im Übrigen nicht (vgl. Validierungskonzept).

    Aber an sich wäre Deine Anmerkung schon korrekt und die Lösung wäre (Update des Compilers notwendig)
    [highlight=epc]
    if event("Uhrzeit-0/2/1") then gettime("Uhrzeit-0/2/1") endif
    [/highlight]
    offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
    Enertex Produkte kaufen

    Kommentar


      #3
      Hallo Michael,
      Zitat von enertegus Beitrag anzeigen
      [highlight=epc]
      if event("Uhrzeit-0/2/1") then gettime("Uhrzeit-0/2/1") endif
      [/highlight]
      Genau dieses Kommando macht eben Probleme, da gettime() ausgeführt wird, obwohl kein Event aufgetreten ist. "Uhrzeit-0/2/1" ist in diesem Fall noch unbelget und die Systemuhr wird daher auf 00:00:00 gesetzt. Sobald ein Uhrzeit-Telegramm vom Bus kommt passt dann alles.

      Das eigentliche Problem dieses Verhaltens ist aber, dass sämtliche zeitrelevanten Funktionen falsche Ergebnisse liefern.

      Folgendes Kommando würde also beispielsweise ausgeführt werden, auch wenn es bereits 9 Uhr wäre:

      if ! chtime(5, 0, 0) then machwas() endif

      Was mir vorschwebt ist folgende Variante:

      knx_time = 0t24
      if systemstart() then knx_time = settime() endif
      if event("Uhrzeit-0/2/1") then knx_time = "Uhrzeit-0/2/1" endif
      gettime(knx_time)

      Was hier leider nicht funktioniert ist knx_time mit einer Konstanten zu definieren (0t24 klappt leider nicht). Ich möchte vermeiden knxtime mit "knx_time = settime()" zu definieren, da sonst ja ständig knx_time invalid werden und entsprechend gettime() auslösen würde.

      Alternativ wäre es auch möglich "Uhrzeit-0/2/1" beim Systemstart mit settime() zu belegen, bloß wie mache ich das?

      So klappt es leider nicht:

      if systemstart() then "Uhrzeit-0/2/1"=settime() endif

      Schöne Grüsse,
      Klaus

      Kommentar


        #4
        Habe eben folgende Lösung ausgearbeitet:

        knx_time = convert(0, "Uhrzeit-0/2/1")
        if systemstart() then knx_time = settime() endif
        if event("Uhrzeit-0/2/1") then knx_time = "Uhrzeit-0/2/1" endif
        gettime(knx_time)

        Spricht etwas dagege es so zu lösen?

        Kommentar


          #5
          @ Klaus

          So klappt es leider nicht:

          if systemstart() then "Uhrzeit-0/2/1"=settime() endif
          Probiers doch mal mit folgendem Code. Das wäre zumindest meine Lösung, sollte ich das Problem verstanden haben.

          if systemstart() then write("Uhrzeit-0/2/1"t24,settime()) endif

          Gruß Andreas

          Kommentar


            #6
            Zitat von Little Bastard Beitrag anzeigen
            Probiers doch mal mit folgendem Code. Das wäre zumindest meine Lösung, sollte ich das Problem verstanden haben.

            if systemstart() then write("Uhrzeit-0/2/1"t24,settime()) endif
            Ist leider nicht ganz das was ich suche, denn ich will die Zeit vom Bus auf den EibPC bringen. Obiges Kommando würde mir die Zeit vom EibPC auf den Bus schreiben.

            Wahrscheinlich werde ich den Code für die Zeitsynchronisation aber ohnehin wieder komplett rausschmeissen und darauf vertrauen, dass die NTP Zeit vom EibPC und die GPS Zeit vom Bus einigermassen synchron laufen. Muss ich bei Gelegenheit mal prüfen, wie gross hier der Unterschied ist.

            Klaus

            Kommentar


              #7
              Wie wäre es dann mit soetwas:

              if systemstart() then {\\
              read ("Uhrzeit-0/2/1");
              gettime("Uhrzeit-0/2/1")}endif

              Das sollte beim Start die Uhrzeit vom Bus lesen und dann Initial zuordnen

              Gruß Andreas

              Kommentar


                #8
                Zitat von Little Bastard Beitrag anzeigen
                Wie wäre es dann mit soetwas:

                if systemstart() then {\\
                read ("Uhrzeit-0/2/1");
                gettime("Uhrzeit-0/2/1")}endif

                Das sollte beim Start die Uhrzeit vom Bus lesen und dann Initial zuordnen
                Klappt so leider auch nicht, da der read() ja nicht sofort ein Ergebnis liefert. Bis die Leseanforderung auf den Bus gesendet ist und das Ergebnis retour kommt vergehen gut und gerne 100 ms. Bis dahin hat der EibPC schon viele male das Programm durchlaufen und längst gettime() mit der Uhrzeit 00:00:00 aufgerufen.

                Wichtig ist hier, dass die korrekte Zeit bereits beim ersten Zyklus vorhanden ist, da sonst sämtliche zeitabhängigen Funktionen falsche Ergebnisse liefern.

                Klaus

                Kommentar


                  #9
                  Zitat von klaus Beitrag anzeigen
                  Klappt so leider auch nicht, da der read() ja nicht sofort ein Ergebnis liefert. Bis die Leseanforderung auf den Bus gesendet ist und das Ergebnis retour kommt vergehen gut und gerne 100 ms. Bis dahin hat der EibPC schon viele male das Programm durchlaufen und längst gettime() mit der Uhrzeit 00:00:00 aufgerufen.
                  Es wird da im nächsten Release eine neue Sektion [InitGA] geben, dazu mehr anbei.
                  Auch die ntp-Sache wird dann konfigurierbar, also warten mit der Verarbeitung bis ntp synchronisiert werden konnte, oder ntp immer abschalten oder so wie bisher immer an ohne Timeout.
                  Damit dürften diverse ähnliche Probleme aus dem Weg geräumt sein.
                  Angehängte Dateien
                  offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                  Enertex Produkte kaufen

                  Kommentar


                    #10
                    • Initializing the group addresses means, the EibPC sends read telegramms to the group
                    addresses. Each Groupaddress will be sent after waiting for a response with a timeout of
                    1500 ms.


                    Kann ich den Timeout auch einstellen?


                    • After the last read telegram is initiated, the EibPC starts processing the user program.

                    Startet das Anwenderprogramm, nachdem das letzte Read-Telegramm GESENDET wurde, oder nachdem für das letzte gesendete Telegramm eine Antwort oder ein Timeout empfangen wurde?


                    Welche möglichkeit habe ich, im Timeoutfalle das Read zu wiederholen oder Initial einen Fantasiewert zuzuweisen, um wenigsten später prüfen zu können, ob nach Durchlaufen der InitGA-Sektion eine GA auch korrekt initialisiert wurde?
                    Kann ich in der InitGA-Sektion auch andere Anweisungen benutzen?

                    [InitGA]
                    Temperatur = -200f16
                    read("TempGA")
                    if NOT TimeoutTempGA then Temperatur = TempGA endif
                    Gruss Pio

                    Kommentar


                      #11
                      Zitat von enertegus Beitrag anzeigen
                      Es wird da im nächsten Release eine neue Sektion [InitGA] geben, dazu mehr anbei.
                      Klingt nach einer sehr nützlichen Sache. Ich habe mittlerweile auch einen Vergleich zwischen der NTP-Uhrzeit und der GPS-Uhrzeit die über den Bus kommt gemacht. Ergebnis: die Zeit ist auf die Sekunde genau gleich. So gesehen lass ich den EibPC die Zeit jetzt selbst synchronisieren und ignoriere die Zeit-Telegramme am Bus.

                      Klaus

                      Kommentar


                        #12
                        Zitat von klaus Beitrag anzeigen
                        Klingt nach einer sehr nützlichen Sache. Ich habe mittlerweile auch einen Vergleich zwischen der NTP-Uhrzeit und der GPS-Uhrzeit die über den Bus kommt gemacht. Ergebnis: die Zeit ist auf die Sekunde genau gleich. So gesehen lass ich den EibPC die Zeit jetzt selbst synchronisieren und ignoriere die Zeit-Telegramme am Bus.

                        Klaus
                        Für NTP und GPS sind Zeiträume von einer Sekunde Welten Mit beiden sollten nur Abweichungen von ein paar ms entstehen.
                        Firma: Enertex Bayern GmbH, Ebermannstädter Straße 8, 91301 Forchheim
                        Amazon: KNXnet/IP Router
                        , KNXnet/IP Interface

                        Kommentar


                          #13
                          Zitat von pio Beitrag anzeigen
                          1. Kann ich den Timeout auch einstellen?
                          2. Startet das Anwenderprogramm, nachdem das letzte Read-Telegramm GESENDET wurde, oder nachdem für das letzte gesendete Telegramm eine Antwort oder ein Timeout empfangen wurde?
                          3. Welche möglichkeit habe ich, im Timeoutfalle das Read zu wiederholen oder Initial einen Fantasiewert zuzuweisen, um wenigsten später prüfen zu können, ob nach Durchlaufen der InitGA-Sektion eine GA auch korrekt initialisiert wurde?
                          4. Kann ich in der InitGA-Sektion auch andere Anweisungen benutzen?
                          Die Fragen haben sich auch mir gestellt. Hinzu kommt:
                          Warum soll ich nach jedem Read erst den Timeout abwarten? Im Grunde genommen kann ich alle Anfragen kurz hintereinander senden, z.B. mit 200ms Abstand. Nach der letzten warte ich dann noch den Timeout ab. Die Antworten müssen ja nicht in der Reihenfolge der Anfragen kommen, Haupsache sie kommen überhaupt innerhalb einer gewissen Zeit nach der Anfrage. Und mit 10 Telegrammen/s ist der Bus im Allgemeinen noch nicht überlastet (mein Berker MasterControl fragt mit 100ms Abstand ab und das funktioniert).




                          Mein Vorschlag wäre:
                          1. GAs werden in genau der Reihenfolge abgefragt, in der sie aufgelistet sind. Das erlaubt, die "langsamen" Geräte zuerst abzufragen und in Zweifelsfällen eine Verschachtelung die dafür sorgt, das nicht zu viele Anfragen hintereinander an das selbe Gerät gehen und dieses dann überfordern.
                          2. GAs werden in einem konfigurierbaren Abstand abgefragt (hat nichts mit dem Timeout zu tun) für Ausnahmefälle sollte zwischen zwei GAs auch eine explizite Pause eingefügt werden können, die dann die globale Angabe ersetzt. Gedacht für den Fall das wieder mehrere Anfragen an ein Gerät gehen, aber nicht genügend andere Abfragen da sind, die immer dazwischen geschoben werden können.
                          3. Es gibt einen konfigurierbaren Timeout, an sich für alle GAs, jedoch sollten GAs auch individuelle Zeiten gegeben werden können.
                          4. Für jede GA sollte angegeben werden können, wie oft die Anfrage nach Ablauf ihres Timeout jeweils wiederholt werden soll.
                          5. Für jede GA sollte angegeben werden können, was geschehen soll, wenn auch dann keine Antwort da ist.
                          6. Der Übergang in den "Normalbetrieb" erfolgt, wenn die letzte Antwort da ist oder der letzte Timeout nach der letzten Wiederholung abgelaufen ist. Optional sollte eine Wartezeit angegeben werden können, z.B. um auf nicht abfragbare aber zyklisch gesendete Informationen (z.B. Uhrzeit) zu warten.
                          7. Wenn ich den Telegramm-Speicher des EPCs auslese, finde ich Angaben darüber, wer wann was an wen gesendet hat. Aber intern weiß der EPC nicht einmal, ob seit Start überhaupt etwas an eine bestimmte GA zugewiesen wurde? Da sollte der EPC irgendwie um die Möglichkeit erweiter werden, das man zu einer GA abfragen kann, ob sie schon mal empfangen wurde - und ggf. auch wie lange das schon her ist. Dann kann Punkt 5 ggf. aus [InitGA] streichen und später im Betrieb nachholen. Außerdem erlaubt das auch Kontrolle derjenigen GAs, die nur sporadisch gesendet werden und nicht auslesbar sind - da hilft [InitGA] nicht...
                          Warum so kompliziert?
                          Nun, ich hätte einige Dutzend GAs abzufragen. Wenn jede mit 1.5s zu Buche schlägt (ohne Wiederholung) dann zieht sich der Startvorgang schon ganz schön in die Länge. Und das Problem, das eine GA danach immer noch ungültig sein kann, bleibt bestehen.

                          Richtig flexibel wäre es aber nur, wenn es eine Init-Sektion gäbe, in der ganz normaler Code ausgeführt werden kann, der dann auch bestimmt, wann in die nächste Sektion übergegangen werden soll.

                          Zum eigentlichen Thema:
                          Ich finde es auch nicht so gut, das gettime() immer wieder ausgeführt wird, vielleicht will ich ja nur hin und wieder synchronisieren. Und was passiert, wenn der Zeitmaster am Bus ausfällt? Bleibt die Zeit des EPCs dann quasi stehen? Weil die GA sich nicht mehr ändert aber immer wieder verwendet wird?
                          Tessi

                          Kommentar


                            #14
                            ist halt immer der Spagat zwischen "optimal konfigurierbar" und "noch für jedermann verständlich". Mir würden Tessis Vorschläge erst mal zu weit gehen, da haben wir wichtigere Baustellen.

                            In drei Punkten stimme ich aber zu: Die Wartezeit sollte einmalig am Ende zuschlagen, nicht zwischen jeder Abfrage, das spart Zeit und macht es nciht schlechter. Für die "Abfragegeschwindigkeit" würde ich ganz normal die Telegrammratenbegrenzung heranziehen. Durch geschicktes Anordnen der GAs kann ich (wenn der EibPC sich dran hält) vermeiden, dass langsame Geräte zu viele Request hintereinander bekommen.

                            Und: Irgendwie sollte man feststellen können, ob eine Antwort kam, oder nicht. DIe Idee einen "Status" zur GA abzufragen, ist vielleicht gar nciht so dumm, also "Status(GA)" liefert die Zeit in Sek seit dem letzten empfangenen Programm oder 0, wenn noch keines empfangen.
                            ....und versuchen Sie nicht erst anhand der Farbe der Stichflamme zu erkennen, was Sie falsch gemacht haben!

                            Kommentar


                              #15
                              Zitat von pio Beitrag anzeigen
                              Kann ich den Timeout auch einstellen?
                              Nein lt. Standard, muss nach dieser Zeit (plus eine Enertex Sicherheit) die Antwort da sein. Wenn das früher der Fall ist, dauert das nicht so lange.
                              "Warum überhaupt die Sache mit dem Timeout, kann man nicht einfach alles rausblasen und dann halt nach der letzten GA warten?" - So dachte ich auch bis hier:
                              https://knx-user-forum.de/knx-eib-fo...nterfaces.html

                              Das Problem ist, dass dann die [von mir getestete] IP Schnittstellen sonst rumzicken. Wie gesagt, wenn's schneller geht, ist es ja eh kein Problem. Die optimale Performance braucht man eben nicht zu "tunen".

                              startet das Anwenderprogramm, nachdem das letzte Read-Telegramm GESENDET wurde, oder nachdem für das letzte gesendete Telegramm eine Antwort oder ein Timeout empfangen wurde?
                              Nach der Antwort bzw. Timeout.

                              Welche möglichkeit habe ich, im Timeoutfalle das Read zu wiederholen oder Initial einen Fantasiewert zuzuweisen, um wenigsten später prüfen zu können, ob nach Durchlaufen der InitGA-Sektion eine GA auch korrekt initialisiert wurde?
                              Nein, dann hast Du eben einen Fehler bei Deiner Installation. Die Teile müssen antworten, lt. Standard. Ausnahme: Das Leseflag ist nicht gesetzt.

                              Code in InitGA ist nicht erlaubt.
                              offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                              Enertex Produkte kaufen

                              Kommentar

                              Lädt...
                              X