NEWS
on({time: Cron}, Funktion, Werte) ignoriert Werte
-
Das Schedule-Statement bietet bedauerlicherweise - im Gegensatz zum on-Statement - keine Möglichkeit, der angegebenen Callback-Funktion Parameterwerte mitzugeben. Ich freute mich daher, in der iobroker-Javascript-Dokumentation den Hinweis entdeckt zu haben, dem on-Statement als Pattern ein cron-Muster mitgeben zu können: on({time: Cron}, Funktion, Werte). Schade, dass es nicht funktioniert, wie folgendes Beispiel zeigt:
function Log(Text) { console.log('Text = ' + Text); } on({time: '* * * * *'}, Log, 'Hallo');
Folgendes wird nämlich geloggt:
javascript.0 script.js.common.Allgemeines.OnTest: Text = undefined
Schade! Muss ich denn jetzt alle vorgesehenen schedule-Aufrufe wirklich durch einen setTimeout mit einer berechneten Zeitdifferenz ersetzen, wobei die setTimeout-Aufrufe und deren Zeitdifferenz-Berechnung geeignet zyklisch wiederholt werden müssen?
-
@hsteinme
Man kann durchaus Parameter übergeben, indem man die gewünschte Funktion innerhalb der anonymen Funktion aufruft.function Log(Text) { console.log('Text = ' + Text); } schedule('* * * * *', function() {Log('Hallo');});
@hsteinme sagte in on({time: Cron}, Funktion, Werte) ignoriert Werte:
im Gegensatz zum on-Statement
Das on-Statement gibt an die Callback-Funktion einen festen Wert zurück: Das Datenpunkt-Objekt.
In der time-Version verhält es sich genauso wie schedule(). -
Danke für den Hinweis. Im Beispiel meines natürlich sehr vereinfachten Testskripts greift dieser Hinweis auch. Da ich aber "im richtigen Leben" statt eines konstanten Wertes einen variablen Wert übergeben möchte, der sich in der Zeit zwischen schedule-Definition und schedule-Ausführung auch noch ändern kann, kann ich ihn dort leider nicht anwenden.
-
@hsteinme sagte:
kann ich ihn dort leider nicht anwenden.
Wieso nicht ? Anstelle von 'Hallo' kann auch eine Variable übergeben werden.
-
Klar kann ich eine Variable dort hinschreiben, aber Variablen sind Schall und Rauch. Auf deren Inhalt kommt's doch an. Ich will dem schedule-Aufruf doch den Variableninhalt zum Aufruf-Zeitpunkt mitgeben. Daher sollte die Callback-Funktion auch den Inhalt zum Aufruf-Zeitpunkt verwenden und nicht den Inhalt zur Laufzeit der Callback-Funktion.
Beispiel:
function Log(Text) { console.log('Text = ' + Text); } var Nachricht; Nachricht = 'Hallo'; schedule('* * * * *', function() {Log(Nachricht);}); Nachricht = 'Guten Tag!';
Ausgabe leider:
javascript.0 script.js.common.Allgemeines.OnTest: Text = Guten Tag!
-
Hallo, ich bin blutiger Anfänger was programmieren angeht und bin mir daher nicht sicher ob ich richtig verstanden hab was du genau meinst
Es gibt ein Astro Skript: https://forum.iobroker.net/topic/2423/astro-tageszeit-abfragen-und-in-datenpunkt-eintragen/331
Dort wird unter anderem ein Datenpunkt geschrieben, der die aktuelle Tageszeit beinhaltet. Der inhalt ändert sich also je nach Tageszeit. Das ist doch sowas ähnliches wie du suchst oder nicht? Vielleicht kannst du dir ja aus dem dortigen Skript das rausziehen, was du brauchst.
-
@hsteinme
mE wäre der Bind-Befehl der richtige für dich. Da kannst du Paramerter bei Funktionsdefinition mitgeben, auch wenn die Funktion zeitverzögert ausgeführt wirdfunction Log(Text,p2,p3) { console.log('Text = ' + Text); } var Nachricht; Nachricht = 'Hallo'; schedule('* * * * *', function() {Log.bind(this,Nachricht ,"p1","p2");}); Nachricht = 'Guten Tag!';
https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
p1,p2 hab ich angefügt um zu zeigen, das man auch mehrere parameter übergeben kann.
-
@Dominik F.:
Meine Fragestellung behandelt Uhrzeiten (3:57, 21:12,...), das dortige Skript behandelt jedoch Tageszeiten (Morgendämmerung, Sonnenaufgang, Tag, ...). Das ist also ein völlig anderes Thema. Die dort verwendete Logik setzt auf einem minütlich aufzurufenden schedule auf - der aber nun mal keine Möglichkeit bietet, der Callback-Funktion jetzige Werte als Parameter mitzugeben.@OliverIO:
Wenn ich Dein geändertes Skript bei mir laufen lasse, kommt kein einziger Logeintrag zustande, weder ein vom console.log des Skriptes durchgeführter noch irgendwelche Fehlerhinweise von übergeordneten "Mächten".Ich habe mich aber mittlerweile mit meinem weiter oben skizzierten Ansatz abgefunden (und auch bereits umgesetzt), die vorgesehenen schedule-Aufrufe jeweils durch setTimeout-Statements mit berechneten Zeitdifferenzen zu ersetzen, wobei die setTimeout-Aufrufe und deren Zeitdifferenz-Berechnungen geeignet zyklisch wiederholt werden müssen.
Herzlichen Dank für alle hier gebrachten Vorschläge.
-
@hsteinme
Dann sofunction Log(Text) {
console.log('Text = ' + Text);
}var Nachricht;
Nachricht = 'Hallo';
schedule('*/10 * * * * *', Log.bind(this,"hallo"));
Nachricht = 'Guten Tag!';schedule ist hier auf 10 Sekunden eingestellt, damit man nicht so lange warten muss
-
Danke schön, OliverIO! Dieses Beispielskript läuft und liefert auch das gewünschte Ergebnis - auch wenn ich die Text-Konstante "hallo" durch die Text-Variable Nachricht ersetze.