Ankündigung

Einklappen
Keine Ankündigung bisher.

Grundsatzfrage zum Bau eines eigenen Widgets

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

    Grundsatzfrage zum Bau eines eigenen Widgets

    Hi,

    nachdem ich meine Config nun mit fast allen Standard Widgets ausgereizt habe, möchte ich die restlichen Wünsche mit einen Plugin schließen
    Ich habe dies vor 6 JAhren schon mal gemacht, nur hat sich der Unterbau der CV mittlerweile so weit verändert, dass ich mich nur schwer zurechtfinde.

    Ich habe folgendes Setup gewählt.
    - altes Wiregate zum Testen
    - von git den Develop strang gezogen und mit
    Code:
    ./generate.py source
    die source gebaut

    Ich habe gesehen das ich damit ein Verzeichnis "source" schaffe, welches die eigentliche CV enthält. (Was genau in diesem ganzen Build abgeht verstehe ich überhaupt nicht).

    Soweit lief die CV und ich habe sie unter wiregatexxx/visu/source aufgerufen.

    Nun habe ich eine kleine Config gebastelt:

    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" lib_version="8" design="pure" xsi:noNamespaceSchemaLocation="../visu_config.xsd" max_mobile_screen_width="480">
        <meta>
            <files>
                <file type="js" content="plugin">resource/config/structure_custom.js</file>
                ...
            </files>
            <mappings>
                <mapping name="Close_Open">
                    <entry value="0">zu</entry>
                    <entry value="1">offen</entry>
                </mapping>
            </mappings>
            <statusbar>
                <status type="html"><![CDATA[
              <img src="resource/icon/comet_64_ff8000.png" alt="CometVisu" /> by <a href="https://www.cometvisu.org/">CometVisu.org</a>
              - <a href="manager.php">Config-Manager</a>
              - <a href=".?config=demo&forceReload=true">Reload</a>
              - <a href=".">Default Config</a>
            ]]></status>
                <status type="html" condition="!edit" hrefextend="config"><![CDATA[
              - <a href="editor/">Edit</a>
            ]]></status>
                <status type="html" hrefextend="config"><![CDATA[
              - <a href="check_config.php">Check Config</a>
              <div style="float:right;padding-right:0.5em">Version: 0.11.0-dev</div>
            ]]></status>
            </statusbar>
        </meta>
        <page name="CometVisu Widget Demo">
            <custom>
                <headline>Mein neues Widget!</headline>
            </custom>
            <switch mapping="Close_Open" styling="GreyGrey" align="center">
                <layout colspan="4"/>
                <label>Testswitch</label>
                <address transform="DPT:1.001" mode="readwrite">2/2/3</address>
            </switch>
        </page>
    </pages>
    Dazu passend aus der Doku die structure_custom.js:

    Code:
    /*
    
    qx.Class.define('cv.ui.structure.pure.Headline', {
      extend: cv.ui.structure.AbstractWidget,
    
      statics: {
        // parse element from visu_config*.xml
        parse: function (xml, path, flavour, pageType) {
          var data = cv.parser.WidgetParser.parseElement(this, xml, path, flavour, pageType);
          data.content = xml.textContent;
          return data;
        }
      },
    
      properties: {
        content: {
          check: 'String',
            init: ''
        }
      },
    
      members: {
        // generate the DOM string to be added to the GUI
        getDomString: function () {
          return '<h1 ' + (this.getClasses() ? 'class="'+this.getClasses()+'"' : '') + '>' + this.getContent() + '</h1>';
        }
      },
    
      // this function is executed when this file is loaded
      defer: function(statics) {
        // register the parser
        cv.parser.WidgetParser.addHandler("headline", cv.ui.structure.pure.Headline);
        // register the widget
        cv.ui.structure.WidgetFactory.registerClass("headline", statics);
      }
    });
    Leider funktioniert dies nicht :

    plugin_v1.png

    An der Stelle versuche ich mit Chromium gerade durch debuging schlauer zu werden.

    1.Frage:
    Ich konnte die switch.js im Debuger finden, habe einen Breakpoint gesetzt und beim Reload wurde dort auch gehalten. Passt
    plugin_v2.png

    Dann habe ich nach meiner "structure_custom.js" gesucht.

    plugin_v3.png
    Irgendwie wurde die Datei bearbeitet und komplett auskommentiert, wodurch auch keine Breakpoint etc funktionieren....

    Kann mir jemand diesen Mechanismus erklären?

    2.Frage

    Was ist sinnvoller zum Start. Das Plugin oder kann ich auch einfach eine Datei switch_new.js unter source/class/cv/ui/structure/pure erstellen und dann das switch_new Widget benutzen? Muss ich jedes mal "./generate.py source" aufrufen?


    Irgendwie hänge ich da fest, danke für etwas Starthilfe!

    Gruß

    Matthias




    #2
    Zitat von mw2000 Beitrag anzeigen
    (Was genau in diesem ganzen Build abgeht verstehe ich überhaupt nicht).
    Ich auch nicht... Aber Fragen dazu kann peuter beantworten
    Zitat von mw2000 Beitrag anzeigen

    Dazu passend aus der Doku die structure_custom.js:

    Code:
    /*
    
    qx.Class.define('cv.ui.structure.pure.Headline', {
    extend: cv.ui.structure.AbstractWidget,
    
    [...]
    Leider funktioniert dies nicht :
    Nun, dein geposteter Code fängt mit einem "/*" an - also hast Du alles auskommentiert...

    TS2, B.IQ, DALI, WireGate für 1wire so wie Server für Logik und als KNX Visu die CometVisu auf HomeCockpit Minor. - Bitte keine PNs, Fragen gehören in das Forum, damit jeder was von den Antworten hat!

    Kommentar


      #3
      Zitat von mw2000 Beitrag anzeigen
      Ich habe gesehen das ich damit ein Verzeichnis "source" schaffe, welches die eigentliche CV enthält. (Was genau in diesem ganzen Build abgeht verstehe ich überhaupt nicht).
      Das "source" Verzeichnis gab es vorher auch schon, das wird nicht beim Generieren erzeugt. Das Verzeichnis "source/script" hingegen schon. Beim Generieren passiert ein ganze Menge, aber das wichtigste ist, dass dadurch der Quellcode analysiert wird und Abhängigkeiten erkannt werden. Außerdem werden alle benötigten "nicht Quellcode"-Dateien wie Übersetzungen und alle Dateien unter "source/resource" eingelesen und dafür ein Index angelegt. Für das alles zusammen wird eine Datei erzeugt (in source/script) die dafür sorgte, dass die Source-Version der CometVisu im Browser geladen werden kann.

      Man muss also nur neu generieren, wenn neue Dateien hinzugefügt wurden, um sicherzustellen, dass diese auch geladen werden. Wenn man die Dateien aber über den Files-Bereich der Config lädt, braucht man das nicht, denn dann ist auf diesem Wege ja sichergestellt, dass die Datei geladen wird. Im Detail ist das alles deutlich komplexer als hier beschreiben, aber das sollte als Erklärung reichen:

      Möchte man ein einfaches Plugin schreiben, welches über meta->files->file in die Config eingetragen wird. Muss man einmal initial "./generate.py source" ausführen, danach nie wieder (außer man aktualisiert seine Version mit "git pull" und es sind darüber neue Dateien rein gekommen). Noch ein allgemeiner Hinweis "generate.py source" ändert den Inhalt der Source-Dateien nicht.


      Zitat von mw2000 Beitrag anzeigen
      2.Frage

      Was ist sinnvoller zum Start. Das Plugin oder kann ich auch einfach eine Datei switch_new.js unter source/class/cv/ui/structure/pure erstellen und dann das switch_new Widget benutzen?
      Der einfachste Weg zum Einstieg sind die "Eigenständigen Plugins", wie sie hier beschrieben sind: https://www.cometvisu.org/CometVisu/...n-uber-plugins
      Also genau dass was Du bereits versucht hast.

      Einfach irgendwo eine Datei erzeugen wird nichts bringen, solange diese Datei, bzw die Klasse, die in der Datei definiert ist, nirgendwo benutzt wird, kannst Du so oft generieren wie Du möchtest, sie wird trotzdem nicht geladen.

      Zitat von mw2000 Beitrag anzeigen
      Muss ich jedes mal "./generate.py source" aufrufen?
      Hab ich oben schon beantwortet => nein


      Gruß
      Tobias

      Kommentar


        #4
        Danke für die Erläuterungen. Habe meinen Fehler eben gefunden.

        Es war ein trivialer Fehler in meinem Upload script zum Wiregate. Die js Datei konnte nicht übertragen werden, aber dort lag auch schon euer structure_custom.js Beispiel, identisch mit meiner Datei, aber auskommentiert

        Dann versuche ich mich jetzt mal weiter!

        Kommentar


          #5
          Noch eine Frage zum Debugging:

          Ich nutzte Chromium und dass mit den Breakpoints funktioniert bei der switch.js super. Leider schaffe ich dies nicht bei der structure_custom.js. Was mir dabei auffiel, das die structure_custom.js bei jedem reload eine neue Ziffer angehangen bekommt und damit der Breakpoint nicht getroffen wird.

          Code:
          source/resource/config/structure_custom.js?1547924702838
          Kann man dies irgendwie unterbinden oder gibt es andere Möglichkeiten den Breakpoint zu setzen?

          Kommentar


            #6
            Da gibt es zwei Möglichkeiten: Zum einen kannst Du in den Source-Code deiner Datei an die Stelle an der der Debugger anhalten soll einfach "debugger;" in den Code schreiben. Das ist natürlich relativ unflexibel, weil man immer den Code ändern muss. Daher besser: Das hier auf "false" ändern: https://github.com/CometVisu/CometVi...Config.js#L324
            Dann sollte die angehängte Zahl aus der URL verschwinden und Du kannst die Breakpoints ganz normal setzen.
            Gruß
            Tobias

            Kommentar


              #7
              Dankeschoen

              Kommentar


                #8
                Hallo zusammen,

                nachdem ich nun 2 Tage an meinem Widget herumbastele bin ich in einer Sackgasse gelandet. Vielleicht könnt Ihr mir kurz einen Hinweis geben wo ich sichen möchte.


                Ziel des Widget:

                Es soll eine kompakter Jalousieaktor für eine 2d Page werdender folgendes kann:

                GA-Adressen:
                - short Touch GA für stop (write)
                - long Touch GA für auf/ab (write)
                - Positionswert Rolladen (read)
                - Rolladen ganz oben (read)
                - Rolladen ganz unten (read)

                Gesteuert über 2 "Taster" sowie die Anzeige der Position, wenn der Rolladen nicht ganz offen/zu ist. Vor ein paar Jahren hatte ich das schon mal so aufgesetzt...

                Jalousie_ALT.png

                Jetzt habe ich auf Basis des Multitrigger/infotrigger Widget mal folgendes Plugin gebaut!
                Code:
                /*
                 * Widget zur Jalousiesteuerung
                 */
                
                qx.Class.define('cv.ui.structure.pure.Switch_jal', {
                    extend: cv.ui.structure.AbstractWidget,
                    include: [
                        cv.ui.common.Operate,
                        cv.ui.common.Update,
                        cv.ui.common.HasAnimatedButton,
                        cv.ui.common.HandleLongpress
                    ],
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // Beginn Parser File
                    //
                    // die folgenden Funktionen sind bei Widgets in einem separatem Parserfile
                    // abgelegt
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                
                    statics: {
                        // parse element from visu_config*.xml
                        parse: function (xml, path, flavour, pageType) {
                            var data = cv.parser.WidgetParser.parseElement(this, xml, path, flavour, pageType, this.getAttributeToPropertyMappings());
                            cv.parser.WidgetParser.parseFormat(xml, path);
                            cv.parser.WidgetParser.parseAddress(xml, path, this.makeAddressListFn);
                            return data;
                        },
                        getAttributeToPropertyMappings: function () {
                            return {
                                'downvalue': {target: 'downValue', transform: parseFloat, "default": 0},
                                'shortdownvalue': {target: 'shortDownValue', transform: parseFloat, "default": 0},
                                'upvalue': {target: 'upValue', transform: parseFloat, "default": 1},
                                'shortupvalue': {target: 'shortUpValue', transform: parseFloat, "default": 1},
                                'shorttime': {target: 'shortThreshold', transform: parseFloat, "default": 500},
                                'infoposition': {
                                    target: 'infoPosition',
                                    "default": 'middle',
                                    transform: function (value) {
                                        return ['middle', 'right'].includes(value) ? value : 'left';
                                    }
                                }
                            };
                        },
                        makeAddressListFn: function (src, transform, mode, variant) {
                            // Aufbereitung der Funktion der jeweiligen Gruppenaddresse
                            var addrFunction;
                            switch (variant) {
                                case 'short':
                                    addrFunction = 1;
                                    break;
                                case 'long':
                                    addrFunction = 2;
                                    break;
                                default:
                                    addrFunction = 3;
                                    break;
                            }
                            return [true, addrFunction];
                
                        }},
                    // this function is executed when this file is loaded
                    defer: function (statics) {
                        // register the parser
                        cv.parser.WidgetParser.addHandler("switch_jal", statics);
                        // register the widget
                        cv.ui.structure.WidgetFactory.registerClass("switch_jal", statics);
                    },
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    // Ende Parser file
                    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                
                
                    // Properties die man dem Widget in der Config mitgeben kann
                    properties: {
                        'downValue': {
                            check: "Number",
                            init: 0
                        },
                        'shortDownValue': {
                            check: "Number",
                            init: 0
                        },
                        'upValue': {
                            check: "Number",
                            init: 1
                        },
                        'shortUpValue': {
                            check: "Number",
                            init: 1
                        },
                        'shorttime': {
                            check: "Number",
                            init: 500
                        },
                        'infoPosition': {
                            check: ["left", "middle", "right"],
                            init: 'middle'
                        }
                    },
                    // Funktionen die diese Widget Klasse zur verfügung stellt
                    members: {
                        // overridden
                        _getInnerDomString: function () {
                            // create the actor
                            var ret_val = '<div class="actor_container" style="float:left">';
                
                
                            //Trigger 1 für Verfahren der Jalousie nach unten
                            var actordown = '<div class="actor switchUnpressed actor_jal_down actor_jal">';
                            actordown += '<div class="value">' + "-" + '</div>';
                            actordown += '</div>';
                
                            //Info für den Jalousie Verfahrweg
                            //var actorinfo = '<div class="info"  style="text-align: center" >';
                            var actorinfo = '<div class="value" style="float:left; margin: 4px 1px;" >' + '15%' + '</div>';
                            //actorinfo += '</div>';
                
                            //Trigger 2 für Verfahren der Jalousie nach oben
                            var actorup = '<div class="actor switchUnpressed actor_jal_up actor_jal">';
                            actorup += '<div class="value">' + "-" + '</div>';
                            actorup += '</div>';
                
                            //Auswahl der Info Position
                            switch (this.getInfoPosition()) {
                                case 'middle':
                                    ret_val += actordown;
                                    ret_val += actorinfo;
                                    ret_val += actorup;
                                    break;
                                case 'right':
                                    ret_val += actordown;
                                    ret_val += actorup;
                                    ret_val += actorinfo;
                                    break;
                                default:
                                    ret_val += actorinfo;
                                    ret_val += actordown;
                                    ret_val += actorup;
                                    break;
                            }
                            return ret_val + '</div>';
                        },
                        // Hilffunktion listet alle Actoren auf
                        getActors: function () {
                            var tmp = qx.bom.Selector.query(".actor", this.getDomElement());
                            return qx.bom.Selector.query(".actor", this.getDomElement());
                        },
                        // overridden
                        initListeners: function () {
                            var tmp = this.getActors();
                            this.getActors().forEach(function (actor) {
                                qx.bom.element.Dataset.set(actor, "longtapable", true);
                                if (this.getShortThreshold() > 0) {
                                    qx.event.Registration.addListener(actor, "tap", this.action, this);
                                    qx.event.Registration.addListener(actor, "longtap", this._onLongTap, this);
                                } else {
                                    // no short tap treat all taps as long
                                    qx.event.Registration.addListener(actor, "tap", this._onLongTap, this);
                                    qx.event.Registration.addListener(actor, "longtap", this._onLongTap, this);
                                }
                                qx.event.Registration.addListener(actor, "pointerdown", this._onPointerDown, this);
                            }, this);
                
                        },
                        // Aktion die bei langem Tastendruck ausgeführt wird
                        _onLongTap: function (event) {
                            this.__action(false, qx.bom.element.Class.has(event.getCurrentTarget(), 'actor_jal_down'));
                        },
                        // Aktion die bei kurzem Tastendruck ausgeführt wird
                        _action: function (event) {
                            this.__action(true, qx.bom.element.Class.has(event.getCurrentTarget(), 'actor_jal_down'));
                        },
                        // generische Aktion die in Abhängigkeit der Länge des
                        // Tastendrucks auszuführen ist
                        __action: function (isShort, isDown) {
                            var value;
                            if (isShort) {
                                // wenn ein kurzer Tastendruck ausgeführt wird
                                value = isDown ? this.getShortDownValue() : this.getShortUpValue();
                            } else {
                                // Wenn ein langer Tastendruck ausgeführt wird
                                value = isDown ? this.getDownValue() : this.getUpValue();
                            }
                
                            // Berechnung der Bitmaske für short/long
                            var bitMask = (isShort ? 1 : 2);
                
                            var list = this.getAddress();
                            for (var id in list) {
                                if (list.hasOwnProperty(id)) {
                                    var address = list[id];
                                    //kurzer Testendruck
                                    if ((address[2] === 1) && (isShort)) {
                                        this.sendToBackend(value, function (address)
                                        {
                                            return !!(address[2] === 1);
                                        });
                                    }
                                    //langer Tastendruck
                                    if ((address[2] === 2) && (!isShort)) {
                                        this.sendToBackend(value, function (address)
                                        {
                                            return !!(address[2] === 2);
                                        });
                                    }
                                }
                            }
                        },
                        getDownActor: function () {
                            return qx.bom.Selector.query(".actor .actor_jal_down", this.getDomElement())[0];
                        },
                        getUpActor: function () {
                            return qx.bom.Selector.query(".actor .actor_jal_up", this.getDomElement())[0];
                        },
                        getInfoActor: function () {
                            return qx.bom.Selector.query(".actor.switchInvisible", this.getDomElement())[0];
                        },
                        
                    }
                
                });
                Die Config dazu
                Code:
                <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
                <pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" lib_version="8" design="pure" xsi:noNamespaceSchemaLocation="../visu_config.xsd" max_mobile_screen_width="480">
                    <meta>
                        <files>
                            <file type="js" content="plugin">resource/config/structure_custom.js</file>
                            <file type="js" content="plugin">resource/config/structure_custom_jal.js</file>
                        </files>
                        <mappings>
                            <mapping name="Close_Open">
                                <entry value="0">zu</entry>
                                <entry value="1">offen</entry>
                            </mapping>
                            <mapping name="Light_Std">
                                <entry value="0">
                                    <icon name="light_light_dim_00" color="grey"/>
                                </entry>
                                <entry value="1">
                                    <icon name="light_light_dim_100" color="white"/>
                                </entry>
                            </mapping>
                        </mappings>
                        <statusbar>
                            <status type="html"><![CDATA[
                          <img src="resource/icon/comet_64_ff8000.png" alt="CometVisu" /> by <a href="https://www.cometvisu.org/">CometVisu.org</a>
                          - <a href="manager.php">Config-Manager</a>
                          - <a href=".?config=demo&forceReload=true">Reload</a>
                          - <a href=".">Default Config</a>
                        ]]></status>
                            <status type="html" condition="!edit" hrefextend="config"><![CDATA[
                          - <a href="editor/">Edit</a>
                        ]]></status>
                            <status type="html" hrefextend="config"><![CDATA[
                          - <a href="check_config.php">Check Config</a>
                          <div style="float:right;padding-right:0.5em">Version: 0.11.0-dev</div>
                        ]]></status>
                        </statusbar>
                    </meta>
                    <page name="CometVisu PlugIn Develop" type="text" >
                        <group>
                            
                            <layout colspan="12"/>
                            <custom>
                                <headline>Mein neues Widget!</headline>
                            </custom>
                            <custom>
                                <switch_jal mapping="Light_Std" styling="GreyGrey" align="center" infoPosition="middle">            
                                    <layout colspan="12"/>
                                    <label>Jalousie-Switch</label>
                                    <address transform="DPT:1.001" mode="readwrite" variant="short" >2/2/3</address>
                                    <address transform="DPT:1.001" mode="readwrite"  variant="long" >2/2/2</address>
                                </switch_jal>
                            </custom>
                            <switch mapping="Light_Std" styling="GreyGrey" align="center">
                                <layout colspan="4"/>
                                <label>Testswitch</label>
                                <address transform="DPT:1.001" mode="readwrite">2/2/3</address>
                            </switch>
                            <infotrigger uplabel="-" upvalue="0" downlabel="+" downvalue="1" align="center" infoposition="middle" change="relative">
                                <layout colspan="12"/>
                                <label>Lautstärke:</label>
                                <address transform="DPT:1.001" mode="readwrite">2/2/2</address>
                                <address transform="DPT:1.001" mode="readwrite">2/2/3</address>
                        
                            </infotrigger>
                            <multitrigger mapping="Light_Std" button1label="HDMI1" button1value="0" button2label="HDMI2" button2value="1" button3label="VGA" button3value="2" button4label="-">
                                <layout colspan="6"/>
                                <label>Eingangsquelle</label>
                                <address transform="DPT:5.001" mode="readwrite">9/6/1</address>
                            </multitrigger>
                        </group>
                    </page>
                </pages>
                Aktuell kann das Widget schon 2 Adressen einlesen und diese in Abhängigkeit von short/long Pressed einen Wert senden.

                Jalousie_aktuell.png

                Auf dem ersten Aktor wird auch das Mapping schon korrekt angewendet, auf dem zweiten nicht.

                Nun meine Fragen:

                - Wie funktioniert des Mapping? Ich möchte jeweils ein Icon auf den Trigger, welches das in Abhängigkeit Read Werte (Auf/zu) gefärbt wird.
                - Wie funktioniert das Updaten der Widgets ver Werte vom BUS kommen?


                Danke

                Matthias


                Kommentar


                  #9
                  Zitat von mw2000 Beitrag anzeigen
                  - Wie funktioniert des Mapping? Ich möchte jeweils ein Icon auf den Trigger, welches das in Abhängigkeit Read Werte (Auf/zu) gefärbt wird.
                  Da wäre es erstmal wichtig zu klären, von wie vielen Read-Adressen die eingehenden Daten kommen. Ist das nur eine mit der Position, wo dann .z.B: der Wert 100 für "ganz unten" und 0 für "ganz oben" steht, oder sind das mehrere?

                  Wenn ich das richtig verstehe brauchst Du ja mindestens für jeden Aktor ein Mapping? Denn bei Jalousie ganz oben soll der obere eingefärbt werden der untere nicht und bei Jalousie ganz unten andersherum, oder nicht? Das erfordert auf jeden Fall eine Sonderbehandlung, zum Einen musst Du irgendwie das zweite Mapping definieren und parsen und zum Anderen die komplette Update-Behandlung überschreiben. Dazu musst Du in deiner Klasse diese beiden Methode überschreiben (einfach den Code reinkopieren und anpassen): https://github.com/CometVisu/CometVi...e.js#L199-L239 und https://github.com/CometVisu/CometVi...e.js#L296-L314.

                  Die erste macht die ganzen Dinge, die mit dem Wert gemacht werden müssen (transform, mapping, format, styling) und die zweite schreibt den Wert ins DOM.

                  Zitat von mw2000 Beitrag anzeigen
                  - Wie funktioniert das Updaten der Widgets ver Werte vom BUS kommen?
                  Wenn ich die Frage wegen dem Tippfehler nicht falsch verstanden habe, würde ich sagen, dass ich die oben schon mit beantwortet habe.

                  Gruß
                  Tobias

                  Kommentar


                    #10
                    Hi Peuter,

                    danke für die Info.

                    Zitat von peuter Beitrag anzeigen
                    Da wäre es erstmal wichtig zu klären, von wie vielen Read-Adressen die eingehenden Daten kommen
                    Mein Ansatz ist folgende Config
                    Code:
                                <custom>
                                    <switch_jal mapping="Light_Std" styling="GreyGrey" align="center" infoPosition="middle">            
                                        <layout colspan="12"/>
                                        <label>Jalousie-Switch</label>
                                        <address transform="DPT:1.001" mode="write" variant="short" >2/2/3</address>
                                        <address transform="DPT:1.001" mode="write"  variant="long" >2/2/2</address>
                                        <address transform="DPT:1.001" mode="read"  variant="pos" >2/2/53</address>
                                        <address transform="DPT:1.001" mode="read"  variant="isUp" >2/2/32</address>
                                        <address transform="DPT:1.001" mode="read"  variant="isDown" >2/2/33</address>
                                    </switch_jal>
                                </custom>
                    und dann folgende Funktion für den Address-Parser

                    Code:
                            makeAddressListFn: function (src, transform, mode, variant) {
                                // Aufbereitung der Funktion der jeweiligen Gruppenaddresse
                                var addrFunction;
                                switch (variant) {
                                    case 'short':
                                        addrFunction = 1;
                                        break;
                                    case 'long':
                                        addrFunction = 2;
                                        break;
                                    case 'pos':
                                        addrFunction = 3;
                                        break;
                                    case 'isUp':
                                        addrFunction = 4;
                                        break;
                                    case 'isDown':
                                        addrFunction = 5;
                                        break;                
                                    default:
                                        addrFunction = 6;
                                        break;
                                }
                                return [true, addrFunction];
                    Damit kann ich dann anhand der Adresse zu unterscheiden, wie ich die Behandlung vornehme.



                    Zitat von peuter Beitrag anzeigen
                    Dazu musst Du in deiner Klasse diese beiden Methode überschreiben
                    das bedeutet folgende Funktionen im Plugin Überschreiben für des Handlings der eingehenden Botschaften. Richtig?

                    Code:
                    defaultValueHandling: function (address, data)
                    defaultUpdate: function (ga, data, passedElement)
                    In welcher Funktion findet den bei den normalen Widgets die Zuweisung des Mappings statt? (sprich XML Inhalt ins DOM umsetzen?)




                    Kommentar


                      #11
                      Zitat von mw2000 Beitrag anzeigen
                      In welcher Funktion findet den bei den normalen Widgets die Zuweisung des Mappings statt? (sprich XML Inhalt ins DOM umsetzen?)
                      Das passiert genau in diesen beiden Funktionen, wobei "defaultUpdate" die zentrale Funktion ist, die wiederum "defaultValueHandling" aufruft. Letztere mach (unter anderem) das Mapping. Und "defaultUpdate" ruft dann wiederum "defaultValue2DOM" auf, welche den gemappten Wert ins DOM schreibt.
                      Gruß
                      Tobias

                      Kommentar


                        #12
                        Beim Überschreiben bekomme ich folgende Fehlermeldung.

                        Code:
                        Uncaught Error: Overwriting member "defaultUpdate" of Class "cv.ui.structure.pure.Switch_jal" is not allowed!
                        Nun habe ich herausgefunden das eine mixin included ist:
                        Code:
                        include: cv.ui.common.BasicUpdate
                        und
                        include: cv.ui.common.Update
                        Ich habe diese beiden Dateien nun in den Config Ordner kopiert, umbenannt und über die Config eingebunden. Danach Umbenennung des Klassennamens und schon kann ich der Funktion arbeiten...
                        Zuletzt geändert von mw2000; 21.01.2019, 23:26.

                        Kommentar


                          #13
                          Ja, das ist aber eher die Holzhammer Methode und wird dazu führen, dass du zukünftige Änderungen an einer der beiden Dateien immer mit in Deinen Code einbauen musst. Besser wäre es (hab ich jetzt nicht getestet, aber sollte eigentlich gehen) wenn Du ein eigenes Mixin schreibst, dass von cv.ui.common.Update erbt (also extend: cv.ui.common.Update) und darin die jeweiligen Funktionen überschreibst.

                          Aber mal eine Grundsätzliche Frage: Kannst Du Deinen Wunsch nicht einfach mit 2 Triggern und einem Info-Widget umsetzen? Wenn es dann nur noch darum geht, die nicht neben- sondern untereinander zu positionieren, dann könntest Du Dich eher am cv.ui.structure.pure.InfoAction Widget orientieren, dass kombiniert zumindest 2 Widgets. Wenn man nach dem Vorbild einfach ein Widget baut, dass einfach mehrere Widgets untereinander positioniert, dann dürfte sich damit Dein Problem doch leicht lösen lassen und es würde noch viel mehr Kombinationsmöglichkeiten bieten
                          Gruß
                          Tobias

                          Kommentar


                            #14
                            Zitat von peuter Beitrag anzeigen
                            Besser wäre es (hab ich jetzt nicht getestet, aber sollte eigentlich gehen) wenn Du ein eigenes Mixin schreibst, dass von cv.ui.common.Update erbt (also extend: cv.ui.common.Update) und darin die jeweiligen Funktionen überschreibst.
                            Das funktioniert leider nicht:
                            Code:
                            Uncaught Error: The configuration key "extend" in mixin "cv.ui.common.UpdateMW" is not allowed!
                            In der Doku von qx steht auch folgendes:
                            Code:
                            Features:[LIST][*]Add mixins to the definition of a class: All members of the mixin are added to the class definition.[*]Add a mixin to a class after the class is defined. Enhances the functionality but is not allowed to overwrite existing members.[*]Patch existing classes. Change the implementation of existing methods. Should normally be avoided but, as some projects may need to patch qooxdoo, we better define a clean way to do so.[/LIST]
                            Ich spiel mal etwas an der Holzhammermethode weiter

                            Zitat von peuter Beitrag anzeigen
                            Aber mal eine Grundsätzliche Frage: Kannst Du Deinen Wunsch nicht einfach mit 2 Triggern und einem Info-Widget umsetzen? Wenn es dann nur noch darum geht, die nicht neben- sondern untereinander zu positionieren, dann könntest Du Dich eher am cv.ui.structure.pure.InfoAction Widget orientieren, dass kombiniert zumindest 2 Widgets. Wenn man nach dem Vorbild einfach ein Widget baut, dass einfach mehrere Widgets untereinander positioniert, dann dürfte sich damit Dein Problem doch leicht lösen lassen und es würde noch viel mehr Kombinationsmöglichkeiten bieten
                            Da hast Du wahrscheinlich recht. Aber ich will ganze mit dem Beispiel mal verstehen und danach noch andere Dinge programmieren.

                            Vielen Dank für die Hilfe soweit...





                            Kommentar


                              #15
                              Stimmt bei Mixins gibts kein extend, sondern nur ein include und da kann man dann nichts überschreiben. Gut es gäbe jetzt noch andere Wege die man beschreiten könnte, aber dazu müsste der vorhandene Code zumindest etwas angepasst werden. Aber wenn es Dir erstmal nur ums Grundverständnis geht, mach erstmal so weiter. Für den Einsteig hast Du Dir da ja schon ein nicht ganz triviales Beispiel vorgenommen.
                              Gruß
                              Tobias

                              Kommentar

                              Lädt...
                              X