Javascript rule to calculate tv times

Hello community,
I upgraded to OH3 and now it is time to tranform my tv time calculation rule to javascript. At this point I have a Problem to update an item which is stored in an influxdb.
I have an item called “tv_on_time_marvis” withe following declaration:

DateTime tv_on_time_marvis "Time is [%1$tH:%1$tM]"

Here is my rule (it is not finished yet):

// calculate tv times marvis

var logger = Java.type('org.slf4j.LoggerFactory').getLogger('org.openhab.rule.' + ctx.ruleUID);
var actuator_state = itemRegistry.getItem("actuator_marvis_1_ch2").getState();
var tv_time = itemRegistry.getItem("tv_on_time_marvis").getState();

// main
if (actuator_state == ON) {
  logger.info("marvis switched on the tv");
}
else if (actuator_state == OFF) {
  logger.info("marvis switched off the tv");
  start = tv_time;
  end = new Date();
  elapsed = end - start;
  logger.info("tv time: " + tv_time);
  logger.info("end: " + end);

  
  events.postUpdate("tv_on_time_marvis", new Date());
}

Here is the log output from the openhab.log:

2021-10-12 16:09:35.229 [INFO ] [org.openhab.rule.3c9229649b         ] - marvis switched on the tv
2021-10-12 16:09:36.774 [INFO ] [org.openhab.rule.3c9229649b         ] - marvis switched off the tv
2021-10-12 16:09:36.805 [INFO ] [org.openhab.rule.3c9229649b         ] - tv time: 2021-10-12T12:20:11.738+0200
2021-10-12 16:09:36.809 [INFO ] [org.openhab.rule.3c9229649b         ] - end: Tue Oct 12 2021 16:09:36 GMT+0200 (CEST)
2021-10-12 16:09:36.814 [WARN ] [internal.defaultscope.ScriptBusEvent] - State 'Tue Oct 12 2021 16:09:36 GMT+0200 (CEST)' cannot be parsed.

My problem is now that the new date cannot be stored in the item, see log output and that the two dates “start” and “end” have different formattings. So it is not possible to calculate the time, the homematic switch with the tv is on.
Thanks for your help

Date() creates a JavaScript Date() Object.

events.postUpdate() requires two String arguments.

openHAB’s DateTime Item requires the String to conform to ISO8601 formatting. JavaScript’s Date appears not to be generating an ISO8601 conformant String.

That’s the root of the problem.

For now, all interactions between openHAB and your Rule is done through Java Objects. For simple things like Strings and Numbers (without units) Nashorn is able to automatically convert things back and forth for you. For more complicated stuff you will be much better off using Java classes and objects instead of JavaScript.

So you can either import Java’s ZonedDateTime and use ZonedDateTime.now() to update the Item, or do the easy thing and create a new DateTimeType which is the actual type of the State that an openHAB DateTime Item carries.

events.postUpdate("tv_on_time_marvis", new DateTimeType());

As an aside, I generally recommend using the items dict instead of pulling Items from the ItemRegistry to get an Item’s state.

var actuator_state = items["actuator_marvis_1_ch2"];
var tv_time = items["tv_on_time_marvis"];

Thanks Rich, now its is possible to store the date in the item. But now I have the problem to convert a new DateTimeType Object to milliseconds.

var tv_time = items["tv_on_time_marvis"];

var laston = new DateTimeType(tv_time);
  var ll = laston.getMilliseconds();
  logger.info("laston " + laston);

I created a new DateTimeType object and now I want to transform the content into milliseconds to calculate times. I get an error into the log file, see:

2021-10-13 13:53:05.006 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID '3c9229649b' failed: TypeError: laston.getMilliseconds is not a function in <eval> at line number 29

can someone help please?

To avoid an XY Problem, why do you need milliseconds? Since you have a Java Object, why not use Java Utilities?

var ZonedDateTime = Java.type("java.time.ZonedDateTime");
var Duration = Java.type("java.time.Duration");
var elapsedTime = Duration.between(ZonedDateTime.now(), items["tv_on_time_marvis"].getZonedDateTime);
logger.info("TV on time duration = " + elapsedTime.toString());

That give you a nice human readable string showing the hours, minutes, seconds.

If you really do need milliseconds of the duration for some reason: elapsedTime.toMillis().

There are all sorts of ways to add, subtract, and compare Duration Objects. Why mess with epoch if you don’t have to?