Hallo zusammen,
es ist vollbracht
Danke eurer Erläuterungen habe ich es recht kurzer Zeit geschaft mein Widget zu bauen. Das CSS ist sicher noch nicht fertig, aber das kann ich noch machen, nachdem die Funktionalitätt jetzt gegegben ist.
Ich erläutere hier mal wie ich es umgesetzt habe und würde mich über eine Feedback freuen. Mir ist wichtig, mich nicht zu weit von der Idee der CV zu entfernen, um zukünftige Inkompatibilitäten so klein wie möglich zu halten. Im Anhang findet Ihr die gesamten Dateien.
Ausschnitt im Config XML zur GA
Auswertung der spezifischen Funktion der GA über den Variant Parameter structure_custom_jal.js
Ausschnitt im Config XML zum Mapping, es gibt ein Icon für UP/DOWN jeweils für Button aktiv/inaktiv
Es gibt folgende Darstellungen
1. ) Der Rolladen steht nicht in den Anschlägen
shutter-mid.png
2.) Der Rolladen ist ganz oben
shutter-up.png
3.) Der Rolladen ist ganz unten
shutter-down.png
Der Zustand der Button wird über die GA "state_button0/1" gesteuert, welche vom BUS die Info bekommen Rolladen ganz unten/oben bekommen. Um mit einem Mapping beide Button zu bespielen, haben ich 4 Icons dort hinterlegt. Um dann beim valueHandling das richtige Icon auf den Button0/1 zu bekommen, wird zu der "data" von der GA "state_button1" ein Offset von 2 addiert (s.u. defaultValueHandling)
Der Tastendruck wird kurz/lang ausgewertet structure_custom_jal.js
Für das korrekte Anzeigen mussten 2 Funktionen (s.o.) mit dem Holzhammer überschieben werden.
Die Magic passiert hier BasicUpdateMW.js
dazu noch eine neue UpdateMW.js mit folgender mini Änderung (sehr Unschön)
eingebunden in meine structure_custom_jal.js
Wie schon gesagt funktioniert dies bestens, ich bin mir aber unsicher, ob isch irgendwelche größeren Prinzipen der CV missachtet habe.
Bleibt nur noch die unschönheit der Holzhammer methode
.
Geschickt wäre es wenn man die defaultUpdate() mit einer userUpdate() ersetzen könnte, damit wäre es deutlich einfacher .
es ist vollbracht

