NEWS
[gelöst] timerId von setTimeout in einem Datenpunkt speichern
-
Moin, Moin,
in einem Skript möchte ich die timerId eines gestarten Timers in einem Datenpunkt speichern, um diesen bei Bedarf wieder zu terminieren. Da die Anzahl der betroffenen Geräte (WebCams) quasi dynamisch ist, schien mir das Speichern in einem Datenpunkt einfacher als ein Datenarray vorzuhalten. Laut Doku ist die TimerId ein Object vom Typ "number". Ich wollte dieses Objekt nun per stringify serialisieren und in den Datenpunkt vom Typ "string" schreiben, aber ich scheitere schon beim serialisieren.
var camID = "javascript.0.alarm.Devices.Cams.Cam1", RecordTime_s = 3; timerID = setTimeout(stopCamAlarm, (RecordTime_s * 1000)); logs(fctName + "setTimeout (timerID: " + JSON.stringify(timerID) + ") stopCamAlarm in " + RecordTime_s + "s for camID: "+ camID, "debug2"); clearTimeout(timerID); function stopCamAlarm() { // was man da so tut }
Beim stringify laufe ich auf folgenden Fehler: TypeError: Converting circular structure to JSON at Object.stringify (native) at script.js.
Auch ein JSON.parse(timerID) hilft nicht –> SyntaxError: Unexpected token o at Object.parse (native) at script.js
Ist das Objekt der timerId so komplex?
Wie macht ihr das?
Ich habe in der Diskussion zum http://forum.iobroker.net/viewtopic.php?f=22&t=1878&hilit=settimeout#p16032 gesehen, dass die timerId's in einem Array-Objekt gespeichert wurden.
Ist das die einzige Möglichkeit?
Danke und Gruß
GH
-
Ich denke eher das es ein "Native" Typ ist und das nicht geht … versuch mal "new Number(timerId)" zu machen ... geht das?
-
Die Scriptengine sagt "Do not use Number as a constructor."
var XX = new Number(timerID);
XX == null
Also leider nicht
-
in einem Skript möchte ich die timerId eines gestarten Timers in einem Datenpunkt speichern, um diesen bei Bedarf wieder zu terminieren. `
Solange das Skript aktiv ist, ist die in dem Skript global deklarierte timerId gültig und kann zum Stoppen des Timers verwendet werden. Wozu also die Speicherung in einem Datenpunkt ? -
Im Prinzip hast du Recht.
Allerdings sind je nach Umgebung (Skript läuft nicht nur beim mir zu Hause) mehr oder weniger Cams aktiv und für jede wird bei einem Alarm (durch Bewegungsmelder) ein Timer gestartet, der den Alarm nach einer festgelegten Zeit zurücksetzt und damit auch die Aufnahmefuntion der jeweiligen Cam. Und da ich in dem Skript an verschiedenen Stellen Daten schreibe und lese, hat sich das mit dem Datenpunkt angeboten.
Ich hatte an dieser Stelle auch überhaupt nicht mit einem Problem gerechnet und da ich bei ioBroker und js Einsteiger bin, würde mich das technisch schon interessieren, warum ich die timerID als Objekt nicht serialisieren und speichern kann.
Bin ich der Erste, der die timerID in einen Datenpunkt schreiben möchte?
Als Ausweg sehe ich im Moment dann nur das Speichern in einem Array.
-
Habe jetzt die timerIDs in einem dynamischen Array gespeichert, ist eigentlich auich die bessere Lösung, dan die IDs nach dem Tot des Skriptes keine Relevanz haben.
-
Habe jetzt die timerIDs in einem dynamischen Array gespeichert, ist eigentlich auich die bessere Lösung, dan die IDs nach dem Tot des Skriptes keine Relevanz haben. `
Hallo,ich versuche gerade genau so einen Fall zu lösen. Kannst Du mir schreiben, wie Du es gelöst hast, also einen Auszug aus Deinem Skript. Ich stehe gerade auf dem Schlauch wie Deine Lösung aussieht.
-
am Anfang des Skriptes eine Variable für die Timer deklariert.
. . . var aTimer[]; . . .
Bei mir im Skript geht es um die Steuerung der Aufnahmezeiten bei Kameras im Alarmfall. D. h. bei einer Alarmierung soll die Kamera x Sekunden aufnehmen und wieder abschalten.
In einer Subscription auf dieses Alarmsignal wird das Objektarray dann entsprechend zugegriffen.
aTimer[cam_name] = null; subscribe({id: camID + ".alarm", change:'ne'}, function (obj) { . . . if(obj.state.val === true) { // set alarm . . . if(aTimer[cam_name]) { // stop old timer clearTimeout(aTimer[cam_name]); } // RecordTimer für Cam starten aTimer[cam_name] = setTimeout(function(){ stopCamAlarm(camID); }, (RecordTime_s * 1000)); } else { var t1 = getState(camID + ".alarm_ack").ts; var tdiff = new Date().getTime() - t1; if(tdiff > RecordMinTime_s) { stopCamAlarm(camID); // stop timer if(aTimer[cam_name]) { // stop timer clearTimeout(aTimer[cam_name]); aTimer[cam_name] = null; } } else { // mindest Aufzeichnungszeit nicht erreicht, nicht abschalten } }
Hoffe, das hilft dir so weiter.
Gruß
GH
-
Hallo,
ja, hat geholfen.
Allerdings musste ich das Array anders definieren, Deine Version zeigt schon ein Ausrufezeichen und beim Speichern kam dann eine Fehlermeldung.
Mit```
var aTimer = [];[/code]
geht es.Danke für die Hilfe.