NEWS
[ gelöst ] Licht bei Bewegung und clearTimeout(id) bei Lichtschalter ein innerhalb der Einschaltzeit
-
Hallo Leute, ich habe ein Script geschrieben für Licht bei Bewegung im Flur.
Das Licht schaltet nach 30.sec wieder ab.
Einschalten bzw. Einschaltbefehl kommt nur durch wenn bestimmte Bedingungen gegebn sind.
Wenn ich jetzt innerhalb der 30 Sekunden das Licht einschalte möchte ich den Ausschaltbefehl welchen ich über setTimeout gebe wieder zurück setzen.
Ich habe zum Ein- und Ausschalten 2 HM Schalter, einen Schaltaktor und einen Sender…Beim Sender könnte ich auf press short triggern um das clearStateDelayed für die entsprechnde ID auszuführen...Für den Schaltaktor fehlt mir die Phantasie, da ich dessen ID ja für mein Script benutze.
Script siehe unten...Ne Idee wie ich das am Besten mache?
//Block für Licht bei Bewegung Flur / Haustür innen on( 'wiffi-wz.0.root.192_168_XXX_XXX.wz_motion_left', function (obj) { var HelligkeitFlur = getState('wiffi-wz.0.root.192_168_xxx_xxx.wz_lux').val; var LichtFlur = getState('hm-rpc.0.OEQ115xxxxx.1.STATE').val; var motionFlur = getState('wiffi-wz.0.root.192_168_xxx_xxx.wz_motion_left').val; var jemandDa = getState('javascript.0.Anwesenheitssteuerung.BewohnerAnwesend').val; var Alarm = getState('javascript.0.alarm.out.alarm_intern').val; var Brand = getState ('javascript.0.Status.Brandmelder.Anzahl_melden_Brand').val; if (motionFlur === true && HelligkeitFlur <= 0.5 && LichtFlur === false && jemandDa === true && Alarm === false && Brand === 0) { setState('hm-rpc.0.OEQ11xxxxx.1.STATE', true); if('hm-rpc.0.OEQ115xxxxx.1.STATE', true); setTimeout(function(){setState('hm-rpc.0.OEQ115xxxxx.1.STATE', false)},30*1000); console.log('Licht Flur / Haustür Innen ein bei Bewegung'); } });
-
Hallo,
hab mal etwas gebastelt.
const idAktor = 'hm-rpc.0.OEQ11xxxxx.1.STATE'; on( 'wiffi-wz.0.root.192_168_XXX_XXX.wz_motion_left', function (obj) { var HelligkeitFlur = getState('wiffi-wz.0.root.192_168_xxx_xxx.wz_lux').val; var LichtFlur = getState(idAktor).val; var motionFlur = obj.state.val; // ist ja das Objekt in dieser Subscription var jemandDa = getState('javascript.0.Anwesenheitssteuerung.BewohnerAnwesend').val; var Alarm = getState('javascript.0.alarm.out.alarm_intern').val; var Brand = getState ('javascript.0.Status.Brandmelder.Anzahl_melden_Brand').val; if (motionFlur === true && HelligkeitFlur <= 0.5 && LichtFlur === false && jemandDa === true && Alarm === false && Brand === 0) { setState(idAktor, true, function() { // Schaltaktor ein und danach Funktion ausführen log('Licht Flur / Haustür Innen ein bei Bewegung'); setStateDelayed(idAktor, false, 30 * 1000, function() { // nach 30s ausschalten und dann nach dem Ausschalten ... log("Aktor nach 30s wieder ausgeschaltet"); // ... Logausgabe }); }); } }); // zweite Subscription mit den manuellen Tastern/Sendern (es können auch als Array oder mit Regex mehrere Trigger angegeben werden) const idTaster = "HM-AKTOR-ID-HIER-EINTRAGEN"; // bitte anpassen on({ id: idTaster, val: true }, function (obj) { clearStateDelayed(idAktor); // Alle Timer des Lichtaktors löschen setState(idAktor, false); // Aktor ausschalten });
Solange in der If-Abfrage weiterhin der Zustand des Aktors auf false geprüft wird, kann der EInschaltbefehl nicht verlängert werden. Ein Verlängerung wäre ja nur bei Licht an möglich…
Gruß
Pix
-
Mit welchem Aktor ist denn das Licht geschaltet?
Ich hab ziemlich das gleiche Szenario im Badezimmer, mit dem Problem, dass der Taster des Homematic-Markendimmers halt nicht unabhängig vom Aktor ist, sprich man kann nicht so einfach auf den Taster subscriben.
Ich hab das dann so gelöst, dass der Bewegungsmelder bei Bewegung gleich am Homematic-Aktor die Einschaltdauer mitsetzt. Bei Betätigung des Tasters wird die Einschaltzeit am Aktor übersteuert, und das kann man bei erneuter Bewegung abfangen.
Sprich:
- Bewegung: Wenn (Licht aus) => Einschaltdauer 300s, einschalten
Wenn (Licht an und Einschaltdauer gesetzt) => Einschaltdauer wieder auf 300s
Bei Bewegung + Licht an und KEINE Einschaltdauer muss vom Schalter aus übersteuert worden sein, also muss man auch manuell wieder ausschalten
var debuglevel = 4; var debugchannel = 'info'; function handleOn(data) { var helligkeit = getState("javascript.0.Helligkeit.Helligkeitsstufe"/*Helligkeit.Helligkeitsstufe*/).val; var hell_limit = 2 ; var RolloId = "hm-rpc.0.JEQ1234567.1.LEVEL"/*Rollo Bad OG (West):1.LEVEL*/; var RolloLimit = 25; var is_working = getState("hm-rpc.0.LEQ1233456.1.WORKING"/*Licht Bad OG:1.WORKING*/).val; var is_on = getState("hm-rpc.0.LEQ1233456.1.LEVEL"/*Licht Bad OG:1.LEVEL*/).val>0; var do_it = false; // execute only if light was not set to "on" manually. if (helligkeit <= hell_limit ) { do_it = (is_on == 0) || ((is_on == 1) && (is_working == 1)); } if (getState(RolloId).val < RolloLimit) { do_it = (is_on == 0) || ((is_on == 1) && (is_working == 1)); } dwmlog ("Licht Status: "+is_on+" Helligkeit: "+helligkeit+" Working: "+is_working+" => Schalte Licht: "+do_it,4); if(do_it) { lighton (data); } } function lighton (data){ var timeout = 450; setState( "hm-rpc.0.LEQ1233456.1.ON_TIME"/*Licht Bad OG:1.ON_TIME*/, timeout ); // set timeout setTimeout(function(){ setState( "hm-rpc.0.LEQ1233456.1.LEVEL"/*Licht Bad OG:1.LEVEL*/, 80); // switch on },100); } // Trigger subscribe({ id: "hm-rpc.0.JEQ1332456.1.MOTION", /*Bewegung Nord Kaputt:1.MOTION*/ val: true }, function (data){ dwmlog("Licht Bewegung Bad OG- BWM hat ausgelöst: "+JSON.stringify(data),4); handleOn(data); });
Nur so mal als Ideenspender
CU
Werner
-
Beides Prima Lösungsansätze, Danke sehr für die neuen Ideen…
ich muss mich jetzt nur noch entscheiden welche ich weiter verfolge...
Bei meinem Flur handelt es sich ja um einen Durchgangsraum wo man sich normalerweise nicht länger aufhält...
Aber wenn doch sollte es eben auch auf Dauer eingeschaltet sein können.
@ Pix und Werne Der Schaltaktor selbst ist ebenfalls ein Schaltaktor mit Taster HM-LC-Sw1PBU-FM und der Sender mit Direktverknüpfung zu diesem Aktor ist ein HM-RC-2-PBU-FM .
@Pix Die Lösung von Pix würde schon funktionieren mit clearStateDelayed während der Einschaltzeit könnte man das Licht eingeschaltet lassen bis es ausgeschaltet würde. Dazu nur setState(idAktor, false); // Aktor ausschalten weglassen... Eine erneute Bewegung würde wegen der var LichtFlur = getState(idAktor).val; nicht durchkommen... Somit müsste man manuell ausschalten. Was ja meine Vorraussetzung war.
Die Sache hätte nur einen Haken, das würde nur mit dem Sender Taster funktionieren, nicht mit dem Aktortaster zusätzlich..
Somit hätte ich 2 verschiedene Tasterfunktionn, was meine Frau zum durchdrehen bringen würde...
on({
id: idTaster,
val: true
}, function (obj) {
clearStateDelayed(idAktor); // Alle Timer des Lichtaktors löschen
});
@Werner Deine Idee finde ich auch klasse. Warum nicht den Timer unter Objekten beschreiben...Auf die Idee bin ich noch garnicht gekommen...Da hab ich so viele HM Produkte im Einsatz, aber auf die Idee den internen Timer zu eschreiben bin ich noch nicht gekommen....Man lernt eben nie aus...
Kannst du mir kurz erleutern was du mit dwmlog machst? Würde mich interessieren, da ich über console.log noch nicht hinaus bin...
Super Tipps von euch beiden Danke sehr!!!
-
Hallo Werner,
hab mal dein Script genommen und angepasst…
hier der log:
javascript.0 2018-08-23 13:31:57.245 info script.js.common.Alarmanlage.Logik: checkSensor group:motion javascript.0 2018-08-23 13:31:57.239 info script.js.common.motion.BewegungInnen: Bewegung erkannt, Trigger für Alarm auf true gesetzt javascript.0 2018-08-23 13:31:57.237 info script.js.common.motion.LichtBeiBewegung: Jemand Da: true Alarm: false Brand 0 Licht Status: false Helligkeit: 10.87 Working: false => Schalte Licht: false javascript.0 2018-08-23 13:31:57.236 info script.js.common.motion.LichtBeiBewegung: Licht Bewegung Flur EG - BWM hat ausgelöst': {"id":"wiffi-wz.0.root.192_168_1_54.wz_motion_left","newState":{"val":true,"ts":1535023917212,"ack":true,"lc":15 javascript.0 2018-08-23 13:31:57.234 info script.js.common.motion.BewegungInnen: Bewegung erkannt, Trigger für Alarm auf true gesetzt
und unten die Anpassung…
var debuglevel = 4; var debugchannel = 'info'; function handleOn(data) { var helligkeit = getState('wiffi-wz.0.root.192_168_XX_xxx.wz_lux').val; var hell_limit = 12 ; var is_on = getState('hm-rpc.0.OEQ115xxxxx.1.STATE').val; // var motionFlur = getState('wiffi-wz.0.root.192_168_xxx_xxxx.wz_motion_left').val; var jemandDa = getState('javascript.0.Anwesenheitssteuerung.BewohnerAnwesend').val; var Alarm = getState('javascript.0.alarm.out.alarm_intern').val; var Brand = getState ('javascript.0.Status.Brandmelder.Anzahl_melden_Brand').val; var is_working = getState("hm-rpc.0.OEQ115xxxxx.1.WORKING").val; var do_it = false; // execute only if light was not set to "on" manually. // var RolloId = "hm-rpc.0.JEQ12xxxxxx.1.LEVEL"; // var RolloLimit = 25; if (helligkeit <= hell_limit && jemandDa === true && Alarm === false && Brand === 0 ) { do_it = (is_on === false) || ((is_on === true) && (is_working === true)); } // if (getState(RolloId).val < RolloLimit) { // do_it = (is_on === 0) || ((is_on === 1) && (is_working === 1)); // } console.log ("Jemand Da: "+jemandDa+" Alarm: "+Alarm+" Brand "+Brand+" Licht Status: "+is_on+" Helligkeit: "+helligkeit+" Working: "+is_working+" => Schalte Licht: "+do_it,4); if(do_it) { lighton (data); } } function lighton (data){ var timeout = 30; setState( "hm-rpc.0.OEQ11xxxxx.1.ON_TIME", timeout ); // set timeout setTimeout(function(){setState( "hm-rpc.0.OEQ1xxxxxx.1.STATE", true)},30); // switch on } //Trigger subscribe({ id: "wiffi-wz.0.root.192_168_xxxx_xxxx.wz_motion_left", val: true }, function (data){ console.log("Licht Bewegung Flur EG - BWM hat ausgelöst': "+JSON.stringify(data),4); handleOn(data); });
Bin mir mit den Timeouts nicht ganz sicher.. kannst du mir kurz erklären, warum du unterschiedliche genommen hast?
Ansonsten funktioniert prima….Danke!!!
-
Servus,
Du meinst die lighton() Funktion oder?
function lighton (data){ var timeout = 30; setState( "hm-rpc.0.OEQ1157843.1.ON_TIME", timeout ); // set timeout setTimeout(function(){setState( "hm-rpc.0.OEQ1157843.1.STATE", true)},30); // switch on }
Das setTimeout da drin dient nur dazu, dass sicher der ON_TIME Datenpunkt vor dem STATE Datenpunkt gesetzt wird. Hatte ich auf 100ms, Du hast's jetzt auf 30ms (MILLISEKUNKDEN!!) gesetzt.
Wahrscheinlich ist's völlig wurscht
Die Zeilen mit debuglevel und debugchannel kannst rauswerfen, die sind für meine dwmlog() Funktion.
CU
Werner
-
Sorry, die Frage nach dwmlog() übersehen …
function dwmlog( message, level, channel) { if (typeof channel === 'undefined') { channel = debugchannel; } if ( typeof level === 'undefined') { level = debuglevel; } if ( debuglevel >= level ) { log (message, channel ); } }
ist bei mir in "global" gespeichert und liefert mir einfach abschaltbare Ausgaben auf der Konsole und im Log.
Ich mache beim Entwickeln immer gern sehr viele Ausgaben in den Code rein, einfach um nachvollziehen zu können was los ist.
Das müllt mir dann später das Log voll.
Deswegen mach ich alle Ausgaben die für die Entwicklungs- und Fehlersuche sind mit dwmlog (…,4) und schalte dann später den debuglevel auf 2 oder 1.
Man muss halt nur vor jedes Script
var debuglevel = 4; var debugchannel = 'info';
schreiben … mit debuglevel entsprechend dem Entwicklungsstand angepasst.
Variablendefinitionen werden aus "global" nicht übernommen.
CU
Werner
-
Prima, vielen lieben Dank für die Ausführung…
-
Script finktioniert dank der hm hardware und der timer und working objekte sehr gut..
-
Thema gelöst