Ankündigung

Einklappen
Keine Ankündigung bisher.

eval überschreiben / userfunktion flexibler

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

    eval überschreiben / userfunktion flexibler

    Es gibt immer wieder Situationen, da möchte man ein Item, welches ein eval verwendet auch manuell überschreiben oder von der knx-Seite überschreiben lassen. Das geht aber leider nicht. Könnte man das nicht mal ändern? Ggf. auch mit einem entsprechenden Attribut. Denn so habe ich die Möglichkeit sowohl auf einen trigger zu reagieren, als auch knx-seitig ohne Hilfsitem, wenn was vom Bus kommt. Auch könnten sich zwei Items so gegenseitig triggern. Und nur wenn das Item schon von dem anderen getriggert wurde, würde dann der trigge rnicht ausgelöst werden.

    Code:
    Item1:
        knx_send: 0/0/1
        knx_listen: 0/1/1
        eval: uf.converter.AnachB(sh...Item1())
        eval_trigger: ..Item2
    
    Item2:
        eval: uf.converter.BnachA(sh...Item2())
        eval_trigger: ..Item1
    Ich könnte jetzt den Wert von KNX in Item1 empfangen und auch senden. Gleichzeitig wird der umgewandelte Wert in Item2 angezeigt und ich könnte beispielsweise mit der SmartVISU Item2 verändern und diesen umgewandelt über Item1 auf den Bus senden.

    Eine Alternative oder andere Option wäre die Userfunktion auch woanders einzusetzen:

    Code:
    Item:
        knx_send: 0/0/1
        knx_listen: 0/1/1
        knx_send_value: uf.converter.AnachB(value)
    So könnte man beispielsweise Werte vor und nach dem Bus umwandeln.

    P.S.: Ich habe bewusst ein paar Punkt ebei den Items weggelassen. Es ist nur sinnbildlich.

    #2
    Hmm. du kannst ja value if sh..self.properts.last_change_by = bla else bla nutzen oder hab ich die Frage falsch verstanden?

    Kommentar


      #3
      Zitat von Onkelandy Beitrag anzeigen
      hab ich die Frage falsch verstanden?
      1. Ich möchte gern ein Item direkt beschreiben, welches auch mit eval/eval_trigger arbeitet. eval soll halt nur ausgeführt werden, wenn es über den eval_trigger kommt.

      2. Der Typ des Items muss nicht zwangsmäßig mit dem knx-Item-Typ übereinstimmen. Das heißt ein Typumwandler käme da zum Zuge.

      Wäre sowas möglich?

      Kommentar


        #4
        Stehe bei der Fragestellung auch ein wenig auf dem Schlauch. Fall's ich's richtig verstanden habe:
        Ich hab's jetzt nicht ausprobiert, aber sowas hier sollte doch gehen, oder?

        Code:
        eval_item:
            type: bla
            eval: sh.irgendwas()
            eval_trigger: irgendwas
        
        irgendein_visu_slider:
            type: blubb
            on_change: eval_item(typumwandlung(value))
        eval_item bekommt seine Werte per eval vom Item 'irgendwas', oder alternativ von Hand über die Visu. Das ist es doch, was Du willst, oder?

        /tom
        Zuletzt geändert von Tom Bombadil; 04.03.2022, 14:00.

        Kommentar


          #5
          Zitat von Tom Bombadil Tom Bombadil Beitrag anzeigen
          eval_item bekommt seine Werte per eval vom Item 'irgendwas', oder alternativ von Hand über die Visu. Das ist es doch, was Du willst, oder?
          Im Prinzip ja, leichter wäre jedoch der direkt Weg, also den Slider einfach auf eval_item zu schreiben. Da könnte man dann ja noch ein Attribut festlegen, was eval nur im Falle von eval_trigger auslöst.

          Kommentar


            #6
            Zitat von Cannon Beitrag anzeigen
            eval nur im Falle von eval_trigger auslöst
            Ömmm - eval löst doch sowieso nur im Fall von eval_trigger aus (je nach Konfiguration von enforce_updates entweder immer oder nur nach Änderung)? Also was hindert Dich daran, den Slider direkt zu verbinden? Ich hatte die Fragestellung so verstanden, dass Du explizit ein *weiteres* Item haben willst ....
            /tom
            Zuletzt geändert von Tom Bombadil; 05.03.2022, 19:50.

            Kommentar


              #7
              Nein, eval wird immer ausgeführt siehe erste Beispiel in der Doku

              Kommentar


                #8
                Zitat von stoepf Beitrag anzeigen
                Nein, eval wird immer ausgeführt siehe erste Beispiel in der Doku
                Ich glaube, wir reden da aneinander vorbei - ich meinte ein eval-Statement, das per eval_trigger mit einem anderen Item verbunden ist. Je nachdem, ob in dem anderen Item enforce_updates gesetzt ist, wird eval_trigger und damit das eval bei jedem Update des anderen Items ausgelöst, oder nur bei einem Change.

                /tom

                Edit / Nachtrag zum Verständnis:

                Bis damals on_update/on_change aufgrund einer fixen Idee von mir implementiert wurden, war eval die einzige Möglichkeit, Items miteinander zu verbinden. Das Verhalten war und ist (vereinfacht beschrieben) wie folgt:

                Variante 1:
                Code:
                item1:
                    type: irgendwas
                    knx_gedöns: gesetzt
                
                    item1a:
                        type: irgendwas
                        eval: mach_was    // wird NUR ausgelöst, wenn Wert von item1 sich tatsächlich ÄNDERT
                        eval_trigger: ..
                Variante2:
                Code:
                item1:
                    type: irgendwas
                    knx_gedöns: gesetzt
                    enforce_updates: true // <-------------------- DAS DA
                
                    item1a:
                        type: irgendwas
                        eval: mach_was    // wird bei JEDEM UPDATE von item1 ausgelöst, auch ohne Wertänderung (z.B. bei zyklischen Abfragen)
                        eval_trigger: ..
                Das Verhalten von enforce_updates ist hier in der Doku beschrieben.

                Für das 'ganze Bild' muss man noch sagen, dass [items] damals auch noch anders geschrieben wurden, und auch die relative Adressierung noch nicht bzw. nur rudimentär implementiert war (daher sehen einige Beispiele aus damaliger Zeit aus heutiger Sicht etwas komisch aus). Aber das ist eine andere Geschichte ...
                Zuletzt geändert von Tom Bombadil; 05.03.2022, 23:47.

                Kommentar


                  #9
                  Zitat von Tom Bombadil Tom Bombadil Beitrag anzeigen
                  Ömmm - eval löst doch sowieso nur im Fall von eval_trigger aus (je nach Konfiguration von enforce_updates entweder immer oder nur nach Änderung)? Also was hindert Dich daran, den Slider direkt zu verbinden? Ich hatte die Fragestellung so verstanden, dass Du explizit ein *weiteres* Item haben willst ....
                  eval wird immer ausgelöst, nicht nur über eval_trigger, dass ist ja das Problem. Ich kann ein Item, welches mit einem eval-Statement arbeitet, keinen direkten Wert zuweisen. Z.B.:

                  Code:
                  Item1:
                      type: bool
                      eval: True if sh.Item2() = 2 else False
                      eval_trigger: Item2
                  
                  Item2:
                      type: num
                  Wenn ich jetzt Item1 direkt anbinden will bzw. den Wert True oder False setzen will geht das nicht, weil immer Item2 ausgewertet wird. Aber es gibt viele Situation, wo man das gar nicht will. Und da wäre es vielleicht sinnvoll statt eval eben ein anderes Attribut zu verwenden, was nur dann abgefragt wird, wenn es wiklich über den Trigger kommt.

                  Kommentar


                    #10
                    Zitat von Cannon Beitrag anzeigen
                    eval wird immer ausgelöst, nicht nur über eval_trigger
                    Nochmal: Das stimmt nicht, oder mit enforce_updates oder eval_trigger ist neuerdings was kaputt. Siehe die beiden Beispiele oben.

                    Zitat von Cannon Beitrag anzeigen
                    Wenn ich jetzt Item1 direkt anbinden will bzw. den Wert True oder False setzen will geht das nicht, weil immer Item2 ausgewertet wird.
                    Das ist nur der Fall, wenn sich item2 tatsächlich ändert, da enforce_updates dort nicht gesetzt ist. Und das ist dann vermutlich auch so gewollt. Es hindert Dich aber nicht daran, item1 z.B. in der Visu trotzdem auf einen Switch zu legen, um es unabhängig von item2 zu schalten.

                    Will ich, dass nach manueller Betätigung nicht mehr von item 2 geerbt wird (auch nicht bei Wertänderungen), muss ich halt zusätzlich mit einem Sperritem arbeiten (z.B. mit on_update aus item 1 unter Auswertung von sh..self.properts.last_change_by, wie oben von Onkelandy schon vorgeschlagen). Das Sperritem muss dann ggf. per Logik oder von Hand wieder aufgehoben werden, wenn wieder Automatikbetrieb gewünscht ist.

                    Ich sehe in Bezug auf den OP jetzt jedenfalls keinen Punkt, der sich aktuell nicht über ein weggelassenes enforce_updates (z.B. manuelles Überreiten per Visu oder Steuerung per Logik) oder ein on_update aus einem externen KNX-Item realisieren ließe:

                    Zitat von Cannon Beitrag anzeigen
                    Es gibt immer wieder Situationen, da möchte man ein Item, welches ein eval verwendet auch manuell überschreiben oder von der knx-Seite überschreiben lassen.
                    Oder ich bin einfach zu doof, das zu verstehen - ich klinke mich daher jetzt hier mal raus und werde stiller Mitleser ...

                    /tom
                    Zuletzt geändert von Tom Bombadil; 06.03.2022, 00:26.

                    Kommentar


                      #11
                      Zitat von Tom Bombadil Onkelandy Tom Bombadil Beitrag anzeigen
                      Das stimmt nicht, oder mit enforce_updates oder eval_trigger ist neuerdings was kaputt. Siehe die beiden Beispiele oben.
                      Aber das ist genau das, was ich meine: Es ist nicht so. Kannst du ja selbst mal testen:

                      Code:
                      Test:
                          eItem1:
                              type: bool
                              eval: True if sh.Test.eItem2() == 2 else False
                              eval_trigger: Test.eItem2
                      
                          eItem2:
                              type: num
                      Du kannst eItem1 NICHT direkt ändern, kann man ja auch im Admin-Interface testen. Solange eItem2 nicht 2 ist, kriegst du eItem1 auch manuell nicht auf True gesetzt.

                      Und genau hier würde ich mir eine Änderung wünschen, sodass man das eben machen kann.

                      Kommentar


                        #12
                        Sorry Tom, da haben wir in der Tat aneinander vorbeigeredet.

                        Wäre das nicht mit on_change zu lösen?
                        Die eval-Syntax gibt das mit dem Item nicht her, oder doch?

                        Code:
                        Test:
                            eItemA:
                                type: bool
                                on_change: ..eItemB = deineuserfunctionAB(value)
                        
                            eItemB:
                                type: num
                                on_change: ..eItemA = deineuserfunctionBA(value)
                        Mit on_update baut man sich eine Endlosschleife bzw. wenn die Umrechnungen nicht genau passen.
                        Zuletzt geändert von stoepf; 06.03.2022, 12:28. Grund: Hinweis auf Endlosschleife eingefügt

                        Kommentar


                          #13
                          Zitat von Cannon Beitrag anzeigen
                          Aber das ist genau das, was ich meine: Es ist nicht so. Kannst du ja selbst mal testen:
                          [...]
                          Du kannst eItem1 NICHT direkt ändern, kann man ja auch im Admin-Interface testen. Solange eItem2 nicht 2 ist, kriegst du eItem1 auch manuell nicht auf True gesetzt.
                          Und genau hier würde ich mir eine Änderung wünschen, sodass man das eben machen kann.
                          Uff, wenn das mittlerweile tatsächlich so ist, nehme ich alles zurück und behaupte das Gegenteil. Ich bin der Meinung, genau diese Konstellation in der Vergangenheit etliche Male verwendet zu haben, u.a. z.B. in der Abbruchfunktion für die Stoßlüftung meiner KWL (die ich aber schon ewig nicht mehr benutzt habe, deshalb ist es mir vielleicht nicht aufgefallen).

                          Wenn sich das Verhalten geändert hat, ist das auch für mich unlogisch. eval darf IMHO nur ausgeführt werden, wenn es 'getriggert' wird, und nicht bei jeder beliebigen Wertzuweisung - deshalb heisst das Ding ja schließlich 'eval_trigger'. Zeit für ein Ticket, denke ich ...

                          /tom

                          Kommentar


                            #14
                            Zitat von Tom Bombadil Beitrag anzeigen
                            Uff, wenn das mittlerweile tatsächlich so ist, nehme ich alles zurück und behaupte das Gegenteil. Ich bin der Meinung, genau diese Konstellation in der Vergangenheit etliche Male verwendet zu haben, u.a. z.B. in der Abbruchfunktion für die Stoßlüftung meiner KWL (die ich aber schon ewig nicht mehr benutzt habe, deshalb ist es mir vielleicht nicht aufgefallen).

                            Wenn sich das Verhalten geändert hat, ist das auch für mich unlogisch. eval darf IMHO nur ausgeführt werden, wenn es 'getriggert' wird, und nicht bei jeder beliebigen Wertzuweisung - deshalb heisst das Ding ja schließlich 'eval_trigger'. Zeit für ein Ticket, denke ich ...
                            Das war schon immer so meine ich, deshalb würde ich das optional ändern. Denn aktuell ist eval nichts anderes als eine Typumwandlung und hat mit dem trigger erst mal nichts zu tun... siehe Doku:

                            Wird einem Item ein neuer Wert zugewiesen, wird dieser erst einmal als value zwischengespeichert. Ist ein eval vorhanden, wird dies erst ausgeführt, bevor dem Item der Wert final zugewiesen wird. Das kann man sich für Nachbearbeitungen zu nutze machen, bspw. wenn der zugewiesene Wert zu viele Nachkommastellen hat. In folgenden Beispiel wird auf eine Nachkommastelle gerundet.
                            Quelle

                            Das wirkt zwar so, dass das zusammengehört, auch in der Doku. Aber für mein Verständnis sind das völlig unterschiedliche Attribute, die nichts miteinander zu tun haben.

                            Kommentar


                              #15
                              Zitat von stoepf stoepf Beitrag anzeigen
                              Wäre das nicht mit on_change zu lösen?
                              Die eval-Syntax gibt das mit dem Item nicht her, oder doch?
                              Es gibt ja viele Wege das irgendwie zu lösen und ich arbeite auch viel mit on_update und on_change, finde das aber nicht so elegant, da die Übersicht verloren geht. Der Vorteil von eval_trigger ist, dass ich immer genau weiß, wo meine Werte in dem Item kommen. Bei on_change, kann die "Quelle" irgendwo ganz anders liegen und man kann irgendwann schwer nachvollziehen von wo das Item geändert wurde.

                              Und das Ganze ist nur beispielhaft mit 2 Items gelköst wurde. Der der Ansatz ist ja folgender gewesen und jetzt mache ich mal ein richtiges Beispiel:

                              Code:
                              Item_RGB:
                                  knx_send: 0/0/1
                                  knx_listen: 0/1/1
                                  eval: uf.converter.HSVnachRGB(sh...Item_HSV())
                                  eval_trigger: ..ItemHSV
                              
                              Item_HSV:
                                  eval: uf.converter.RGBnachHSV(sh...Item_RGB())
                                  eval_trigger: ..Item_RGB
                              Ich könnte jetzt (aktuell geht das so nicht) mittels RGB-Regler Item_RGB ändern und mittels HSV-Regeler Item_HSV. Beide Items wären immer synchron. Mein KNX-System unterstützt jedoch nur RGB, deshalb wird es da auch geschrieben und kann auch gelesen werden.

                              Kommentar

                              Lädt...
                              X