JavaScript (ECMA 2021) Rules which is triggered by a motion sensor but only runs once a day

Dear community,

I am struggeling with a ECMA 2021 JS rule which is triggered by a motion sensor but only runs once a day.

var InternScharf = items.getItem("EMA_Scharfschaltung_InternScharf");
var EchoEgNotifVol = items.getItem("Echo_Wohnzimmer_NotificationVolume");
var EchoOgNotifVol = items.getItem("Echo_Obergeschoss_NotificationVolume");
var EchoEgTtsVol = items.getItem("Echo_Wohnzimmer_TTS_Volume");
var EchoOgTtsVol = items.getItem("Echo_Obergeschoss_TTS_Volume");
var EchoEgVol = items.getItem("Echo_Wohnzimmer_Volume");
var EchoOgVol = items.getItem("Echo_Obergeschoss_Volume");

var letzterDurchlauf = time.ZonedDateTime.now();
var jetzt = time.ZonedDateTime.now();

//this.RunIndicator = (this.RunIndicator === undefined) ? 0 : this.RunIndicator;

this.letzterDurchlauf = (this.letzterDurchlauf === undefined) ? null : letzterDurchlauf;

console.log("Letzter Durchlauf (vor Schleife):", letzterDurchlauf);
console.log("Jetzt (vor Schleife):", jetzt);


if (this.letzterDurchlauf.isBefore(jetzt.minusHours(12)) || this.letzterDurchlauf === null) {
  if (InternScharf.state == "ON") {
    InternScharf.sendCommand("OFF");
  }

  EchoEgNotifVol.sendCommand("20");
  EchoOgNotifVol.sendCommand("20");
  EchoEgTtsVol.sendCommand("20");
  EchoOgTtsVol.sendCommand("20");
  EchoEgVol.sendCommand("20");
  EchoOgVol.sendCommand("20");

  console.log("Letzter Durchlauf (Schleife) 1.Wert:", this.letzterDurchlauf);
  this.letzterDurchlauf = time.ZonedDateTime.now();
  console.log("Letzter Durchlauf (Schleife) 2.Wert:", this.letzterDurchlauf);
}

//RunIndicator++;
console.log("Letzter Durchlauf (ausserhalb Schleife):", this.letzterDurchlauf);```

provides the following log output

2022-01-26 18:04:39.445 [WARN ] [.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.

2022-01-26 18:04:40.043 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (vor Schleife): “2022-01-26T18:04:40.027+01:00[SYSTEM]”

2022-01-26 18:04:40.046 [INFO ] [org.openhab.automation.script ] - Jetzt (vor Schleife): “2022-01-26T18:04:40.034+01:00[SYSTEM]”

2022-01-26 18:04:40.055 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (ausserhalb Schleife): “2022-01-26T18:04:40.027+01:00[SYSTEM]”

2022-01-26 18:04:55.901 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (vor Schleife): “2022-01-26T18:04:55.894+01:00[SYSTEM]”

2022-01-26 18:04:55.903 [INFO ] [org.openhab.automation.script ] - Jetzt (vor Schleife): “2022-01-26T18:04:55.897+01:00[SYSTEM]”

2022-01-26 18:04:55.909 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (ausserhalb Schleife): “2022-01-26T18:04:55.894+01:00[SYSTEM]”


How can I assign the time of the last rule execution in the current context?

Thanks in advance!

Br, Thomas

As far as I know there is no OOTB capability for this.
Either store the execution time into a global variable or into an item

It’s not clear what’s wrong just by looking at the code and the logs. The logs show it’s doing what you are asking it to do.

If I imply from your question that what you need is to save a variable from one run of the rule to the next you ca use an Item or use the cache.

I want to store the last successful run (one of the conditions of the if clause is met) to the variable “letzterDurchlauf”. When the rule is triggered next time from the motion sensor I want to access the DateTime of the last successful run using this.letzterDurchlauf. But the variable “letzterDurchlauf” does not get the DateTime set in the last run with "this.letzterDurchlauf = time.ZonedDateTime.now(). It contains the value of the initialization of the actual run and not the value of the last run.

The workaround would be to store the state in a switch item which will be set to OFF at midnight and set to ON after the last successful run. But I wonder that I cannot use the context “this” to store the last execution which I set to “now” after the last successful run. I know that this way would not “survive” a restart or changes of the rule - which is stated here - OH 3 Examples: Writing and using JavaScript Libraries in MainUI created Rules

this.letzterDurchlauf and letzterDurchlauf are the same reference inside your Script-instance. And the first thing you do is to set letzterDurchlauf to now.
If I’m not wrong something like this is what you want:

var jetzt = time.ZonedDateTime.now();
// Das "if" ist keine Schleife sondern eine Bedingung
console.log("Letzter Durchlauf (vor Schleife):", this.letzterDurchlauf);
console.log("Jetzt (vor Schleife):", jetzt);
if (this.letzterDurchlauf === undefined || this.letzterDurchlauf.isBefore(jetzt.minusHours(12))) {
  // this.letzterDurchlauf could be undefined at this point
  console.log("Letzter Durchlauf (Schleife) 1.Wert:", this.letzterDurchlauf);
  this.letzterDurchlauf = jetzt;
  
  console.log("Letzter Durchlauf (Schleife) 2.Wert:", this.letzterDurchlauf);
}
console.log("Letzter Durchlauf (ausserhalb Schleife):", this.letzterDurchlauf);

Be aware that your statement is true every 12 hours.

Hi David,
for sure if contains a condition and not a loop - I just copied the comments from a loop and did not changed it for now :slight_smile:

Just tried your suggestion (and changed the condition to jetzt.minusMinutes(1)) and the result is the following:
2022-01-26 21:45:56.073 [INFO ] [org.openhab.automation.script ] - this.Letzter Durchlauf (vor Zuweisung): “2022-01-26T21:45:56.060+01:00[SYSTEM]”

2022-01-26 21:45:56.075 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (vor Bedingung): “2022-01-26T21:45:56.060+01:00[SYSTEM]”

2022-01-26 21:45:56.077 [INFO ] [org.openhab.automation.script ] - this.Letzter Durchlauf (vor Bedingung): “2022-01-26T21:45:56.060+01:00[SYSTEM]”

2022-01-26 21:45:56.079 [INFO ] [org.openhab.automation.script ] - Jetzt (vor Bedingung): “2022-01-26T21:45:56.066+01:00[SYSTEM]”

2022-01-26 21:45:56.086 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (ausserhalb Bedingung): “2022-01-26T21:45:56.060+01:00[SYSTEM]”

2022-01-26 21:47:25.464 [INFO ] [org.openhab.automation.script ] - this.Letzter Durchlauf (vor Zuweisung): “2022-01-26T21:47:25.454+01:00[SYSTEM]”

2022-01-26 21:47:25.466 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (vor Bedingung): “2022-01-26T21:47:25.454+01:00[SYSTEM]”

2022-01-26 21:47:25.468 [INFO ] [org.openhab.automation.script ] - this.Letzter Durchlauf (vor Bedingung): “2022-01-26T21:47:25.454+01:00[SYSTEM]”

2022-01-26 21:47:25.470 [INFO ] [org.openhab.automation.script ] - Jetzt (vor Bedingung): “2022-01-26T21:47:25.459+01:00[SYSTEM]”

2022-01-26 21:47:25.476 [INFO ] [org.openhab.automation.script ] - Letzter Durchlauf (ausserhalb Bedingung): “2022-01-26T21:47:25.454+01:00[SYSTEM]”

The context “this” does not keep the value of the variable between the different runs. That’s what I wonder about.

Strange. When I run the Skeleton with isBefore(jetzt.minusSeconds(5)) I get the expected results. Unfortunately I can’t help you here.

Logs

First run:

2022-01-26 22:16:31.819 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (vor Schleife): undefined

2022-01-26 22:16:31.838 [INFO ] [org.openhab.automation.script       ] - Jetzt (vor Schleife): "2022-01-26T22:16:31.566+01:00[SYSTEM]"

2022-01-26 22:16:31.840 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (Schleife) 1.Wert: undefined

2022-01-26 22:16:31.842 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (Schleife) 2.Wert: "2022-01-26T22:16:31.566+01:00[SYSTEM]"

2022-01-26 22:16:31.844 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (ausserhalb Schleife): "2022-01-26T22:16:31.566+01:00[SYSTEM]"

Second run <5 seconds later:

2022-01-26 22:16:35.024 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (vor Schleife): "2022-01-26T22:16:31.566+01:00[SYSTEM]"

2022-01-26 22:16:35.027 [INFO ] [org.openhab.automation.script       ] - Jetzt (vor Schleife): "2022-01-26T22:16:35.010+01:00[SYSTEM]"

2022-01-26 22:16:35.047 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (ausserhalb Schleife): "2022-01-26T22:16:31.566+01:00[SYSTEM]"

Third run ~15 seconds after 2nd run:

2022-01-26 22:16:45.044 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (vor Schleife): "2022-01-26T22:16:31.566+01:00[SYSTEM]"

2022-01-26 22:16:45.046 [INFO ] [org.openhab.automation.script       ] - Jetzt (vor Schleife): "2022-01-26T22:16:45.034+01:00[SYSTEM]"

2022-01-26 22:16:45.057 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (Schleife) 1.Wert: "2022-01-26T22:16:31.566+01:00[SYSTEM]"

2022-01-26 22:16:45.059 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (Schleife) 2.Wert: "2022-01-26T22:16:45.034+01:00[SYSTEM]"

2022-01-26 22:16:45.062 [INFO ] [org.openhab.automation.script       ] - Letzter Durchlauf (ausserhalb Schleife): "2022-01-26T22:16:45.034+01:00[SYSTEM]"
1 Like

Again, either use a DateTime Item to store this value, or use the cache.

1 Like

Thanks David and Rich for your suggestions. I found the fault. The order of the conditions in the IF statement is important. After I gave the conditions of undefined and null to the first and second place and the .isBefore condition to the last place, I got the correct result.

Br, Thomas