MQTT binding upgrade to OH3 rule not working

Hello All

I have working OH2.5 with mqtt binding and boiler switch that works fine with rules
When I try to move the switch to new fresh install OH3 the same rule is not working with error
The item itself works Ok

Item:

String Boiler_Switch_Dummy
DateTime strBoiler_Start_Time
DateTime strBoiler_End_Time
Switch swBoiler "Boiler"  { channel="mqtt:topic:swBoiler:power", channel="mqtt:topic:swBoiler:state_power"}
String strBoilerP { channel="mqtt:topic:swBoiler:pulseTime1" }

Rule:

var Timer boilerOff5Minute = null
rule "Trun on Boiler with timer"
when
    Item Boiler_Switch_Dummy received command
then
    strBoiler_Start_Time.postUpdate (new DateTimeType())
    Thread::sleep(3000)
    switch (Boiler_Switch_Dummy.state){
        case "0":{
            //strBoiler_Rule1.sendCommand("ON Power1#state=1 DO RuleTimer1 10 ENDON ON Rules#Timer=1 do Power1 off ENDON")
            strBoilerP.sendCommand(1900)
            strBoiler_End_Time.postUpdate((new DateTimeType(new DateTime((strBoiler_Start_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusMinutes(30).toString)))
            boilerOff5Minute = createTimer(now.plusMinutes(25), [|
                sendBroadcastNotification ("Boiler is OFF in 5 minute.")
                boilerOff5Minute?.cancel
                boilerOff5Minute = null
                ])
            }

        case "1":{
            //strBoiler_Rule1.sendCommand("ON Power1#state=1 DO RuleTimer1 20 ENDON ON Rules#Timer=1 do Power1 off ENDON")
            strBoilerP.sendCommand(3700)
            strBoiler_End_Time.postUpdate((new DateTimeType(new DateTime((strBoiler_Start_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusMinutes(60).toString)))
            boilerOff5Minute = createTimer(now.plusMinutes(55), [|
                sendBroadcastNotification ("Boiler is OFF in 5 minute.")
                boilerOff5Minute?.cancel
                boilerOff5Minute = null
                ])
            }

        case "2":{
            //strBoiler_Rule1.sendCommand("ON Power1#state=1 DO RuleTimer1 30 ENDON ON Rules#Timer=1 do Power1 off ENDON")
            strBoilerP.sendCommand(5500)
            strBoiler_End_Time.postUpdate((new DateTimeType(new DateTime((strBoiler_Start_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusMinutes(90).toString)))
            boilerOff5Minute = createTimer(now.plusMinutes(85), [|
                sendBroadcastNotification ("Boiler is OFF in 5 minute.")
                boilerOff5Minute?.cancel
                boilerOff5Minute = null
                ])
            }
    }
    Thread::sleep(3000)
    swBoiler.sendCommand("ON")
    Boiler_Switch_Dummy.postUpdate(-1)
    //sendBroadcastNotification ("Boiler is ON from " + strBoiler_Start_Time.state.format("%1$tH:%1$tM") + " to " + strBoiler_End_Time.state.format("%1$tH:%1$tM"))
    
end

rule "Boiler changed"
when
    Item swBoiler changed
then
    logInfo("notifications", "swBoiler changed to " + swBoiler.state + " " + boilerOff5Minute)
    if(swBoiler.state == OFF){
        sendBroadcastNotification ("Boiler is OFF")
        boilerOff5Minute?.cancel
        boilerOff5Minute = null    
    }
    else {
        if(boilerOff5Minute === null){
            strBoiler_Start_Time.postUpdate (new DateTimeType())
            Thread::sleep(3000)
            strBoiler_End_Time.postUpdate((new DateTimeType(new DateTime((strBoiler_Start_Time.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusMinutes(30).toString)))
            boilerOff5Minute = createTimer(now.plusMinutes(25), [|
                sendBroadcastNotification ("Boiler is OFF in 5 minute.")
                boilerOff5Minute?.cancel
                boilerOff5Minute = null
            ])   
            sendBroadcastNotification ("Boiler button is ON from " + strBoiler_Start_Time.state.format("%1$tH:%1$tM") + " to " + strBoiler_End_Time.state.format("%1$tH:%1$tM"))
        }
    }

end

and the error is:

2021-03-29 23:41:10.809 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'boiler-1' failed: An error occurred during the script execution: Cannot assign a value in null context. in boiler

I’m using switch with 3 option in sitemap

Switch item=Boiler_Switch_Dummy label="בוילר" mappings=[0="  30 Min  ", 1="  60 Min  ", 2="  90 Min  "]

Where that null came from?

TIA

Looks like it’s choking on that to me, though I can’t see why; do you see the error at rules file load time, or at execution time?
I say that because

is not pointing at a rule, unless you’ve truncated the message in the copy/paste?

EDIT - I suppose “null context” can also mean within timer code block. There have been changes to timer cancel/reschedule simply because the rule engine has changed.
This -

is a daft thing to do within timer code … the timer referenced has after all already hit its appointed time and is currently executing. Maybe it is less accepting than it used to be.

No. That’s the only error and I check twice its not truncated

Can you point me to the documents please?

I agree with you and cant remember why its here after the timer is excecated

It’s a new rule engine. There is no specific document that says don’t use timer.cancel in ways it was never intended to be used. I’m not sure what you want here.

Ok
I try to write it all again
One more something that I notice is when it switch on and off I get that log:


2021-03-30 00:44:08.534 [INFO ] [nhab.core.model.script.notifications] - swBoiler changed to ON null
2021-03-30 00:44:39.227 [INFO ] [nhab.core.model.script.notifications] - swBoiler changed to OFF null

Where is that null came from?

It comes from this line in your code

because you do this in various places

Everything is doing exactly what you told it to do here.

2 Likes

another thing i see, not regarding to the error, but should be optimized i think. your rule:

… i had such rules and sometimes problems because when you trigger received command you should better switch switch (receivedCommand){ because it might be the state is still not updated when executing the rule.

I notice that and that’s why I have to wait 3 sec before I read the state

So I understand that my problem is in the datetime conversion and find that there is a changed in OH3 with datetime type: