NEWS
Schreibzugriff auf (Objekt-)Attribute in Blockly
-
Nach nunmehr vier Jahren Blockly will ich mich nun endlich in die direkte Programmierung via JavaScript vertiefen. Hierzu kam mir der Wunsch eines Familienmitglieds gerade recht: Rollladen in Gruppen verwalten.
Ziel ist es, Blöcke in Blockly bereitzustellen, mit denen die Rollladengruppen verwaltet werden können.
Hierzu habe ich eine kleine OOP-Anwendung geschrieben. Ich habe ein Objekt erstellt, das neben mehreren Methoden einige Datenfelder enthält.
Voraussetzungen ..
Ein Datenfeld members des Objektes enthält ein ARRAY aus Objekten, die einzelne Rollladen beschreiben. Die Struktur des ARRAYs und eines Rollladens sind in der nachfolgenden Abbildung dargestellt. Ein Rollladenobjekt besteht aus einem Namen (String) und einer Objektadresse (String). Die Adresse verweist auf den zugehörigen Datenpunkt in einem Rollladenaktor, mit dem die Position des jeweiligen Rollladens gesteuert wird.
Meine ersten Versuche ..
Der Block GrpGetRol liefert den i-ten Rollladen aus dem ARRAY members. Zwar kann ich nun auf das darin enthaltene Adressfeld zugreifen, aber ich weiß nicht, wie ich schreibend auf den im Adressfeld (als String) gespeicherten Datenpunkt mittels Blockly schreibend zugreifen kann (sozusagen eine indirekte Adressierung).
Ausweg ..
Selbstverständlich könnte ich mittels eines selbst erstellten Blocks, in dem ich via setState diesen Schreibzugriff realisiere, diese Aufgabe lösen, aber ich hätte gerne gewusst, ob es auch eine Lösung in Blockly gibt, die es ermöglich dies auszuführen.
Wer's genauer wissen will, was ich gemacht habe, findet hier das Objekt ..
function ObjGrpRol(ID_Data) { //Name des Datenpunktes der Gruppe im Objektbaum this.ID_Grp = ID_Data //Daten des Widgets: Liste mit Namen, Liste der Nummerierung, selektierter Eintrag this.WidgetData = {ID_lstNamen : '', ID_lstNr : '', ID_SelItem : ''} //Array der Rollläden in ioBroker Objects speichern this.members = JSON.parse(getState(ID_Data).val) this.GrpSetWidgetData = function (ID_lstNamen, ID_lstNr, ID_selItem) { this.WidgetData.ID_lstNamen = ID_lstNamen this.WidgetData.ID_lstNr = ID_lstNr this.WidgetData.ID_selItem = 0 } this.GetMembers = function () { return this.members } this.widgetUpdate = function (WidgetData) { let lName = "" //Datenpunkt(Widget) mit Namensliste der Rollläden let lNr = "" //Datenpunkt(Widget) mit Nummern der Listeneinträge let i = "" //Hilfsvariable this.members.forEach((item) => { lName = lName + ";" + item.Name //Namen der Rollläden lNr = lNr + ";" + String(i+1) //EintragsNr der Rollläden i++ }) lName = lName.slice(1) //führendes Semikolon entfernen lNr = lNr.slice(1) //führendes Semikolon entfernen setState(this.WidgetData.ID_lstNamen,lName,true) //Namenliste der Rollladengruppe in den Objekte abspeichern setState(this.WidgetData.ID_lstNr,lNr,true) //Nummern der Listeneinträge in den Objekten abspeichern } this.Get = function (i) { if(i < this.members.length) { console.log(this.members.length) return this.members[i] } else { return null } } //Array der Rollläden als JSON in Objekte abspeichern. this.store = function () { //let a = 'Käsekuchen' //'JSON.stringify(this.members)' setState(this.ID_Grp,JSON.stringify(this.members),true) } //einzelnen Rollladen (Rol) in eine Gruppe (Grp) einfügen this.ins = function (Rol) { if (Rol != null) { if (this.pos(Rol) < 0 ) { //noch nicht vorhanden liefert -1 this.members.push(Rol) } } } this.pos = function (Rol) { // -1 : Element wurde nicht gefunden // nr : Nummer der Postion des Elementes in der Gruppe (Array) let i = -1 let found = false if (Rol != null) { while (!found && i<this.members.length - 1) { i++ found = (this.members[i].Name == Rol.Name && this.members[i].ObjAddr == Rol.ObjAddr) } } if (found) return i else return -1 } //einen Rollladen (Rol) aus der Gruppe (members) löschen this.del = function (Rol) { let nr = this.pos(Rol) if (nr >= 0) { //nr = -1 wenn Element nicht gefunden this.members.splice(nr,1) } } } grp = new ObjGrpRol(members); return grp
-
@legro sagte: schreibend auf den im Adressfeld (als String) gespeicherten Datenpunkt mittels Blockly schreibend zugreifen kann
Das geht mit dem Block "schreibe".
@legro sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
Rollladen in Gruppen verwalten.
Dafür sind in ioBroker die Aufzählungen gedacht. Eine Aufzählung enthält die zugewiesenen IDs in common.members. Der $Selektor kann zur Auswahl der IDs einer Aufzählung dienen.
-
Vielen Dank für deine Unterstützung.
Ich kann nur vermuten, dass du ggf. diesen Block meinst ..
Aber wie gebe ich hier die Zieladresse ein? Datenpunkt des Aktors liegt mir doch nur als String vor.
Die Aufzählungen aus Blockly möchte ich aus zwei Gründen nicht verwenden. Zum einen möchte ich mich endlich in JavaScript vertiefen, zum anderen fehlt mir in den Aufzählungen die Möglichkeit einzelne Objekte hinzuzufügen oder zu löschen - oder habe ich die bloß nicht gefunden?
-
@legro sagte: wie gebe ich hier die Zieladresse ein?
@legro sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
Möglichkeit einzelne Objekte hinzuzufügen oder zu löschen - oder habe ich die bloß nicht gefunden?
Die Funktionen zum Verändern (setObject) in "enum.functions.rollos" unter common.members liefert der Javascript-Adapter.
const idEnum = 'enum.functions.rollos'; const obj = getObject(idEnum); const members = obj.common.members; // Array mit IDs // Hinzufügen oder löschen von IDs in members setObject(idEnum, obj);
-
Wie ich oben schrieb: Ich möchte zum Üben dieses Projekt in der skizzierten Weise durchziehen.
Mithin habe ich bloß die eine Frage: Könnte man auf das Attribut „objAddr“ eines Rollladen-Objektes schreibend zugreifen?
So sieht meine Test-View aus. Mit den +/- Buttons kann man Rollladen in die Gruppen hinzufügen oder löschen.
-
@legro sagte: auf das Attribut „objAddr“ eines Rollladen-Objektes schreibend zugreifen?
Neues Objekt (wie im ersten Beitrag gezeigt):
Diese Blöcke stehen seit JS-Version 7.9.0 zur Verfügung.
-
Erst einmal: Vielen Dank für deine tatkräftige Unterstützung!
Wenn ich dich und das Ganze richtig verstanden habe, sollte ich mein Ziel doch auch (noch) kürzer erreichen, indem ich ..
.. kodiere. Der Datenpunkt Grp01_Position_01 enthält den Wert, den ich in den Datenpunkt objAddr schreiben möchte.
Oder liege ich (mal wieder voll) daneben?
Ich stelle mir das Ganze wie folgt vor ..
Der rechte Block liefert an den linken Block die Adresse des zu steuernden Datenpunktes des Rollladens, die im Attribut objAddr des Rollladen-Objektes enthalten ist. Der linke Block sorgt nun dafür, dass der Wert aus dem Datenpunkt Grp01_Position_01 in den Datenpunkt des Rollladens geschrieben wird.
-
@legro sagte: Grp01_Position_01 enthält den Wert, den ich in den Datenpunkt objAddr schreiben möchte.
Passt so.
-
@paul53 sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
Passt so.
Langsam verstehe ich nun doch das Ganze.
Nach vier Jahren wurde es höchste Zeit, dass ich endlich einmal mit JavaScript beginne. Blockly ist ja für den Einstieg schon eine feine Sache, aber man kommt doch schnell an dessen Grenzen.
Nun bitte nochmals zu den Kodierungen. Sind meine Vorstellungen richtig, wenn ich davon ausgehe, dass in deinem Vorschlag ..
- .. der erste (grüne) Block den Wert des Attributs des Objektes neu schreibt/füllt.
- .. der zweite (grüne) Block einen Datenpunkt im Objektbaum anlegt mit der Bezeichnung aus der Variable name.
- .. mein Lösungsvorschlag einen nur temporär existierenden Datenpunkt (ohne Bezeichnung) erzeugt, der nach dem Schreibvorgang wieder gelöscht wird.
Wo finde ich diese grünen Blöcke?
-
@legro sagte: der erste (grüne) Block den Wert des Attributs des Objektes neu schreibt/füllt.
Ja, ein existierender Wert wird überschrieben, ein nicht existierendes Attribut des Javascript-Objektes wird erzeugt.
@legro sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
der zweite (grüne) Block einen Datenpunkt im Objektbaum anlegt mit der Bezeichnung aus der Variable name.
Nein: Es handelt sich um ein Javascript-Objekt, das erzeugt wird in der Form
var obj = { objAddr: 'Objekt-ID', Name: 'Objekt-Name' };
Das hat nichts mit ioBroker-Objekten zu tun!
@legro sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
mein Lösungsvorschlag einen nur temporär existierenden Datenpunkt (ohne Bezeichnung) erzeugt, der nach dem Schreibvorgang wieder gelöscht wird.
Es wird kein Datenpunkt erzeugt, sondern in einen Datenpunkt geschrieben, der bereits existieren muss.
@legro sagte in Schreibzugriff auf (Objekt-)Attribute in Blockly:
Wo finde ich diese grünen Blöcke?
Bei mir sind sie hellbraun und erst ab Javascript-Version 7.9.0 verfügbar (ich nutze Version 8.3.0).
-
Da habe ich ja richtig Glück gehabt, dass ich in dir einen sehr guten Kenner von ioBroker und JavaScript angetroffen habe.
Ich habe die letzte Version aus dem stable repository 7.8.0. Hierin sind diese Blöcke (noch) nicht vorhanden. Es fehlt in dieser Version das gesamte Register Objekte.
-
@legro sagte: Es fehlt in dieser Version das gesamte Register Objekte.
Ja, 7.9.0 > 7.8.0.