Ankündigung

Einklappen
Keine Ankündigung bisher.

Verständnisproblem oder Fehler in eventwrite()?

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

    Verständnisproblem oder Fehler in eventwrite()?

    Hallo zusammen,

    habe ich ein Verständnisproblem bei der Verwendung von eventwrite()?

    EibPC: Firmware 2.004, Patch 2.100, EibStudio 2.100

    (sorry, dieser Text ist etwas lang geworden. Ich wollte halt möglichst präzise sein.)

    Anstatt mit event() auf write/response/read-Telegramme zu reagieren, möchte ich gezielt write-Telegramme verarbeiten - also mit eventwrite().

    Hierzu möchte ich Anweisungen wie folgt programmieren:
    [highlight=epc]
    if (eventwrite(<GA>) && <GA> == <Zielwert>) then \\
    {
    <Anweisungen>
    } endif
    [/highlight]
    (wobei <GA> natürlich einer Gruppenadresse im Format "Name-X/Y/Z" entspricht und <Zielwert> ein gültiger Wert für die Gruppenadresse ist.)

    Nach meinen Beobachtungen wird <Anweisungen> nur dann ausgeführt, wenn ein Write-Telegramm auftritt *und* sich der Wert der <GA> seit dem letzten eventwrite(<GA>) geändert hat und der Wert der <GA> dem <Zielwert> entspricht. D.h. sende ich mehrfach hintereinander denselben <Zielwert> auf den Bus, werden <Anweisungen> trotzdem nur einmal ausgeführt.

    Eigentlich hätte ich doch aber erwartet, dass <Anweisungen> immer ausgeführt wird, wenn ein Write-Telegramm auftritt und der Wert der <GA> dem <Zielwert> entspricht, also auch, wenn sich der Wert nicht geändert hat.

    Ersetze ich in obigem Beispiel eventwrite() durch event(), so wird <Anweisungen> bei jedem Write-Telegramm mit dem erwarteten <Zielwert> ausgeführt.

    Zum Verdeutlichung, wann event() und eventwrite() auslöst, habe ich folgendes kleine Progrämmchen:
    [highlight=epc]
    // ================================================== ===========================
    // event()/eventwrite() einzeln
    // ================================================== ===========================
    if (event("Test_1Byte_UInt-9/5/102")) then \\
    {
    syslog($event: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif

    if (eventwrite("Test_1Byte_UInt-9/5/102")) then \\
    {
    syslog($write: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif

    // ================================================== ===========================
    // event()/eventwrite() und Wert == 0?
    // ================================================== ===========================
    if (event("Test_1Byte_UInt-9/5/102") && "Test_1Byte_UInt-9/5/102" == 0) then \\
    {
    syslog($event_0: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif

    if (eventwrite("Test_1Byte_UInt-9/5/102") && "Test_1Byte_UInt-9/5/102" == 0) then \\
    {
    syslog($write_0: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif

    // ================================================== ===========================
    // event()/eventwrite() und Wert == 1?
    // ================================================== ===========================
    if (event("Test_1Byte_UInt-9/5/102") && "Test_1Byte_UInt-9/5/102" == 1) then \\
    {
    syslog($event_1: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif

    if (eventwrite("Test_1Byte_UInt-9/5/102") && "Test_1Byte_UInt-9/5/102" == 1) then \\
    {
    syslog($write_1: Test_1Byte_UInt value: $ + convert("Test_1Byte_UInt-9/5/102", $$))
    } endif
    [/highlight]

    Die Funktion syslog() kommt aus (den Anfängen) meiner Macro-Bibliothek:

    [highlight=epc]
    // ================================================== ===========================
    // getTimeStr()
    // ================================================== ===========================
    :begin getTimeStr()
    :shortinfo $Liefert die Uhrzeit als String im Format hh:mm:ss$
    stringformat(hour() , 0, 3, 2, 2) + $:$ + \\
    stringformat(minute(), 0, 3, 2, 2) + $:$ + \\
    stringformat(second(), 0, 3, 2, 2)
    :end

    // ================================================== ===========================
    // syslog()
    // ================================================== ===========================
    :begin syslog(theText)
    :info $Schickt den gegebenen Text an netcat auf einem anderen PC$
    :var aLF@
    aLF@ = $ $

    if (EIN) then \\
    {
    stringset(aLF@, 10, 0u16);

    sendudp( 5555u16 \\
    , 192.168.1.6 \\
    , getTimeStr() + $: $ + convert(theText,$$) + aLF@ \\
    )
    } endif
    :end
    [/highlight]

    syslog() schickt den übergebenen Wert (erweitert um Uhrzeit und LF) an einen anderen PC, auf dem ich die Logs mit Netcat (nc -u -l -p 5555) auf der Konsole ausgebe.
    (BTW: eine 'echte' syslog()-Funktion zur Übergabe von Logs an einen syslogd auf einem anderen Rechner wäre wünschenswert/hilfreich.)

    Beobachtungen:
    Ausgangssituation: der Wert der GA ist 2
    Mit jeweils ca. 5 Sekunden Abstand löse ich zunächst zwei Write Telegramme mit Wert 1 aus und anschliessend zwei Write-Telegramme mit Wert 0

    Auszug aus dem Meldungsfenster von EibStudio:
    (Leerzeilen und Kommentare händisch eingefügt)
    Code:
    // Ausgangssituation herstellen:
    % 2011-04-15 13:22:43 | Sender: 1.1.55 | GA: "Test_1Byte_UInt-9/5/102" | Wert: 2 | Typ: positive Ganzzahl |  Schreiben
    
    // 1. Telegramm: Wert 1 schreiben:
    % 2011-04-15 13:23:00 | Sender: 1.1.55 | GA: "Test_1Byte_UInt-9/5/102" | Wert: 1 | Typ: positive Ganzzahl |  Schreiben
    
    // 2. Telegramm: Wert 1 schreiben:
    % 2011-04-15 13:23:05 | Sender: 1.1.55 | GA: "Test_1Byte_UInt-9/5/102" | Wert: 1 | Typ: positive Ganzzahl |  Schreiben
    
    // 3. Telegramm: Wert 0 schreiben:
    % 2011-04-15 13:23:10 | Sender: 1.1.55 | GA: "Test_1Byte_UInt-9/5/102" | Wert: 0 | Typ: positive Ganzzahl |  Schreiben
    
    // 4. Telegramm: Wert 0 schreiben:
    % 2011-04-15 13:23:15 | Sender: 1.1.55 | GA: "Test_1Byte_UInt-9/5/102" | Wert: 0 | Typ: positive Ganzzahl |  Schreiben
    Ausgabe von Netcat:
    (Leerzeilen und Kommentare händisch eingefügt)
    Code:
    // Reaktion auf 1. Telegramm: Wert 1 schreiben:
    13:23:00: write:      Test_1Byte_UInt  value: 1
    13:23:00: write_1:    Test_1Byte_UInt  value: 1
    13:23:00: event:      Test_1Byte_UInt  value: 1
    13:23:00: event_1:    Test_1Byte_UInt  value: 1
    
    // Reaktion auf 2. Telegramm: Wert 1 schreiben:
    13:23:05: write:      Test_1Byte_UInt  value: 1
    13:23:05: event:      Test_1Byte_UInt  value: 1
    13:23:05: event_1:    Test_1Byte_UInt  value: 1
    
    // Reaktion auf 3. Telegramm: Wert 0 schreiben:
    13:23:10: write:      Test_1Byte_UInt  value: 0
    13:23:10: write_0:    Test_1Byte_UInt  value: 0
    13:23:10: event:      Test_1Byte_UInt  value: 0
    13:23:10: event_0:    Test_1Byte_UInt  value: 0
    
    // Reaktion auf 4. Telegramm: Wert 0 schreiben:
    13:23:15: write:      Test_1Byte_UInt  value: 0
    13:23:15: event:      Test_1Byte_UInt  value: 0
    13:23:15: event_0:    Test_1Byte_UInt  value: 0
    Wie zu sehen ist, wird beim zweiten und beim vierten Telegramm die Ausgabe "write_0" bzw. "write_1" nicht ausgegeben, d.h. event() wird zwar ausgelöst, eventwrite() jedoch nicht.

    Wo liegt hier mein Verständnisproblem?

    Viele Grüße und vielen Dank,

    Alex

    PS: Kleine Frage am Rande: Warum lässt sich folgender Code nicht compilieren:

    [highlight=epc]
    // ================================================== ===========================
    // syslog()
    // ================================================== ===========================
    :begin syslog(theText)
    :info $Schickt den gegebenen Text an netcat auf einem anderen PC$
    :var aLF@
    aLF@ = $ $

    stringset(aLF@, 10, 0u16);

    sendudp( 5555u16 \\
    , 192.168.1.6 \\
    , getTimeStr() + $: $ + convert(theText,$$) + aLF@ \\
    )

    :end
    [/highlight]

    liefert:
    Code:
    Makro genieriert ungültigen Code >stringset(__syslog_0__aLF, 10, 0u16);<
    
    Internal Error
    Please report this bug
    EC:127
    füge ich ein "if (EIN)...endif" um die Anweisungen stringset & sendmail (siehe oben) compilierts.

    #2
    Zu der kleinen Frage am Rande:

    Bin zwar kein EibPC-Experte, da ich noch keinen habe und kann dahernur vermuten:

    Der EibPC weiss nicht wann der Code ausgeführt werden soll wenn du kein if drum herum baust.
    Mit dem if (EIN) würde ich erwarten, dass das dann jeden Zyklus ausgeführt wird.

    Ich würde die "cycle"-Funktion drum herum packen.
    z.B. if cycle(1,0) then <Das jede Minute ausführen> endif

    Kommentar


      #3
      Zur kleinen Frage:
      Warum diese Fehlermeldung kommt, weiß wohl nur der Entwickler...

      Unbedingte Befehle werden tatsächlich nicht ausgeführt, da eine Ausführung in jedem Zyklus kaum je sinnvoll ist und das System fast immer überlasten würde.

      Aber if(EIN) tut das auch nicht, denn der ganze Ausdruck wird ja nur ausgewertet, wenn sich etwas an der Bedingung ändert, aber EIN ist eine Konstante...

      An sich sollte der Compiler auch solchen toten Code melden...
      Tessi

      Kommentar


        #4
        Zitat von Alex Beitrag anzeigen
        habe ich ein Verständnisproblem bei der Verwendung von eventwrite()?
        Da habe ich auch Verständnisschwierigkeiten, denn die Anleitung spricht immer noch von einer Antwort auf ein write(), wie das erkannt werden soll verstehe ich nicht (siehe auch https://knx-user-forum.de/144371-post3.html).

        Dein beobachtetes Verhalten habe ich auch so gesehen (ich hatte testweise alle event() durch ein eventwrite() ersetzt, da sich eigentlich nichts ändern sollte ... dachte ich).
        BR
        Marc

        Kommentar


          #5
          Zitat von Tessi Beitrag anzeigen
          Aber if(EIN) tut das auch nicht, denn der ganze Ausdruck wird ja nur ausgewertet, wenn sich etwas an der Bedingung ändert, aber EIN ist eine Konstante...
          Wenn das Makro ausgewertet ist, dann steht da was anderes, dann hat der Alex außen herum noch ein ein if event GA then drumherum

          [highlight=epc]
          if event(GA) then {
          {
          syslog( Text )
          } endif
          [/highlight]


          daraus wird dann ein

          [highlight=epc]
          if event(GA) then {
          {
          if (EIN) then \\
          {
          stringset(aLF@, 10, 0u16);

          sendudp( 5555u16 \\
          , 192.168.1.6 \\
          , getTimeStr() + $: $ + convert(Text,$$) + aLF@ \\
          )
          } endif
          } endif
          [/highlight]

          Da das innere der if ... then dann immer neu evaluiert wird, sollte das schon funktionieren.

          Übrigens habe ich derzeit meine "neuen" eventwrite auch wieder durch event zurückersetzt da ich nicht wußte warum das nicht so lief, wie ich erwartet hatte. Ich wollte bei mir nur auf die writes vom Bewegungsmelder reagieren, nicht auf response oder read. Habe das aber auf die Beta geschoben und mir keine weiteren Gedanken dazu gemacht.

          Gruß,
          Bernd

          Kommentar


            #6
            Zitat von Alex Beitrag anzeigen
            Hallo zusammen,
            habe ich ein Verständnisproblem bei der Verwendung von eventwrite()?
            Ok, das ist wohl ein echter Bug. Eigentlich ist die Verwendung so wie Du gedacht hast.
            PS: Kleine Frage am Rande: Warum lässt sich folgender Code nicht compilieren:
            Internal Error
            Please report this bug
            Das wäre dann ein 2. Bug. Sowas und das in einem Posting
            offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
            Enertex Produkte kaufen

            Kommentar


              #7
              Zitat von bmx Beitrag anzeigen
              Da das innere der if ... then dann immer neu evaluiert wird, sollte das schon funktionieren.
              Richtig, ein Workaround eben. Aber der "internal" Bug muss weg...
              offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
              Enertex Produkte kaufen

              Kommentar


                #8
                Sorry, etwas verspätet: vielen Dank an alle für die Rückmeldungen.

                Zitat von enertegus Beitrag anzeigen
                Ok, das ist wohl ein echter Bug. Eigentlich ist die Verwendung so wie Du gedacht hast.
                Ok, dann habe ich die Funktion zumindest richtig verstanden.

                Zitat von enertegus Beitrag anzeigen
                ...Aber der "internal" Bug muss weg...
                Prima.

                Werden beide Fehler in der nächsten Firmware/Patch behoben sein? Kannst Du vielleicht sogar schon abschätzen, wann es soweit sein wird?

                Viele Grüße,
                Alex

                Kommentar


                  #9
                  Zitat von Alex Beitrag anzeigen
                  Werden beide Fehler in der nächsten Firmware/Patch behoben sein?
                  Ja
                  Kannst Du vielleicht sogar schon abschätzen, wann es soweit sein wird?
                  Schwer zu sagen: 3 bis 8 Wochen ...
                  offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                  Enertex Produkte kaufen

                  Kommentar


                    #10
                    Zitat von Alex Beitrag anzeigen
                    [highlight=epc]
                    // ================================================== ===========================
                    // syslog()
                    // ================================================== ===========================
                    :begin syslog(theText)
                    :info $Schickt den gegebenen Text an netcat auf einem anderen PC$
                    :var aLF@
                    aLF@ = $ $

                    stringset(aLF@, 10, 0u16);

                    sendudp( 5555u16 \\
                    , 192.168.1.6 \\
                    , getTimeStr() + $: $ + convert(theText,$$) + aLF@ \\
                    )

                    :end
                    [/highlight]

                    liefert:
                    Code:
                    Makro genieriert ungültigen Code >stringset(__syslog_0__aLF, 10, 0u16);<
                    
                    Internal Error
                    Please report this bug
                    EC:127
                    füge ich ein "if (EIN)...endif" um die Anweisungen stringset & sendmail (siehe oben) compilierts.
                    Das Problem tritt auf, da Du kein :return definiert hast.
                    Grundsätzlich ist auch bei Makrofunktionen das Validierungsschema zu berücksichtigen (siehe hierzu auch im aktuellen Handbuch):

                    if XXX then MyMacrofunc() endif

                    Hier wird alles, was hinter :return in MyMacrofunc() definiert wurde, in die Abhängigkeitsliste der if-Anweisung "eingehängt". Wenn kein :return im Makro steht, so wird die letzte Zeile vor dem :end genutzt.
                    Diese letzte Zeile ist aber eine leere Zeile, die der Compiler in die Abhängigkeit von if bringen soll/will und das kann ja nicht gehen.
                    Ich hab da nun eine Fehlermeldung eingebaut.

                    In Deinem Fall solltest Du
                    Code:
                    :return { 
                         stringset(aLF@, 10, 0u16);
                         sendudp( 5555u16 , 192.168.1.6, getTimeStr() + $: $ + convert(theText,$$) + aLF@);
                    }
                    schreiben. Dann stimmt alles.
                    Aber bitte unbedingt die Sache mit dem :return lesen und verinnerlichen.
                    Dein Workaround mit if EIN sorgt für ein ähnliches Verhalten und die Verschachtelung dieser if EIN mit der äußeren im Code sorgt für die Auswertung (vgl. Valdierungskonzept, Verschachtelungen im Handbuch).
                    offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                    Enertex Produkte kaufen

                    Kommentar

                    Lädt...
                    X