Ich erläutere hier mal wie ich es umgesetzt habe und würde mich über eine Feedback freuen. Mir ist wichtig, mich nicht zu weit von der Idee der CV zu entfernen, um zukünftige Inkompatibilitäten so klein wie möglich zu halten. Im Anhang findet Ihr die gesamten Dateien.
Ausschnitt im Config XML zur GA
Code:
<switch_jal mapping="fts_shutter_duoswitch" styling="GreyGrey" format="%.0f %%" align="center" infoPosition="middle" downValue="1"> <layout colspan="12"/> <label>Jalousie-Switch</label> <address transform="DPT:1.008" variant="long">3/2/12</address> <address transform="DPT:1.001" variant="short">3/2/52</address> <address transform="DPT:1.001" variant="state_button0">3/2/172</address> <address transform="DPT:1.001" variant="state_button1">3/2/132</address> <address transform="DPT:5.001" variant="position">3/2/92</address> </switch_jal>
Code:
getAddressFunction: function (ga) { // Die Funktion der aktuellen GA aus den zum Widget gehörigen // Gruppenadressen(property Variant) herausfiltern for (var curAddr in this.getAddress()) { if (curAddr === ga) { return this.getAddress()[ga][2]; break; } } return 0; },
Code:
<mapping name="fts_shutter_duoswitch"> <entry value="0"> <icon name="fts_shutter_down" color="white"/> </entry> <entry value="2"> <icon name="fts_shutter_up" color="white"/> </entry> <entry value="1"> <icon name="fts_shutter_down" color="grey"/> </entry> <entry value="3"> <icon name="fts_shutter_up" color="grey"/> </entry>
1. ) Der Rolladen steht nicht in den Anschlägen
shutter-mid.png
2.) Der Rolladen ist ganz oben
shutter-up.png
3.) Der Rolladen ist ganz unten
shutter-down.png
Der Zustand der Button wird über die GA "state_button0/1" gesteuert, welche vom BUS die Info bekommen Rolladen ganz unten/oben bekommen. Um mit einem Mapping beide Button zu bespielen, haben ich 4 Icons dort hinterlegt. Um dann beim valueHandling das richtige Icon auf den Button0/1 zu bekommen, wird zu der "data" von der GA "state_button1" ein Offset von 2 addiert (s.u. defaultValueHandling)
Der Tastendruck wird kurz/lang ausgewertet structure_custom_jal.js
Code:
// 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 var x = this.getDownValue(); var y = this.getUpValue(); 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] === 0) && (isShort)) { this.sendToBackend(value, function (address) { return !!(address[2] === 0); }); } //langer Tastendruck if ((address[2] === 1) && (!isShort)) { this.sendToBackend(value, function (address) { return !!(address[2] === 1); }); } } } },
Für das korrekte Anzeigen mussten 2 Funktionen (s.o.) mit dem Holzhammer überschieben werden.
Die Magic passiert hier BasicUpdateMW.js
Code:
defaultValueHandling: function (address, data) { // #1: transform the raw value to a JavaScript type var value = this.applyTransform(address, data); // store it to be able to suppress sending of unchanged data if (value !== undefined) { this.setBasicValue(value); } // Modifikation der Value um Mapping Icons von Button // 1 und 2 unterscheiden zu können // Funktion der Adresse ermitteln var gaFunction = this.getAddressFunction(address); if (gaFunction === 3) { // Value um 2 erhöhen, damit andere Bilder genommen werden value += 2; } // #2: map it to a value the user wants to see value = this.applyMapping(value); // #3: format it in a way the user understands the value // Formatierung nur bei der Positionsanzeige if ((value !== undefined) && (gaFunction === 4)) { value = this.applyFormat(address, value); this.setValue(value); } if (value && value.constructor === Date) { switch (this.getAddress()[address][0]) // special case for KNX { case 'DPT:10.001': value = value.toLocaleTimeString(); break; case 'DPT:11.001': value = value.toLocaleDateString(); break; case 'OH:datetime': value = value.toLocaleDateString(); break; case 'OH:time': value = value.toLocaleTimeString(); break; } } this.applyStyling(this.getBasicValue()); // #4 will happen outside: style the value to be pretty return value; }, .... defaultUpdate: function (ga, data, passedElement) { var element = passedElement || this.getDomElement(); // Funktion der Adresse ermitteln var gaFunction = this.getAddressFunction(ga); // nur Anzeige Adressen durchlassen if (gaFunction < 2) { return data; } ; var value = this.defaultValueHandling(ga, data); // TODO: check if this is the right place for this // might be if the styling removes the align class if (this.getAlign()) { qx.bom.element.Class.add(element, this.getAlign()); } //Das passende Valueelement auswählen var valueElement; var doUpdate = false; switch (gaFunction) { case 2: //Update des Button 1 doUpdate = true; //Status Endanschlag des Button 1 abspeichern if (parseInt(data, 16) === 1) { //Endanschlag erreicht keine weisteres Fahren in diese Richtung möglich this.setButtonEndState1(1); } else { this.setButtonEndState1(0); } valueElement = qx.bom.Selector.query('.actor_jal_down > .value', element)[0]; break; case 3: //Update des Button 2 doUpdate = true; //Status Endanschlag des Button 2 abspeichern if (parseInt(data, 16) === 1) { //Endanschlag erreicht keine weisteres Fahren in diese Richtung möglich this.setButtonEndState2(1); } else { this.setButtonEndState2(0); } valueElement = qx.bom.Selector.query('.actor_jal_up > .value', element)[0]; break; case 4: //Positionsvalues valueElement = qx.bom.Selector.query('.actor_jal_pos', element)[0]; doUpdate = true; ; break; default: //ursprünglicher Code valueElement = this.getValueElement ? this.getValueElement() : qx.bom.Selector.query('.value', element)[0]; break; } //Spezialbehandling für den Endanschlag status beider Buttons if ((this.getButtonEndState1() === 1) || (this.getButtonEndState2() === 1)) { // die Positionsanzeige wird unterdrückt var posElem = qx.bom.Selector.query('.actor_jal_pos', element)[0]; qx.bom.element.Style.setCss(posElem, "float:left; margin: 4px 1px; display: none"); } else { // die Positionsanzeige wird angezeigt if (gaFunction === 4) { var posElem = qx.bom.Selector.query('.actor_jal_pos', element)[0]; qx.bom.element.Style.setCss(posElem, "float:left; margin: 4px 1px; "); } } if (doUpdate) { //Alten Inhalt löschen qx.dom.Element.empty(valueElement); //neuen Inhalt darstellen if (undefined !== value) { this.defaultValue2DOM(value, qx.lang.Function.curry(this._applyValueToDom, valueElement)); } else { qx.dom.Element.insertEnd(document.createTextNode('-'), valueElement); } } return value; },
Code:
include: cv.ui.common.BasicUpdateMW,
Code:
include: [ cv.ui.common.Operate, cv.ui.common.UpdateMW, cv.ui.common.HasAnimatedButton, cv.ui.common.HandleLongpress ],
Bleibt nur noch die unschönheit der Holzhammer methode

Geschickt wäre es wenn man die defaultUpdate() mit einer userUpdate() ersetzen könnte, damit wäre es deutlich einfacher .
Kommentar