NEWS
Skript: Alle RHS/Fenster in einem Raum
-
// Select and show (for debug) all sensors in "Kabinet" and with type "Fenster" var sensors = $('channel[state.id=*.STATE](rooms=Kabinet)(functions=Fenster)').each(function(id) { log(id); }); function getCurrentState() { var commonState = 0; sensors.each(function (id) { if (id.indexOf('Statistik') != -1) return; var val = getState(id).val; log(id + ' = ' + val); // Convert from any possible value to int if (val === true || val === 'true') val = 1; if (val === false || val === 'false') val = 0; val = parseInt(val) || 0; log(id + ' = ' + val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); log('State= ' + commonState); return commonState; } // On change sensors.on(function(obj) { if (obj.id.indexOf('Statistik') == -1) { setState('Status_Schlafzimmer_Fenster', getCurrentState()); } }); createState('Status_Schlafzimmer_Fenster',getCurrentState());
Vielleicht braucht man in adapter dir Funktionen: convertToInt, convertToBool
-
Hallo Bluefox,
es funktioniert so. Ist sehr nützlich, da es auch in Räumen funktioniert, die zur Zeit noch nur mit einem Sensor ausgestattet sind. Wenn ich später mal nachrüste, brauch ich am Skript nichts zu ändern.
Vielen Dank für die Hilfe. Werde mich sicher noch einige Male an Dich wenden.
Gruß
Pix
-
// Select and show (for debug) all sensors in "Kabinet" and with type "Fenster" var sensors = $('channel[state.id=*.STATE](rooms=Kabinet)(functions=Fenster)').each(function(id) { log(id); }); function getCurrentState() { var commonState = 0; sensors.each(function (id) { if (id.indexOf('Statistik') != -1) return; var val = getState(id).val; log(id + ' = ' + val); // Convert from any possible value to int if (val === true || val === 'true') val = 1; if (val === false || val === 'false') val = 0; val = parseInt(val) || 0; log(id + ' = ' + val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); log('State= ' + commonState); return commonState; } // On change sensors.on(function(obj) { if (obj.id.indexOf('Statistik') == -1) { setState('Status_Schlafzimmer_Fenster', getCurrentState()); } }); createState('Status_Schlafzimmer_Fenster',getCurrentState());
Vielleicht braucht man in adapter dir Funktionen: convertToInt, convertToBool `
Es geht auch Tick kompakte ab neue JS version:
// Select and show (for debug) all sensors in "Kabinet" and with type "Fenster" var sensors = $('channel[state.id=*.STATE](rooms=Kabinet)(functions=Fenster)'); function getCurrentState() { var commonState = 0; sensors.each(function (id) { if (id.indexOf('Statistik') != -1) return; var val = toInt(getState(id).val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); return commonState; } // On change sensors.on(function(obj) { if (obj.id.indexOf('Statistik') == -1) setState('Status_Schlafzimmer_Fenster', getCurrentState()); }); createState('Status_Schlafzimmer_Fenster', getCurrentState());
-
Hallo,
ich habe ein ähnliches Problem, bei mir sollen es 3 Räume aus dem Obergeschoß werden.
Kann man die Zeile
var sensors = $('channel[state.id=*.STATE](rooms=Kabinet)(functions=Fenster)');
entsprechend anpassen, dass ich diese drei Räume mit den FT (Fenster/Tür)Kontakten abfragen kann? Alle(!) FTKontakte haben bei mir das Gewerk Alarmanlage. DIe Räume sind enstsprechend zugeweisen.
z. B. …(rooms=Schlafzimmer,Bad,Kind)? Als Trennzeichen hatte ich , ; | erfolglos versucht.
Wie funktioniert überhaupt diese Zeile :?:
Ich kann z. B. an einem Lampen-Objekt keine Gewerke bei mir sehen.
Nur das Objekt enum.functions.Licht hat als Member die einzelnen zugewiesenen Objekte. Aber diese Liste wird doch hier gar nicht abgefragt, oder?
<u>Kurzum:</u> Wie funktioniert denn diese tolle Zauberzeile genau? Hier ist ja mächtig Potential, Skripte erheblich zu verkürzen.
Ich hatte versucht mit eine
log (sensors);
zu experementieren. Leider kommt hier immer nur ein "undefined". Muss ich hier was anderes machen, um den Inhalt anzuzeigen?
Danke im Voraus,
Fitti
-
Hallo,
Du kannst die Bedingung (rooms=xxx) einfach weglassen, wenn nicht gebraucht.
Gruß
Pix
Gesendet von meinem iPhone mit Tapatalk
-
@pix:Du kannst die Bedingung (rooms=xxx) einfach weglassen, wenn nicht gebraucht. `
Na ganz im Gegenteil - ich habe 10 Räume. Von nur drei Räumen möchte ich jeden TürFensterkontakt haben. Der Raum ist also essential.Diese Zeile bereitet mir immer noch Kopfschmerzen: sie scheint so voller Potenzial zu stecken und ich versteh' nix.
Klar, der Filter ist verstanden, aber ich habe nicht einmal mit Hilfe eines anderen Programmierer, der ein bisschen Java auch macht (jau - wir haben hier JS… - aber wen man schon mal Zugriff hat ...), verstanden, ob Werte oder Objekte in der Variablen sensors landen. Nur ein Hochkomma usw...
Wäre echt toll, wenn bitte noch jemand dieses noch etwas mehr erklären könnte. Gerne auch nur ein Link zur richtigen Erklärung irgendwo im INet. Da ich abe rnicht weiß, wonach ich suchen muss, finde ich auch nichts. Habe erfolglos zwei JavaScript Anleitungen durchgeblättert.
Viele Grüße,
Fitti
-
Das hier hast du dir schon angesehen?
https://github.com/iobroker/ioBroker.javascript/blob/master/README.md#–-selector
Gruß
Pix
-
Nur das Objekt enum.functions.Licht hat als Member die einzelnen zugewiesenen Objekte. Aber diese Liste wird doch hier gar nicht abgefragt, oder? `
Doch, genau diese Zuweisungen sind entscheidend für die Auswertung der enums.Z.B. legst Du ein Gewerk "Fenster-OG" unter enum.functions an und weist als Mitglieder alle TFK im OG zu. Dann dürfte die Abfrage recht einfach werden, z.B.:
// Alle TFK im Gewerk "Fenster-OG" auswerten var sensors = $('channel[state.id=*.STATE](functions=Fenster-OG)'); function getCurrentState() { var commonState = false; sensors.each(function (id) { if (getState(id).val) commonState = true; }); return commonState; } // On change sensors.on(function() { setState('Status_OG-Fenster', getCurrentState()); }); createState('Status_OG-Fenster', getCurrentState());
-
@pix: :oops: Danke!
@paul53: Das wollte ich aus zwei Gründen vermeiden:
1.) Ich möchte die Gewerke nicht für logische Gruppen, die ich nur in einem Skript benötige, unnötig aufblähen. Das sind für mich auch zuviel Abhängigkeiten, die man später kaum überblickt.
2.) Es versuche mich in JS einzuarbeiten und das Ganze besser zu verstehen - und fragte mich deshalb, ob auch eine doppelte ROOMS-Filterung, oder das Ganze irgendwie anders geht?
Habe da noch Verständnisfragen - basierend auf der parallel laufende Anfrage von mir - ich will doppelte Posts vermeiden, deshalb mache ich nur hier weiter:
Im Code
var sensors = $('channel[state.id=*.STATE](rooms=Schlafzimmer)(functions=Fenster)'); function getCurrentState() { var commonState = 0; sensors.each(function (id) { var val = toInt(getState(id).val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); return commonState; } // On change sensors.on(function(obj) { if (obj.id.indexOf('Statistik') == -1) setState('Status_Schlafzimmer_Fenster', getCurrentState());}); createState('Status_Schlafzimmer_Fenster', getCurrentState());
<size size="150">1.)</size>
habe ich nun mit Eurer Hilfe es so verstanden, dass im Bereich //on Change eine Funktion definiert wird. Ein Wert wird dieser Funktion übergeben und dieser wird der Variablen obj zugewiesen. Eine Zeile später wird diese Variable in der Abfrage obj.id.indexOf("… verwendet, richtig? (Und das ist hier nur ein Filter, damit Aktoren mit dem Namen "Statistik" ausgefiltert werden.)
<size size="150">2.)</size>
Ich nehme an, dass der Wert, dem der Funktion-internen Variablen obj übergeben wird, aus dem Selector "sensors" übernommen wird und "vermutlich(?)" durch einen CallBack (Rückaufruf?) gefüllt wird, richtig? Also irgendein Deamon im Hintergrund, initiiert durch sensors.on, wacht über eine Liste (senosrs-Selector). Ändert sich was, wird dieser eine Wert(?) übergeben?
Ändert sich hier was, wird nun die Variable 'Status_Schlafzimmer_Fenster gesetzt, den Wert/Status dazu bekommt man durch die Funktion getCurrentState().
<size size="150">3.)</size>
In der Funktion getCurrentState() wird mit sensors.each(function(id) nun JEDER(?) Aktor in der Liste sensors (gefiltert durch den selector) einer neuen function einzeln übergeben. Diese Funktion wird in den soeben genannten code ( sensors.each(function(id) ) definiert und der Wert wird der Funktion-internen Variablen id übergeben,richtig?
<size size="150">3a.)</size>
Dadurch kann z . B. in der Zeile var val = toInt(getState(id).val); dieser Wert abgefragt werden, richtig?
<size size="150">4.)</size>
Letztendlich wird die allerletzte Zeile quasi nur ein einziges Mal aufgerufen, danach übernimmt die on "Schleife/Deamon" die Weiterverarbeitung, richtig?
<size size="150">5.)</size>
Was ist denn nun in der Variablen sensors drinnen? Eine Liste (Array?)?
Wie immer, vielen Dank für Eure Hilfe.
Viele Grüße,
Fitti
-
Das Skript läuft jetzt bei mir mit drei Räumen.
Ich habe die val variable global gemacht, für jeden Raum einen Selector eingesetzt und drei on Funktion hinzugefügt.
// Script zum Setzen einer Variablen, um z.B. eine kleines Übersichts-Icon/Widget // anzuzeigen. // Die Variable VIS.zeige_1og_fensterstatus_icon kann folgende Werte haben: // 0 - alle Fenster zu // 1 - mindestens 1 Fenster angekippt // 2 - mindestens 1 Fenster offen. // Es wird immer der höhere Wert über allen räumen gesetzt. // Im Widget muss unter der Sichtbarkeit die Variable > 0 abgefragt werden. // Es werden die Sensoren in drei Räumen abgefragt(rooms=xxx), so wie diese gesetzt sind und jweils mit // dem Gewerk (functions=xxx). var sensors_raum1 = $('channel[state.id=*.STATE](rooms=Bad)(functions=Alarmanlage)').each(function(id) { log("R1: " + id); }); var sensors_raum2 = $('channel[state.id=*.STATE](rooms=Wohnen1)(functions=Alarmanlage)').each(function(id) { log("R2: " + id); }); var sensors_raum3 = $('channel[state.id=*.STATE](rooms=Wohnen2)(functions=Alarmanlage)').each(function(id) { log("R3: " + id); }); var val; // Ohne Loginfo jedes erkannte Geräte: //var sensors = $('channel[state.id=*.STATE](rooms=Wohnen1)(functions=Alarmanlage)'); function getCurrentState() { var commonState = 0; sensors_raum3.each(function (id) { val = toInt(getState(id).val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); sensors_raum2.each(function (id) { val = toInt(getState(id).val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); sensors_raum1.each(function (id) { val = toInt(getState(id).val); // Find the maximum (2 - opened, 1 - tilted, 0 - closed) if (val > commonState) commonState = val; }); return commonState; } // On change Raum3 sensors_raum3.on(function() { setState('VIS.zeige_1og_fensterstatus_icon', getCurrentState()); }); // On change Raum2 sensors_raum2.on(function() { setState('VIS.zeige_1og_fensterstatus_icon', getCurrentState()); }); // On change Raum1 sensors_raum1.on(function() { setState('VIS.zeige_1og_fensterstatus_icon', getCurrentState()); }); createState("VIS.zeige_1og_fensterstatus_icon", getCurrentState(), {name: 'VIS Zeige 1Og Fensterstatus-Icon'});
Es funktioniert. Stellt sich mir nur die Frage, ob es vielleicht in der Abfrage optimiert werden kann oder ob die drei ON's in irgendeiner Form supoptimal sind?
Viele Grüße,
Fitti