@MagicSven sagte in Offene Fenster in node-red:
Wird ein Fenster geöffnet, steht in einem Textfeld "Fenster Bad"
wird ein zweites Fenster geöffnet, steht "Fenster Bad; Fenster Küche"
wird jetzt ein Fenster geschlossen, dann steht: " "
Das hat eigentlich nichts mit NR oder JS zu tun. Ich frage halt nur zu einer bestimmten Zeit ab und reagiere nicht automatisch auf den Zustand. Wenn das bei dir so sein soll, musst du immer wenn sich der Zustand eines Fensters ändert, den String komplett neu aufbauen.
Was mein JS-Script anbetrifft so wirst du es nicht ohne Weiteres verwenden können.
Ich arbeite inzwischen für alle Tür-/Fensteraktoren mit alias.0-States. Das hat den Vorteil, dass in gleicher Weise sowohl HM- als auch meine Zigbee-Aktoren bearbeitet werden können. Und einen Aktor austauschen ist auch kein Problem mehr.
Das Skript sieht dann so aus:
Spoiler
//R. W. 17.11.2018
// 04.12.2018 - cacheSelector[]
// 13.12.2019 - Umstellung auf alias.0
const resultType = "open"; // all, open, close
// array of states
// $() ist a object function in iob JS API
var cacheSelector = [$('state[id=alias.0.Verschluss.*]')];
function countOpenwindows() {
let windows = []; // array of windows-objects
let speakVolume = '50';
let speakText = '';
for (const cSelector of cacheSelector) {
// $(selector).each(function(id, i) {}); each dp in cSelector
cSelector.each(function (id) {
let w = {};
let deviceId = id.substr(0, id.lastIndexOf("."));
w.id = id; //state _id
// Name is Part from id in alias.0 states
// "alias.0.Verschluss.Fenster_Gäste_WC.opened"
// "alias.0.Verschluss.Garage.Zwischentür_vorn.Schloss.opened"
let name = id.replace(/alias.0.Verschluss./, "").replace(/.opened/, "");
w.Name = name;
w.val = getState(id).val;
switch (resultType) {
case 'open':
if (w.val === true) { windows.push(w); }
break;
case 'close':
if (w.val === false) { windows.push(w); }
break;
default: //all
if (w.val === true || w.val === false) { windows.push(w); }
break;
}
}); // end each dp in cSelector
}; // end for each cacheSelector
// if no result
if (windows.length < 1) {
windows.push({
"Name": 'keine',
"id": '',
"val": null
});
}
// prepare speak text
windows.forEach((w) => {
//replace all special characters with underscore
w.Name = w.Name.replace(/:|,|#|;|-|[ ]/g, '_');
//join Name to speakText and
//calculate speak block length and set delimiter
speakText = speakText + w.Name + ((w.Name.length < 100) ? "," : ";");
log(w.id + ' ' + w.Name + ' ' + w.val);
});
speakText = speakVolume + ';offene Fenster oder Türen,' + speakText;
log('speakText: ' + speakText);
//alexa speak
setTimeout(function () {
setState("alexa2.0.Echo-Devices." + getState('alexa2.0.History.serialNumber').val + ".Commands.speak", speakText);
}, 2000);
}
on({ id: 'javascript.0.Alexa-trigger.vOpenWindows', change: "any" }, function (obj) {
countOpenwindows();
});
Das Skript ist mehr mit der heissen Nadel und war mal ne Vorlage um alle offenen oder geschlossenen Fenster auszulesen. Tut es aber. Und wie das meist mit Improvisationen ist...