NEWS
[Gelöst]Subscribe/on und Arrays
-
Hallo zusammen,
ich bin gerade dabei, von FHEM auf ioBroker zu wechseln und habe ein kleines Problem mit einem ersten kleinen Script, welches die letzte Öffnung des jeweiligen Fenstersensors in einen state wegschreiben soll.
Die states habe ich alle entsprechend angelegt (siehe ganz unten) und es funktioniert auch, bis auf eine "Kleinigkeit". Egal welches Fenster ich öffne, es wird immer in die states von fs.length - 1 geschrieben, also KellerTuer.
`var fs = []; fs.push({id:"OEQ0XXXX1", name:"GaesteWC"}); fs.push({id:"MEQ0XXXX2", name:"Bad"}); fs.push({id:"MEQ0XXXX3", name:"BueroTerrassenTuer"}); fs.push({id:"OEQ0XXXX4", name:"Buero"}); fs.push({id:"MEQ0XXXX5", name:"KuecheTerrassenTuer"}); fs.push({id:"OEQ0XXXX6", name:"Kueche"}); fs.push({id:"MEQ0XXXX7", name:"WohnzimmerTerrassenTuer"}); fs.push({id:"OEQ0XXXX8", name:"WohnzimmerGartenLinks"}); fs.push({id:"OEQ0XXXX9", name:"WohnzimmerGartenRechts"}); fs.push({id:"OEQ0XXX10", name:"WohnzimmerStrasseLinks"}); fs.push({id:"OEQ0XXX11", name:"WohnzimmerStrasseRechts"}); fs.push({id:"OEQ0XXX12", name:"SchlafzimmerLinks"}); fs.push({id:"OEQ0XXX13", name:"SchlafzimmerRechts"}); fs.push({id:"MEQ0XXX14", name:"EingangsTuer"}); fs.push({id:"OEQ0XXX15", name:"KellerTreppe"}); fs.push({id:"OEQ0XXX16", name:"KellerDusche"}); fs.push({id:"OEQ0XXX17", name:"KellerZimmerRechts"}); fs.push({id:"OEQ0XXX18", name:"KellerZimmerLinks"}); fs.push({id:"OEQ0XXX19", name:"KellerTuer"}); for (var i=0; i<fs.length; i++){/var/triggername="hm-rpc.0." +/fs[i].id/".1.state";/setnamea="Fenstersensoren." fs[i].name/".open";/setnameb="Fenstersensoren." ".lastopen";/log("trigger:/"/setnamea:/setnameb:/setnameb);/on({id:/triggername,/change:/"ne"},/function(obj)/{/setstate(setnamea,/obj.state.val);/if(obj.state.val="==" true){/zeitpunkt="formatDate(obj.state.ts," "dd.mm.yyyy/hh:mm");/setstate(setnameb,/zeitpunkt);/}/});/<e=""></fs.length;>` P.S.: Ich bin mir bewusst, dass es über RegExp auch einfacher geht, aber es geht mir hier erstmal um ein Grundverständnis, warum die in der Schleife angelegten subscribes nicht, wie vom mir erwartet, funktionieren. Die jeweiligen Objekte unter javascript.0 sehen folgendermaßen aus: `~~[code]~~/* Einmaliges Anlegen der Objekte for (var i=0; i<fs.length; i++){/var/name="Fenstersensoren." +/fs[i].name;/createstate(name,/fs[i].id);/createstate(name/".open",/false,/{read:/true,/write:/name:/"fenster/offen?",/type:/"boolean",/def:/false});/".lowbat",/"batterie/leer/?",/".lastopen",/"n/a",/"beschreibung",/"string",/a"});/}/*/<e=""></fs.length;>`[/i][/i][/code][/i][/i][/i]
-
Egal welches Fenster ich öffne, es wird immer in die states von fs.length - 1 geschrieben, also KellerTuer. `
Ja, das ist bei JavaScript und Schleifen so ein ding. Zu dem Zeitpunkt wo deine on-Funktion ausgeführt wird, ist i = fs.length-1.Du hast zwei (drei) Möglichkeiten:
1. Wenn dein NodeJS neu genug ist, ersetze alle "var" durch "let" und es sollte funktionieren.
2. Aktualisiere dein NodeJS und zurück zu 1.
3. Ansonsten lagere den Schleifeninhalt in eine eigene Funktion aus:
`var fs = []; fs.push({id:"OEQ0XXXX1", name:"GaesteWC"}); fs.push({id:"MEQ0XXXX2", name:"Bad"}); fs.push({id:"MEQ0XXXX3", name:"BueroTerrassenTuer"}); fs.push({id:"OEQ0XXXX4", name:"Buero"}); fs.push({id:"MEQ0XXXX5", name:"KuecheTerrassenTuer"}); fs.push({id:"OEQ0XXXX6", name:"Kueche"}); fs.push({id:"MEQ0XXXX7", name:"WohnzimmerTerrassenTuer"}); fs.push({id:"OEQ0XXXX8", name:"WohnzimmerGartenLinks"}); fs.push({id:"OEQ0XXXX9", name:"WohnzimmerGartenRechts"}); fs.push({id:"OEQ0XXX10", name:"WohnzimmerStrasseLinks"}); fs.push({id:"OEQ0XXX11", name:"WohnzimmerStrasseRechts"}); fs.push({id:"OEQ0XXX12", name:"SchlafzimmerLinks"}); fs.push({id:"OEQ0XXX13", name:"SchlafzimmerRechts"}); fs.push({id:"MEQ0XXX14", name:"EingangsTuer"}); fs.push({id:"OEQ0XXX15", name:"KellerTreppe"}); fs.push({id:"OEQ0XXX16", name:"KellerDusche"}); fs.push({id:"OEQ0XXX17", name:"KellerZimmerRechts"}); fs.push({id:"OEQ0XXX18", name:"KellerZimmerLinks"}); fs.push({id:"OEQ0XXX19", name:"KellerTuer"}); function buildTrigger(trigger) { var triggername = "hm-rpc.0." + trigger.id + ".1.STATE"; var setnameA = "Fenstersensoren." + trigger.name + ".open"; var setnameB = "Fenstersensoren." + trigger.name + ".lastopen"; //log("Trigger: " + triggername + " setnameA: " + setnameA + " setnameB: " + setnameB); on({id: triggername, change: "ne"}, function(obj) { setState(setnameA, obj.state.val); if(obj.state.val === true){ var zeitpunkt = formatDate(obj.state.ts, "DD.MM.YYYY hh:mm"); setState(setnameB, zeitpunkt); } }); } for (var i=0; i<fs.length; i++){/buildtrigger(fs[i]);/}/<e=""></fs.length;>` Es würde auch gehen, wenn du direkt auf ein Array der State-IDs lauschst und dann in Abhängigkeit von der ID des geänderten States die richtige Aktion wählst.[/i]
-
Vielen Dank für die schnelle Antwort AlCalzone,
Du hast meinen Sonntag gerettet
-
Alternativ ( so mache ich es an ein paar stellen) mach ein Mapping Objekt. Key=en überwachten statenamen ( wie dein Array das erst nur vollständig mit „hm-rpc. …” und value die zielvariable. Dann kannst du in der on-Funktion obj.id nehmen und einfach genetisch die zielvariable auslesen
-
Sowas meinte ich mit
> in Abhängigkeit von der ID des geänderten States die richtige Aktion