Ankündigung

Einklappen
Keine Ankündigung bisher.

address(XXXu16) / getaddress(XXXu16) irgendwo hakt es...

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

    address(XXXu16) / getaddress(XXXu16) irgendwo hakt es...

    Gegeben ein Makro, das eine Reihe von 8 GAs verarbeiten soll, die Basis der Untergruppe ist immer "0".

    [highlight=epc]
    :begin RolloFensterGriffMainDefinitions(Name, pGAbase)
    :info $Bereitstellen der Variablen für die verschiedenen Makros zur Interaktion$\\
    $Name zur Eindeutigkeit$\\
    $Basisgruppenadresse des Rollladens$

    //Rollladenglobale Konstanten
    Name_DoLearnNow = AUS //Löst den Lernvorgang aus - Auch verwendet in Makro "TasteGotoAndLearnpos"
    Name_DoGotoLearntPos = AUS //Löst den Goto-Vorgang zur gelernten Position aus - Auch verwendet in Makro "TasteGotoAndLearnpos"

    Name_GAbasis = getaddress(pGAbase)
    Name_GAstop = getaddress(pGAbase) + 1u16
    Name_GAStatusOben = getaddress(pGAbase) + 2u16
    Name_GAStatusUnten = getaddress(pGAbase) + 3u16
    Name_GAStatusPosition = getaddress(pGAbase) + 4u16
    Name_GAGoToPos = getaddress(pGAbase) + 5u16
    Name_GATasteDoppelklick = getaddress(pGAbase) + 6u16
    Name_GALEDquittung = getaddress(pGAbase) + 7u16

    .......
    [/highlight]

    Damit will ich mir ersparen, bei 14 Rollläden insgesamt 112 GAs als Parameter richtig einkopieren zu müssen und eine typische Fehlerquelle (ich...) vermeiden.

    In den darauf aufbauenden Makros (es werden nicht immer alle benutzt) sollen die GAs dann wie im Manual mit write(adress(...),Wert) beschrieben als address(Name_GA...) verwendet werden:

    [highlight=epc]
    begin Rollo(Name, btnShiftAufABStop, btnLearnPos, pgID, FlashAdrGoto)
    :info $Rollladenbedienung: RAUF, RUNTER, STOP, PROZENTPOSITION anfahren$ \\
    $Name (wegen Eindeutigkeit)$\\
    $Web: pShifter Runter / Rauf / Goto / Stop für $\\
    $Web: pButton Position lernen$\\
    $Web: Page ID$\\
    $Flash: Adresse des gelernten Prozentwerts (u08)$\\ //Wertebereich 0..255 !
    ...
    /* ----------------------- Abarbeiten der Events ------------------ */
    if event(address(Name_GAbasis)) or event(address(Name_GAGoToPos)) then {
    Name_isMoving = EIN;
    if (address(Name_GAbasis) == RAUF) or (Name_PosAktuell > Name_GoToPos) then {
    pdisplay(btnLearnPos,$Fährt auf $ + convert(Uhrzeit,$$),UP,ACTIVE,GREEN,pgID);
    } else {
    pdisplay(btnLearnPos,$Fährt zu $ + convert(Uhrzeit,$$),DOWN,ACTIVE,GREEN,pgID);
    } endif
    } endif
    // STOP-Event
    if (event(address(Name_GAstop)) and (address(Name_GAstop)) == EIN) then {
    pdisplay(btnShiftAufABStop,Uhrzeit,STOP,BRIGHTRED, GREEN,pgID);
    Name_StopPressed = EIN;
    Name_isMoving = AUS;
    } endif
    if (delay(Name_StopPressed==EIN, 5000u64)) then {
    pdisplay(btnShiftAufABStop,Uhrzeit,STOP,INACTIVE,G REEN,pgID);
    Name_StopPressed = AUS;
    } endif
    // Statusauswertungen
    if event(address(Name_GAStatusPosition)) or (event(address(Name_GAStatusOben)) and address(Name_GAStatusOben)) or (event(address(Name_GAStatusUnten)) and address(Name_GAStatusUnten)) then {
    Name_isMoving = AUS;
    Name_PosAktuell = address(Name_GAStatusPosition);
    Name_GoToPos = Name_PosAktuell;

    if (address(Name_GAStatusPosition) == 0% or address(Name_GAStatusOben)) then {
    pdisplay(btnLearnPos,convert( 0f16,$$) + $ %$,ROLLER,STATE7,GREEN,pgID);
    } endif;
    if (address(Name_GAStatusPosition) == 100% or address(Name_GAStatusUnten)) then {
    pdisplay(btnLearnPos,convert(100f16,$$) + $ %$,ROLLER,ACTIVE,GREEN,pgID);
    } endif;
    if (address(Name_GAStatusPosition) == C^Name^Lamel) and !address(Name_GAStatusOben) and !address(Name_GAStatusUnten) then {
    pdisplay(btnLearnPos,convert(address(Name_GAStatus Position),$$) + $ %$,ROLLER,STATE4,GREEN,pgID);
    } endif;
    if (address(Name_GAStatusPosition) < 100%) and (address(Name_GAStatusPosition) > C^Name^Lamel) and !address(Name_GAStatusOben) and !address(Name_GAStatusUnten) then {
    pdisplay(btnLearnPos,convert(convert(address(Name_ GAStatusPosition),0f16) * 100f16 / 255f16,$$) + $ %$,ROLLER,DISPLAY,GREEN,pgID);
    } endif;
    if (address(Name_GAStatusPosition) > 0%) and (address(Name_GAStatusPosition) < C^Name^Lamel) and !address(Name_GAStatusOben) and !address(Name_GAStatusUnten) then {
    pdisplay(btnLearnPos,convert(convert(address(Name_ GAStatusPosition),0f16) * 100f16 / 255f16,$$) + $ %$,ROLLER,STATE5,GREEN,pgID);
    } endif;

    if (Name_Ausloeser == 1) then {
    Name_ManuellPos = Name_PosAktuell;
    Name_ManuellPosTime = utctime();
    } endif;
    if (Name_Ausloeser == 1) then {
    Name_ManuellPos = Name_PosAktuell;
    Name_ManuellPosTime = utctime();
    } endif;

    pdisplay(btnShiftAufABStop,Uhrzeit,STOP,INACTIVE,G REEN,pgID);
    } endif
    ...
    [/highlight]

    Beim Kompilieren (Name=RollDGBuero) motzt EibStudio:
    !! Anwendungsfehler !!
    Gruppenadresse wurde doppelt definiert:RollDGBuero_GAGoToPos
    EC:103


    Kommentiere ich oben die Zeilen 10 bis 17 (if event(address(Name_GAbasis...) aus, bemängelt EibStudio:
    !! Anwendungsfehler !!
    Gruppenadresse wurde doppelt definiert:RollDGBuero_GAStatusPosition
    EC:103

    Anscheinend verschluckt es sich jetzt an Zeile 29.

    Gibt es irgendwelche bekannten Probleme oder Einschränkungen bei der Verwendung von address() / getaddress() in Makros?

    #2
    address() hat wohl einen Bug

    So jetzt noch einmal auf ein einfach(st)es Beispiel reduziert:

    Die Fehlermeldung des Eibstudio:
    !! Anwendungsfehler !!
    Gruppenadresse wurde doppelt definiert:Test_GA1
    EC:103


    Das kleine Makro:
    [highlight=epc]
    /*---- Test address() / getaddress()
    :begin Testmakro(Name, pGAbasis)

    Name_GA1 = getaddress(pGAbasis)
    Name_GA2 = Name_GA1 + 1u16

    if event(address(Name_GA1)) and address(Name_GA1)==AUS then {
    write(address(Name_GA2),AUS);
    } endif
    if event(address(Name_GA1)) and address(Name_GA1)==EIN then {
    write(address(Name_GA2),EIN);
    } endif

    :end

    //Die Aufrufdeklaration im Hauptprogramm:
    Testmakro(Test,"Test LED1-4/0/101")
    if pbutton(btnTestLED,pgID_testpage)==1 then {
    write("Test LED1-4/0/101",!"Test LED1-4/0/101");
    } endif
    [/highlight]

    Die folgende Version lässt sich kompilieren und ausführen. Allerdings führt das Makro nicht dazu, die zweite LED parallel mit zu schalten. Also wieder nix Gescheites...:

    [highlight=epc]
    /*--------------- Ein Testbereich für Makros --------------------*/
    /*---- Test address() / getaddress()
    :begin Testmakro(Name, pGAbasis)

    Name_GA1 = getaddress(pGAbasis)
    Name_GA2 = Name_GA1 + 1u16
    Name_Zaehler = 0u16

    if event(address(Name_GA1)) then {
    write(address(Name_GA2),address(Name_GA1));
    Name_Zaehler = Name_Zaehler+1u16;
    } endif
    :end
    [/highlight]

    und wenn man den Debugger aufrufen will, um zu sehen, ob wenigstens der Zähler hochzählt, kommt ein Fenster im EibStudio mit der schönen Fehlermeldung:
    "Item Test_GA1 already exists
    Item Test_GA1 already exists
    while executing
    "# Compiled -- no source code available
    error "called a copy of a compiled script""
    (procedure "vfnLoadObjectsInDebugger" line 1)
    invoked from within
    "# Compiled -- no source code available
    error "called a copy of a compiled script""
    (procedure "fnSetGetObjectValueAlert" line 1)
    invoked from within
    "fnSetGetObjectValueAlert"
    (menu invoke)
    "

    Da scheint noch ganz schön Arbeit drinnen zu stecken!

    Das ist schade, denn bei systematisch angelegten GAs könnte man sich bei den Makroparametern das Leben ganz schön erleichtern.

    Kommentar


      #3
      Zitat von klaus_kraemer Beitrag anzeigen
      Das ist schade, denn bei systematisch angelegten GAs könnte man sich bei den Makroparametern das Leben ganz schön erleichtern.
      Muss ich mir anschauen. Ich setzt das mal auf die Liste.
      offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
      Enertex Produkte kaufen

      Kommentar


        #4
        Zitat von enertegus Beitrag anzeigen
        Muss ich mir anschauen. Ich setzt das mal auf die Liste.
        Ich verdeutliche meiner langen Vorrede kurzen Sinn nochmal um meine simple Vorstellung:
        Laut Handbuch ist address() vom "Datentyp Gruppenadresse" - damit stelle ich mir vor, address() überall dort einstzen zu können, wo ich sonst eine GA in den Code schreibe.

        Kommentar


          #5
          Ist das zwischenzeitlich schon erledigt?

          Kommentar


            #6
            Zitat von klaus_kraemer Beitrag anzeigen
            Ist das zwischenzeitlich schon erledigt?
            Ja, oder nicht?
            offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
            Enertex Produkte kaufen

            Kommentar


              #7
              Na, dann werd' ich es dieser Tage mal testen...

              Kommentar


                #8
                Nun, es scheint noch nicht ganz zu funktionieren:

                Das Handbuch sagt zu Address:

                "Funktion address(variable)
                ....
                Wirkung
                ● Rückgabewert: eine Gruppenadresse, wie sie von write, readetc. verwendet werden kann.
                Datentyp Ergebnis (Rückgabe)
                ● Datentyp Gruppenadresse"

                Allerdings scheint dies nicht zu gelten, wenn Konstrukte wie (verkürzt dargestellt verwendet werden:

                [highlight=epc]
                GAaddress = getaddress(GA)

                if change(address(GAaddress)) then... endif
                oder
                if event(address(GAaddress)) then ... endif
                oder
                write(Andere GA, address(GAaddress))

                [/highlight]

                aktuell habe ich mit einem kleinen Makro zu testen versucht und die Funktionalität der Codeabschnitte kommentiert:

                [highlight=epc]
                /*---- Test address() / getaddress()*/
                :begin Testmakro(Name, pGAbasis)

                //Sinn des Makros: Der Wert der BasisGA pGAbasis soll auf die
                //unmittelbar folgende GA geschrieben werden, von beiden GAs
                //wird jeweils eine LED zur Konrolle angesteuert...

                Name_GA1 = getaddress(pGAbasis)
                Name_GA2 = Name_GA1 + 1u16
                Name_Zaehler = 0u16

                //funzt nicht:
                //if event(address(Name_GA1)) then {
                // write(address(Name_GA2),address(Name_GA1));
                // Name_Zaehler = Name_Zaehler+1u16;
                //} endif

                //funktioniert:
                if event("Test LED1-4/0/101") then {
                write(address(Name_GA2),"Test LED1-4/0/101");
                Name_Zaehler = Name_Zaehler+1u16;
                } endif

                //funktioniert nicht (Zähler zählt hoch, aber kein write auf "Name_GA2"
                //if event("Test LED1-4/0/101") then {
                // write(address(Name_GA2),address(Name_GA1));
                // Name_Zaehler = Name_Zaehler+1u16;
                //} endif

                :end
                [/highlight]

                Der zugehörige Code im Hauptprogramm ist:

                [highlight=epc]
                Testmakro(Test,"Test LED1-4/0/101")
                if pbutton(btnTestLED,pgID_testpage)==1 then {
                write("Test LED1-4/0/101",!"Test LED1-4/0/101");
                } endif
                [/highlight]

                Vielleicht testet Ihr das ja mal selbst, denn wenn eine Funktion vom Datentyp "Gruppenadresse" sein soll, dann sollte auch alles wie bei einer Gruppenadresse funktionieren, also auch event(), change(), Werte auslesen,...

                Kommentar


                  #9
                  Zitat von klaus_kraemer Beitrag anzeigen
                  Nun, es scheint noch nicht ganz zu funktionieren:
                  write(Andere GA, address(GAaddress))
                  Da liegt ein Misverständnis vor: address kann für die Argumente der write, event etc. Funktionen genutzt werden, wo die GA als Adresse genutzt wird,
                  also etwa
                  • write(address(GAaddress), Wert)
                  • read(address(GAaddress))
                  • eventread(address(GAaddress))

                  usw. Es heisst ja auch im Handbuch zur Definition:
                  write(Gruppenadresse, Wert)
                  Also kann address nur für das erste Argument genutzt werden. Das gilt für alle GA Funktionen.
                  Das Abfragen des Inhalts einer GA (deren Inhalt) ist wie folgt auf verschiedenen Wegen möglich.
                  GAImage: Den aktuellen Status einer GA im Speicherabbild des EibPC erfragen:
                  [highlight=epc]
                  y='0/1/0'u08
                  x=$$
                  z=AUS
                  if systemstart() then write('0/1/0'u08,87) endif
                  if z then x=convert(gaimage(getaddress('0/1/0'u08)),$$) endif
                  [/highlight]
                  wäre so möglich. Hier benötigt man aber immer einen Trigger durch "z", also einer if-Abfrage. Denn ein Ausdruck ohne if
                  [highlight=epc]
                  o=convert(gaimage(getaddress('0/1/0'u08)),$$)
                  [/highlight]
                  hängt nur von der konstanten Zahl "getaddress('0/1/0'u08)" ab (hier 256u16), sodass hier nie eine Auswertung angestossen wird.

                  Dann gibt es ReadKnx: Damit ist das hier möglich
                  [highlight=epc]
                  Wert=0
                  Nummer=0u16
                  Ausgabe=$$
                  if readknx(Nummer, Ausgabe) then {
                  if Nummer==getaddress('0/1/0'u08) then Wert=convert(Ausgabe,$$) endif
                  } endif
                  [/highlight]
                  Etwas umständlich für Deine Aufgabe, da ja readknx die GA-Nummer gleich mit auswertet und man eine zusätzliche if-braucht.
                  Dann wäre noch einfacher
                  [highlight=epc]
                  x3=$$
                  Nummer=0u16
                  Ausgabe=$$
                  if event(readknx(Nummer, Ausgabe)) then {
                  x3=convert(gaimage(getaddress('0/1/0'u08)),$$)
                  } endif
                  [/highlight]
                  offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                  Enertex Produkte kaufen

                  Kommentar


                    #10
                    Na, Deine Vorschläge muss ich mir erst mal zu Gemüte führen - in diesen Bereichen der EibPC Programmierung hab' ich mich noch nicht bewegt. Aber Danke erstmal, vielleicht komme ich damit hin.

                    Allerdings geht man beim Lesen eines Programmiermanuals eigentlich vom Typ des Rückgabewertes aus - und da steht "Gruppenadresse". Ein dezenter Hinweis darauf, dass diese "Gruppenadresse" nicht exakt wie eine Gruppenadresse verwendet werden kann, wäre wohl angebracht. Denn "write, read, etc". habe ich natürlich sehr weit interpretiert, besonders das "etc"...

                    Kommentar


                      #11
                      Zitat von klaus_kraemer Beitrag anzeigen
                      Allerdings geht man beim Lesen eines Programmiermanuals eigentlich vom Typ des Rückgabewertes aus - und da steht "Gruppenadresse". Ein dezenter Hinweis darauf, dass diese "Gruppenadresse" nicht exakt wie eine Gruppenadresse verwendet werden kann, wäre wohl angebracht. Denn "write, read, etc". habe ich natürlich sehr weit interpretiert, besonders das "etc"...
                      Vor über 6 Jahren, als wir die Syntax entwickelten - und sicher nicht auch nur annähernd den Funktionsumfang soweit vorraussahen - stand zu Diskussion, die Syntax hier genauer zu gestalten.
                      Da wäre um auf den Inhalt zu referenzieren eine Funktion "Inhalt" notwendig:
                      x=Inhalt("Meine-GA-1/2/3")
                      notwendig gewesen.
                      Dann wäre der Code dann eben:
                      if ... then write("Meine-GA-1/2/3",Inhalt("Meine-GA-1/2/3")) endif
                      Wir fanden jedoch die nun umgesetzte Syntax
                      x="Meine-GA-1/2/3"
                      bzw.
                      if ... then write("Meine-GA-1/2/3","Meine-GA-1/2/3") endif
                      letztlich schöner, weil kürzer. An Getaddress o.ä. haben wir nicht gedacht, gabs ja nicht. Im Grundsatz hast Du aber recht, dass wir bei "Meine-GA-1/2/3" einmal den Inhalt der GA und einmal die Adresse der GA meinen. Für den Einstieg erscheint mir diese Variante einfacher, daher wurde das so seinerzeit gemacht.
                      offizielles Supportforum für den Enertex® EibPC: https://knx-user-forum.de/eibpc/
                      Enertex Produkte kaufen

                      Kommentar


                        #12
                        Nun, das lässt ja noch auf die inhalt()-Variante hoffen.

                        Aber nachdem der Compiler ja bei der Variante "FbhPumpe-1/2/2" ja auch die richtigen Verweise setzen muss, sollte doch die Implementation einer Notation ga(adresseU16) auch nicht weit entfernt liegen, die dann äquivalent eingesetzt werden könnte. Ganz grob und schnell gedacht...

                        Kommentar


                          #13
                          Zitat von enertegus Beitrag anzeigen
                          Vor über 6 Jahren, als wir die Syntax entwickelten - und sicher nicht auch nur annähernd den Funktionsumfang soweit vorraussahen - stand zu Diskussion, die Syntax hier genauer zu gestalten.
                          Da wäre um auf den Inhalt zu referenzieren eine Funktion "Inhalt" notwendig:
                          x=Inhalt("Meine-GA-1/2/3")
                          notwendig gewesen.
                          Eigentlich nichts neues, trotzdem spannend zu lesen, dass über solche Dinge tatsächlich diskutiert wurde.

                          Schade finde ich, dass dann nicht konsequent die entsprechende Funktion auch implementiert wurde und die abkürzende Schreibweise dementsprechend beschrieben und auch so erklärt wird/würde! Derartige Optimierungen sind sicherlich nicht schlecht, wenn sie entsprechend verstanden werden.

                          Dann würde man z.B. auch Aussagen leichter(?) verstehen, wie "Funktionen mit konstanten Argumenten lösen keine Neuberechnung aus", denn GAs sind nun mal ursächlich Konstanten, oder?
                          BR
                          Marc

                          Kommentar

                          Lädt...
                          X