TypeError: M.toEpochSecond is not a function

Hi all.

I seem to have a type-incompatibility problem when trying to do some date/time comparison in JavaScript. I had a DSL rule that worked, but it stopped working when I tried to convert it to JavaScript. The error I get is:

Failed to execute rule 'Um-Mitternacht-Heizungsregelung-f-r-Abwesenheit-308e1207-bf4f-4810-90bf-02188886c5fb': Failed to execute action: 1(Error: Failed to execute rule Um-Mitternacht-Heizungsregelung-f-r-Abwesenheit-308e1207-bf4f-4810-90bf-02188886c5fb: TypeError: M.toEpochSecond is not a function: TypeError: M.toEpochSecond is not a function

And this is the relevant JS code:

rules.when().cron("0 0 0 * * ?").or()
    .item("HeizungAusBis").changed()
    .then(() => {
        var now = time.toZDT();
        if (items.getItem("HeizungAusBis").state != null) {
            // Wenn gesetztes Datum in der Zukunft liegt, Heizung auf Standby
            if (now.isBefore(new Date(items.getItem("HeizungAusBis").state))) {

HeizungAusBis is a DateTime item. Does anybody see my mistake and how to fix it? I did look at the relevant docs but could not figure it out.

Try

now.isBefore(time.toZDT(items.getItem("HeizungAusBis")))

Thanks for the tip. I just tried this, but now I get:
Error: Item HeizungAusBis is NULL or UNDEF, cannot convert to a time.ZonedDateTime

This seem odd because, as you can see above, I am explicitly checking against null:
if (items.getItem("HeizungAusBis").state != null) {
Is there anything wrong with that syntax? Does it have to be NULL maybe in OH?

null is a java null, vs openHAB’s NULL which is not the same.

I’m not familiar with how it’s handled in jsscripting, perhaps the state would equal the string NULL? Alternatively compare .rawState against NULL i.e.

if (items.getItem("HeizungAusBis").rawState != NULL) {
...

@florian-h05 / @rlkoshak would understand this much better.

UnDefType.NULL is not available by default in JS Scripting, so this would not work out of the box.

You could compare the Item state to the string NULL:

if (items.getItem("HeizungAusBis").state !== 'NULL') {

As @JimT notes, null is not the same thing as NULL or UNDEF. NULL and UNDEF are special Item states.

In JS Scripting, the best way to test if an Item is NULL or UNDEF is

if(items.HeizungAusBis.isUninitialized) {

You can also compare the Item’s state to the String 'NULL' as @florian-h05 demonstrated but you also need to check for 'UNDEF' which gets a little ugly but not too terribly bad. .state is always the String representation of the state.

If for some reason you did want or need to use the raw Java types you have that option. You just need to import them first.

var OnOffType = require('@runtime');
if(items.HeizungAufBis.rawState != UnDefType.NULL){

But again you have the issue that UNDEF is a problem too and you need to test for that.

You could test the type of the rawState and see if it’s the same type as UnDefType.

But all of these options are more involved than using the built in isUninitialized.

Thanks a lot, I will try this!

Hmm, so I now have this:

        if (items.HeizungAusBis.isUninitialized) {
            // Wenn gesetztes Datum in der Zukunft liegt, Heizung auf Standby
            if (now.isBefore(time.toZDT(items.getItem("HeizungAusBis")))) {
                console.log("HEIZUNG AUF STANDBY");
                items.getItem("Betriebsmodus").sendCommand("standby");

But it still throws me this error here:
Error: Item HeizungAusBis is NULL or UNDEF, cannot convert to a time.ZonedDateTime
I thought that isUnititialized(..) would check for nullness. What am I still doing wrong?

It does. isUninitialized returns true when the Item’s state is NULL or UNDEF. So the next line fails because NULL or UNDEF cannot be converted to a ZonedDateTime.

You want to test that the Item’s state is not NULL or UNDEF`

if (!items.HeizungAusBis.isUninitialized) {

or the more verbose

if (items.HeizungAusBis.isUninitialized != true) {

Oh of course, I missed the Un part. Thanks!