NEWS
[gelöst] Variable in einem "IDs vom Selektor"
-
Moin,
versuche gerade eine Variable für die "role" in den IDs vom Selektor zu übergeben, finde aber nirgends eine Beschreibung, oder ein Beispiel. Was ich gefunden habe, ist ein offenes Issue im JS Adapter hierzu, allerdings zu der "latest" JS.
Github Issue JavaScript Adapter
auch einen alten Forums Beitrag, der aber von @paul53 anscheinend gelöst wurde:
[gelöst] Variable in einem "IDs vom Selektor"-Array
Hintergrund ist, dass mit dem LoRaWAN Adapter Installationen von hunderten Heizkörperthermostaten realistisch werden. Der Adapter ist mittlerweile so aufgebaut, dass die Geräte ihre Nutzdaten in eine DB schreiben und steuerbar sind und auch automatisch state.roles bekommen, allein durch das Hinzufügen im LNS und dies geht auch per Bulk Import per JSON, oder cfg Datei. Ziel ist es ohne großen Aufwand einige Automatisierungen vornehmen zu können. Im ersten Schritt war angedacht, dass der Heizkörper runterregelt, wenn in diesem Raum das Fenster geöffnet wird. Den Geräten muss hierfür natürlich der Raum zugewiesen werden. Auch muss einem Fenster-Sensor die [role=sensor.window] zugewiesen sein, dass passiert mittlerweile auch automatisch.
Ich triggere also auf alle roles=sensor.window in der Lorawan Instanz, hole mit der JS Funktion das Objekt zu dem State und zieh mir dort den Raum raus:
const rooms=getObject(testID,"rooms") return rooms;
Nun ist bekannt, dass ein Fenster geöffnet wurde und in welchem Raum, in dem Fall "office"
Nun soll die TargetTemperatur des entsprechnen Raums (office) auf 6 Grad gestellt werden.
Wird der IDs vom Selektor ohne Variable, einfach mit (rooms=office) benutzt, so komme ich an den richtigen State.
Probiere ich es mit der Übergabe als Variable nicht.
Wie müsste denn die Übergabe der Variable aussehen, damit das klappt?
Und, gibt es eine Dokumentation, wo das ersichtlich ist?Das Blockly in JS Anicht:
var testID, room2, room3; // Beschreibe diese Funktion … async function rooms() { const rooms=getObject(testID,"rooms") return rooms; } on({ id: [].concat(Array.prototype.slice.apply($('lorawan.1.* [role=sensor.window]'))), change: 'ne' }, async (obj) => { let value = obj.state.val; let oldValue = obj.oldState.val; testID = ('' + Array.prototype.slice.apply($('lorawan.1.* [role=sensor.window]'))); console.info((await rooms())); room2 = getAttr((await rooms()), 'enumIds.0'); console.error(room2); console.error((room2.slice(11, room2.length))); room3 = room2.slice(11, room2.length); console.warn(('Variable room3 ist: ' + String(room3))); console.info('lorawan.* [role=level.temperature] (rooms=office)'); console.warn(Array.prototype.slice.apply($('lorawan.* [role=level.temperature] (rooms=office)'))); console.info('lorawan.* [role=level.temperature] (rooms="+room3+")'); console.error(Array.prototype.slice.apply($('lorawan.* [role=level.temperature] (rooms="+room3+")'))); console.info('lorawan.* [role=level.temperature] (rooms=\'+room3+\')'); console.error(Array.prototype.slice.apply($('lorawan.* [role=level.temperature] (rooms=\'+room3+\')'))); });
Es funktioniert weder: (rooms="+room3+") noch: (rooms='+room3+')
-
@j_paul sagte: Probiere ich es mit der Übergabe als Variable nicht.
Offenbar wurde der Selektor verändert und es wird nun ein \ vor das Hochkomma gesetzt, womit es nicht funktioniert.
So funktioniert es:return Array.prototype.slice.apply($('*.LoRaWAN.*[role=level.temperature](rooms='+room+')'));
-
@paul53
Vielen Dank, für Deine Antwort. Es ist nicht das erste mal, dass du mit deiner Antwort meinen Karren aus dem Dreck ziehst, ich weiß das zu schätzen. Es ist zwar eine Lösung, aber schön ist das nicht. Dass eine Funktion da war und nun raus genommen wurde ist das eine, dass dies aber- nicht in der Dokumentation zu finden ist
- nicht im Change LOG zu finden ist
- offen Issues dazu nicht beantwortet werden
ist das andere. Dein "Offenbar" sagt mir, dass du dazu auch nichts gefunden hast.
Ich werde es so machen, wie von dir aufgezeigt, nochmals danke!
-
@j_paul Ja, das vorher war ein Bug. Richtig. Dass man da quasi per Code Injection Variablen einfügen kann war nie so geplant oder gedacht.
Kann ich gern im Issue erklären und schließen
-
@j_paul sagte in [gelöst] Variable in einem "IDs vom Selektor":
dies aber
- nicht im Change LOG zu finden ist
Steht doch drin
-
@haus-automatisierung
Danke für die Erklärung.
"It‘s not a Feature, it‘s a Bug"
kannte ich so rum noch nichtDie Angabe im Change Log hatte ich nicht mit der Übergabe einer Variablen in Zusammenhang gebracht, mein Fehler.
-
@j_paul sagte in [gelöst] Variable in einem "IDs vom Selektor":
"It‘s not a Feature, it‘s a Bug"
Ja genau, wenn single quotes nicht escaped würden, wäre der JavaScript Code ja nicht gültig, sobald man nur eines verwendet z.B. Oder man konnte solchen Quatsch eingeben:
'; const test = 123; hello();
Und das ist ja wirklich nicht im Sinne dieser Blöcke, dass man darin programmieren kann.
Genau so funktioniert übrigens SQL Injection auf Webseiten. Man gibt in ein Feld (z.B. für den Benutzernamen) weitere SQL-Syntax ein, in der Hoffnung den Befehl korrekt zu unterbrechen und dann weiteren Logik auszuführen / in der Datenbank andere Statements abzusetzen statt sich anzumelden.
-
@haus-automatisierung sagte: das vorher war ein Bug
Die Änderung seit Version 8.7.0 ist ein "breaking change", da der "Bug" in der Vergangenheit ausgenutzt wurde, um Variablen in den Selektor-String einzufügen.
-
@paul53 Das war nur nie so dokumentiert und ist von Blockly auch nicht so gedacht bei Input Fields. Ist ja nirgendwo sonst so
-
@haus-automatisierung
Sorry, falls das eine naive Frage sein sollte:
Liesse sich IDs von Selektor nicht als Block bauen, bei dem man, wie bei den anderen Blöcken auch, Möglichkeit hat Text/Variablen für states, roles, functions, rooms anzuheften? Dies könnte man ja auf erlaubte Zeichen begrenzen, damit nichts anbrennen kann.
Ja ich weiß, aber nein, von mir ist diesbezüglich kein PR zu erwarten. -
@j_paul Ja, könnte man natürlich machen